// 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 GARNET_DRIVERS_BLUETOOTH_LIB_GATT_GATT_H_
#define GARNET_DRIVERS_BLUETOOTH_LIB_GATT_GATT_H_

#include <fbl/ref_counted.h>
#include <fbl/ref_ptr.h>
#include <lib/async/dispatcher.h>
#include <lib/fit/function.h>

#include "garnet/drivers/bluetooth/lib/common/uuid.h"
#include "garnet/drivers/bluetooth/lib/gatt/gatt_defs.h"
#include "garnet/drivers/bluetooth/lib/gatt/local_service_manager.h"
#include "garnet/drivers/bluetooth/lib/gatt/remote_service.h"
#include "garnet/drivers/bluetooth/lib/gatt/types.h"

#include "lib/fidl/cpp/vector.h"
#include "lib/fxl/memory/ref_ptr.h"

namespace btlib {

namespace l2cap {
class Channel;
}  // namespace l2cap

namespace gatt {

// This is the root object of the GATT layer. This object owns:
//
//   * A single local attribute database
//   * All client and server data bearers
//   * L2CAP ATT fixed channels
//
// GATT requires an dispatcher on initialization which will be used to
// serialize all internal GATT tasks.
//
// All public functions are asynchronous and thread-safe.
class GATT : public fbl::RefCounted<GATT> {
 public:
  // Constructs a GATT object.
  static fbl::RefPtr<GATT> Create(async_dispatcher_t* gatt_dispatcher);

  // Initialize/ShutDown the GATT profile. It is safe for the caller to drop its
  // reference after ShutDown.
  //
  // The owner MUST call ShutDown() to properly clean up the object.
  virtual void Initialize() = 0;
  virtual void ShutDown() = 0;

  // Registers the given connection with the GATT profile without initiating
  // service discovery. Once a connection is registered with GATT, the peer can
  // access local services and clients can call the "Remote Service" methods
  // below using |peer_id|.
  //
  // |peer_id|: The identifier for the peer device that the link belongs to.
  //            This is used to identify the peer while handling certain events.
  // |att_chan|: The ATT fixed channel over which the ATT protocol bearer will
  //             operate. The bearer will be associated with the link that
  //             underlies this channel.
  virtual void AddConnection(const std::string& peer_id,
                             fbl::RefPtr<l2cap::Channel> att_chan) = 0;

  // Unregisters the GATT profile connection to the peer with Id |peer_id|.
  virtual void RemoveConnection(std::string peer_id) = 0;

  // ==============
  // Local Services
  // ==============
  //
  // The methods below are for managing local GATT services that are available
  // to data bearers in the server role.

  // Registers the GATT service hierarchy represented by |service| with the
  // local attribute database. Once successfully registered, the service will
  // be available to remote clients.
  //
  // Objects under |service| must have unique identifiers to aid in value
  // request handling. These identifiers will be passed to |read_handler| and
  // |write_handler|.
  //
  // The provided handlers will be called to handle remote initiated
  // transactions targeting the service. These handlers will be run on the
  // on the GATT dispatcher.
  //
  // This method returns an opaque identifier on successful registration,
  // which can be used by the caller to refer to the service in the future. This
  // ID will be returned via |callback| which run on the GATT dispatcher.
  //
  // Returns |kInvalidId| on failure. Registration can fail if the attribute
  // database has run out of handles or if the hierarchy contains
  // characteristics or descriptors with repeated IDs.
  using ServiceIdCallback = fit::function<void(IdType)>;
  virtual void RegisterService(ServicePtr service,
                               ServiceIdCallback callback,
                               ReadHandler read_handler,
                               WriteHandler write_handler,
                               ClientConfigCallback ccc_callback) = 0;

  // Unregisters the GATT service hierarchy identified by |service_id|. Has no
  // effect if |service_id| is not a registered id.
  virtual void UnregisterService(IdType service_id) = 0;

  // Sends a characteristic handle-value notification to a peer that has
  // configured the characteristic for notifications or indications. Does
  // nothing if the given peer has not configured the characteristic.
  //
  // |service_id|: The GATT service that the characteristic belongs to.
  // |chrc_id|: The GATT characteristic that will be notified.
  // |peer_id|: ID of the peer that the notification/indication will be sent to.
  // |value|: The attribute value that will be included in the notification.
  // |indicate|: If true, an indication will be sent.
  //
  // This method can only be called on the GATT task runner.
  //
  // TODO(armansito): Revise this API to involve fewer lookups (NET-483).
  // TODO(armansito): Fix this to notify all registered peers when |peer_id| is
  // empty (NET-589).
  virtual void SendNotification(IdType service_id,
                                IdType chrc_id,
                                std::string peer_id,
                                ::fidl::VectorPtr<uint8_t> value,
                                bool indicate) = 0;

  // ===============
  // Remote Services
  // ===============
  //
  // The methods below are for interacting with remote GATT services. These
  // methods operate asynchronously.

  // Perform service discovery and initialize remote services for the peer with
  // the given |peer_id|.
  virtual void DiscoverServices(std::string peer_id) = 0;

  // Register a handler that will be notified when a remote service gets
  // discovered on a connected peer.
  //
  // |watcher| will be posted on an dispatcher if one is provided.
  // Otherwise, it will run on an internal thread and the client is responsible
  // for synchronization.
  using RemoteServiceWatcher =
      fit::function<void(const std::string& peer_id,
                         fbl::RefPtr<RemoteService> service)>;
  virtual void RegisterRemoteServiceWatcher(RemoteServiceWatcher watcher,
                                            async_dispatcher_t* dispatcher = nullptr) = 0;

  // Returns the list of remote services that were found on the device with
  // |peer_id|. If |peer_id| was registered but DiscoverServices() has not been
  // called yet, this request will be buffered until remote services have been
  // discovered. If the connection is removed without discovery services,
  // |callback| will be called with an error status. |callback| will always run
  // on the GATT loop.
  virtual void ListServices(std::string peer_id,
                            std::vector<common::UUID> uuids,
                            ServiceListCallback callback) = 0;

  // Connects the RemoteService with the given identifier found on the
  // device with |peer_id|. Returns nullptr if the service is not found.
  // |callback| will be run on the given task runner.
  //
  // TODO(armansito): Change this to ConnectToService().
  virtual void FindService(std::string peer_id,
                           IdType service_id,
                           RemoteServiceCallback callback) = 0;

 protected:
  friend class fbl::RefPtr<GATT>;
  GATT() = default;
  virtual ~GATT() = default;

 private:
  FXL_DISALLOW_COPY_AND_ASSIGN(GATT);
};

}  // namespace gatt
}  // namespace btlib

#endif  // GARNET_DRIVERS_BLUETOOTH_LIB_GATT_GATT_H_
