// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef SRC_CONNECTIVITY_BLUETOOTH_CORE_BT_HOST_GATT_REMOTE_SERVICE_DEVICE_H_
#define SRC_CONNECTIVITY_BLUETOOTH_CORE_BT_HOST_GATT_REMOTE_SERVICE_DEVICE_H_

#include <ddk/device.h>
#include <ddk/driver.h>
#include <ddk/protocol/bt/gattsvc.h>
#include <fbl/macros.h>
#include <lib/async-loop/cpp/loop.h>
#include <lib/async-loop/default.h>
#include <lib/async/cpp/task.h>
#include <lib/async/dispatcher.h>
#include <zircon/types.h>

#include "src/connectivity/bluetooth/core/bt-host/gatt/gatt.h"

namespace bthost {

// This class is responsible for bridging remote GATT services to the DDK so
// GATT services can be implimented as drivers (eg HID over GATT as HIDBUS
// device)
class GattRemoteServiceDevice final {
 public:
  GattRemoteServiceDevice(bt::gatt::PeerId peer_id, fbl::RefPtr<bt::gatt::RemoteService> service);
  ~GattRemoteServiceDevice() = default;

  // Publish a bt-gatt-svc device as a child of |parent|.
  zx_status_t Bind(zx_device_t* parent);

  // Unpublishes any associated bt-gatt-svc and stops processing GATT callbacks. This will be called
  // by the DDK as part of regular device lifecycle but it can also be called directly to remove a
  // device.
  void Unbind();

 private:
  static bt_gatt_svc_protocol_ops_t proto_ops_;

  // Protocol trampolines.
  static void DdkUnbind(void* ctx) { static_cast<GattRemoteServiceDevice*>(ctx)->Unbind(); }

  static void DdkRelease(void* ctx) { static_cast<GattRemoteServiceDevice*>(ctx)->Release(); }

  static void OpConnect(void* ctx, bt_gatt_svc_connect_callback connect_cb, void* cookie) {
    static_cast<GattRemoteServiceDevice*>(ctx)->Connect(connect_cb, cookie);
  }

  static void OpStop(void* ctx) { static_cast<GattRemoteServiceDevice*>(ctx)->Stop(); }

  static void OpReadCharacteristic(void* ctx, bt_gatt_id_t id,
                                   bt_gatt_svc_read_characteristic_callback read_cb, void* cookie) {
    static_cast<GattRemoteServiceDevice*>(ctx)->ReadCharacteristic(id, read_cb, cookie);
  }

  static void OpReadLongCharacteristic(void* ctx, bt_gatt_id_t id, uint16_t offset,
                                       size_t max_bytes,
                                       bt_gatt_svc_read_characteristic_callback read_cb,
                                       void* cookie) {
    static_cast<GattRemoteServiceDevice*>(ctx)->ReadLongCharacteristic(id, offset, max_bytes,
                                                                       read_cb, cookie);
  }

  static void OpWriteCharacteristic(void* ctx, bt_gatt_id_t id, const void* buf, size_t len,
                                    bt_gatt_svc_write_characteristic_callback status_cb,
                                    void* cookie) {
    static_cast<GattRemoteServiceDevice*>(ctx)->WriteCharacteristic(id, buf, len, status_cb,
                                                                    cookie);
  }

  static void OpEnableNotifications(void* ctx, bt_gatt_id_t id,
                                    const bt_gatt_notification_value_t* value_cb,
                                    bt_gatt_svc_enable_notifications_callback status_cb,
                                    void* cookie) {
    static_cast<GattRemoteServiceDevice*>(ctx)->EnableNotifications(id, value_cb, status_cb,
                                                                    cookie);
  }

  // DDK device ops.
  void Release();

  // bt-gatt-svc ops.
  void Connect(bt_gatt_svc_connect_callback connect_cb, void* cookie);
  void Stop();
  void ReadCharacteristic(bt_gatt_id_t id, bt_gatt_svc_read_characteristic_callback read_cb,
                          void* cookie);

  void ReadLongCharacteristic(bt_gatt_id_t id, uint16_t offset, size_t max_bytes,
                              bt_gatt_svc_read_characteristic_callback read_cb, void* cookie);
  void WriteCharacteristic(bt_gatt_id_t id, const void* buff, size_t len,
                           bt_gatt_svc_write_characteristic_callback write_cb, void* cookie);
  void EnableNotifications(bt_gatt_id_t id, const bt_gatt_notification_value_t* value_cb,
                           bt_gatt_svc_enable_notifications_callback status_cb, void* cookie);

  // All device protocol messages are dispatched on this loop to not block the
  // gatt or host thread.
  async::Loop loop_;

  std::mutex mtx_;

  // The bt-gatt-svc device that is managed by this object. This member is null if no device has
  // been published.
  zx_device_t* dev_ __TA_GUARDED(mtx_);

  const bt::gatt::PeerId peer_id_;
  const fbl::RefPtr<bt::gatt::RemoteService> service_;

  // The base DDK device ops.
  zx_protocol_device_t dev_proto_ = {};

  DISALLOW_COPY_AND_ASSIGN_ALLOW_MOVE(GattRemoteServiceDevice);
};

}  // namespace bthost
#endif  // SRC_CONNECTIVITY_BLUETOOTH_CORE_BT_HOST_GATT_REMOTE_SERVICE_DEVICE_H_
