// Copyright 2017 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_GAP_LOW_ENERGY_CONNECTION_MANAGER_H_
#define GARNET_DRIVERS_BLUETOOTH_LIB_GAP_LOW_ENERGY_CONNECTION_MANAGER_H_

#include <list>
#include <memory>
#include <unordered_map>
#include <unordered_set>
#include <vector>

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

#include "garnet/drivers/bluetooth/lib/data/domain.h"
#include "garnet/drivers/bluetooth/lib/gap/gap.h"
#include "garnet/drivers/bluetooth/lib/gatt/gatt.h"
#include "garnet/drivers/bluetooth/lib/hci/command_channel.h"
#include "garnet/drivers/bluetooth/lib/hci/control_packets.h"
#include "garnet/drivers/bluetooth/lib/hci/low_energy_connector.h"

#include "lib/fxl/macros.h"
#include "lib/fxl/memory/ref_ptr.h"
#include "lib/fxl/memory/weak_ptr.h"

namespace btlib {

namespace hci {
class Transport;
}  // namespace hci

namespace gap {

namespace internal {
class LowEnergyConnection;
}  // namespace internal

// TODO(armansito): Document the usage pattern.

class LowEnergyConnectionManager;
class PairingDelegate;
class RemoteDevice;
class RemoteDeviceCache;

class LowEnergyConnectionRef final {
 public:
  // Destroying this object releases its reference to the underlying connection.
  ~LowEnergyConnectionRef();

  // Releases this object's reference to the underlying connection.
  void Release();

  // Returns true if the underlying connection is still active.
  bool active() const { return active_; }

  // Sets a callback to be called when the underlying connection is closed.
  void set_closed_callback(fit::closure callback) {
    closed_cb_ = std::move(callback);
  }

  const std::string& device_identifier() const { return device_id_; }
  hci::ConnectionHandle handle() const { return handle_; }

 private:
  friend class LowEnergyConnectionManager;
  friend class internal::LowEnergyConnection;

  LowEnergyConnectionRef(const std::string& device_id,
                         hci::ConnectionHandle handle,
                         fxl::WeakPtr<LowEnergyConnectionManager> manager);

  // Called by LowEnergyConnectionManager when the underlying connection is
  // closed. Notifies |closed_cb_|.
  void MarkClosed();

  bool active_;
  std::string device_id_;
  hci::ConnectionHandle handle_;
  fxl::WeakPtr<LowEnergyConnectionManager> manager_;
  fit::closure closed_cb_;
  fxl::ThreadChecker thread_checker_;

  FXL_DISALLOW_COPY_AND_ASSIGN(LowEnergyConnectionRef);
};

using LowEnergyConnectionRefPtr = std::unique_ptr<LowEnergyConnectionRef>;

class LowEnergyConnectionManager final {
 public:
  LowEnergyConnectionManager(fxl::RefPtr<hci::Transport> hci,
                             hci::LowEnergyConnector* connector,
                             RemoteDeviceCache* device_cache,
                             fbl::RefPtr<data::Domain> data_domain,
                             fbl::RefPtr<gatt::GATT> gatt);
  ~LowEnergyConnectionManager();

  // Allows a caller to claim shared ownership over a connection to the
  // requested remote LE device identified by |device_identifier|. Returns
  // false, if |device_identifier| is not recognized, otherwise:
  //
  //   * If the requested device is already connected, this method
  //     asynchronously returns a LowEnergyConnectionRef without sending any
  //     requests to the controller. This is done for both local and remote
  //     initiated connections (i.e. the local adapter can either be in the LE
  //     central or peripheral roles). |callback| always succeeds.
  //
  //   * If the requested device is NOT connected, then this method initiates a
  //     connection to the requested device using one of the GAP central role
  //     connection establishment procedures described in Core Spec v5.0, Vol 3,
  //     Part C, Section 9.3. A LowEnergyConnectionRef is asynchronously
  //     returned to the caller once the connection has been set up.
  //
  //     The status of the procedure is reported in |callback| in the case of an
  //     error.
  //
  // |callback| is posted on the creation thread's dispatcher.
  using ConnectionResultCallback =
      fit::function<void(hci::Status, LowEnergyConnectionRefPtr)>;
  bool Connect(const std::string& device_identifier,
               ConnectionResultCallback callback);

  RemoteDeviceCache* device_cache() { return device_cache_; }

  // Disconnects any existing LE connection to |device_identifier|, invalidating
  // all active LowEnergyConnectionRefs. Returns false if |device_identifier| is
  // not recognized or the corresponding remote device is not connected.
  bool Disconnect(const std::string& device_identifier);

  // Initializes a new connection over the given |link| and returns a connection
  // reference. Returns nullptr if the connection was rejected.
  //
  // |link| must be the result of a remote initiated connection.
  //
  // TODO(armansito): Add an |own_address| parameter for the locally advertised
  // address that was connected to.
  //
  // A link with the given handle should not have been previously registered.
  LowEnergyConnectionRefPtr RegisterRemoteInitiatedLink(
      hci::ConnectionPtr link);

  // Returns the PairingDelegate currently assigned to this connection manager.
  PairingDelegate* pairing_delegate() const { return pairing_delegate_.get(); }

  // Assigns a new PairingDelegate to handle LE authentication challenges.
  // Replacing an existing pairing delegate cancels all ongoing pairing
  // procedures. If a delegate is not set then all pairing requests will be
  // rejected.
  void SetPairingDelegate(fxl::WeakPtr<PairingDelegate> delegate);

  // TODO(armansito): Add a RemoteDeviceCache::Observer interface and move these
  // callbacks there.

  // Called when the connection parameters on a link have been updated.
  using ConnectionParametersCallback = fit::function<void(const RemoteDevice&)>;
  void SetConnectionParametersCallbackForTesting(
       ConnectionParametersCallback callback);

  // Called when a link with the given handle gets disconnected. This event is
  // guaranteed to be called before invalidating connection references.
  // |callback| is run on the creation thread.
  //
  // NOTE: This is intended ONLY for unit tests. Clients should watch for
  // disconnection events using LowEnergyConnectionRef::set_closed_callback()
  // instead. DO NOT use outside of tests.
  using DisconnectCallback = fit::function<void(hci::ConnectionHandle)>;
  void SetDisconnectCallbackForTesting(DisconnectCallback callback);

  // Sets the timeout interval to be used on future connect requests. The
  // default value is kLECreateConnecionTimeoutMs.
  void set_request_timeout_for_testing(int64_t value_ms) {
    request_timeout_ms_ = value_ms;
  }

 private:
  friend class LowEnergyConnectionRef;

  // Mapping from device identifiers to open LE connections.
  using ConnectionMap =
      std::unordered_map<std::string,
                         std::unique_ptr<internal::LowEnergyConnection>>;

  class PendingRequestData {
   public:
    PendingRequestData(const common::DeviceAddress& address,
                       ConnectionResultCallback first_callback);
    PendingRequestData() = default;
    ~PendingRequestData() = default;

    PendingRequestData(PendingRequestData&&) = default;
    PendingRequestData& operator=(PendingRequestData&&) = default;

    void AddCallback(ConnectionResultCallback cb) {
      callbacks_.push_back(std::move(cb));
    }

    // Notifies all elements in |callbacks| with |status| and the result of
    // |func|.
    using RefFunc = fit::function<LowEnergyConnectionRefPtr()>;
    void NotifyCallbacks(hci::Status status, const RefFunc& func);

    const common::DeviceAddress& address() const { return address_; }

   private:
    common::DeviceAddress address_;
    std::list<ConnectionResultCallback> callbacks_;

    FXL_DISALLOW_COPY_AND_ASSIGN(PendingRequestData);
  };

  // Called by LowEnergyConnectionRef::Release().
  void ReleaseReference(LowEnergyConnectionRef* conn_ref);

  // Called when |connector_| completes a pending request. Initiates a new
  // connection attempt for the next device in the pending list, if any.
  void TryCreateNextConnection();

  // Initiates a connection attempt to |peer|.
  void RequestCreateConnection(RemoteDevice* peer);

  // Initializes the connection to the peer with the given identifier and
  // returns the initial reference to it. This method is responsible for setting
  // up all data bearers.
  LowEnergyConnectionRefPtr InitializeConnection(const std::string& device_id,
                                                 hci::ConnectionPtr link);

  // Adds a new connection reference to an existing connection to the device
  // with the ID |device_identifier| and returns it. Returns nullptr if
  // |device_identifier| is not recognized.
  LowEnergyConnectionRefPtr AddConnectionRef(
      const std::string& device_identifier);

  // Cleans up a connection state. This results in a HCI_Disconnect command
  // if |close_link| is true, and notifies any referenced
  // LowEnergyConnectionRefs of the disconnection. Marks the corresponding
  // RemoteDeviceCache entry as disconnected and cleans up all data bearers.
  //
  // |conn_state| will have been removed from the underlying map at the time of
  // a call. Its ownership is passed to the method for disposal.
  //
  // This is also responsible for unregistering the link from managed subsystems
  // (e.g. L2CAP).
  void CleanUpConnection(std::unique_ptr<internal::LowEnergyConnection> conn,
                         bool close_link = true);

  // Called by |connector_| when a new locally initiated LE connection has been
  // created.
  void RegisterLocalInitiatedLink(hci::ConnectionPtr link);

  // Updates |device_cache_| with the given |link| and returns the corresponding
  // RemoteDevice.
  //
  // Creates a new RemoteDevice if |link| matches a peer that did not
  // previously exist in the cache. Otherwise this updates and returns an
  // existing RemoteDevice.
  //
  // The returned device is marked as non-temporary and its connection
  // parameters are updated.
  //
  // Called by RegisterRemoteInitiatedLink() and RegisterLocalInitiatedLink().
  RemoteDevice* UpdateRemoteDeviceWithLink(const hci::Connection& link);

  // Called by |connector_| to indicate the result of a connect request.
  void OnConnectResult(const std::string& device_identifier,
                       hci::Status status,
                       hci::ConnectionPtr link);

  // Event handler for the HCI Disconnection Complete event.
  // TODO(armansito): This needs to be shared between the BR/EDR and LE
  // connection managers, so this handler should be moved elsewhere.
  void OnDisconnectionComplete(const hci::EventPacket& event);

  // Event handler for the HCI LE Connection Update Complete event.
  void OnLEConnectionUpdateComplete(const hci::EventPacket& event);

  // Called when the preferred connection parameters have been received for a LE
  // peripheral. This can happen in the form of:
  //
  //   1. <<Slave Connection Interval Range>> advertising data field
  //   2. "Peripheral Preferred Connection Parameters" GATT characteristic
  //      (under "GAP" service)
  //   3. HCI LE Remote Connection Parameter Request Event
  //   4. L2CAP Connection Parameter Update request
  //
  // TODO(armansito): Support #1, #2, and #3 above.
  //
  // This method caches |params| for later connection attempts and sends the
  // parameters to the controller if the initializing procedures are complete
  // (since we use more agressing initial parameters for pairing and service
  // discovery, as recommended by the specification in v5.0, Vol 3, Part C,
  // Section 9.3.12.1).
  //
  // |device_identifier| uniquely identifies the peer. |handle| represents the
  // the logical link that |params| should be applied to.
  void OnNewLEConnectionParams(
      const std::string& device_identifier,
      hci::ConnectionHandle handle,
      const hci::LEPreferredConnectionParameters& params);

  // Tells the controller to use the given connection |params| on the given
  // logical link |handle|.
  void UpdateConnectionParams(
      hci::ConnectionHandle handle,
      const hci::LEPreferredConnectionParameters& params);

  // Returns an iterator into |connections_| if a connection is found that
  // matches the given logical link |handle|. Otherwise, returns an iterator
  // that is equal to |connections_.end()|.
  //
  // The general rules of validity around std::unordered_map::iterator apply to
  // the returned value.
  ConnectionMap::iterator FindConnection(hci::ConnectionHandle handle);

  fxl::RefPtr<hci::Transport> hci_;

  // The pairing delegate used for authentication challenges. If nullptr, all
  // pairing requests will be rejected.
  fxl::WeakPtr<PairingDelegate> pairing_delegate_;

  // Time after which a connection attempt is considered to have timed out. This
  // is configurable to allow unit tests to set a shorter value.
  int64_t request_timeout_ms_;

  // The dispather for all asynchronous tasks.
  async_dispatcher_t* dispatcher_;

  // The device cache is used to look up and persist remote device data that is
  // relevant during connection establishment (such as the address, preferred
  // connetion parameters, etc). Expected to outlive this instance.
  RemoteDeviceCache* device_cache_;  // weak

  // The reference to the data domain, used to interact with the L2CAP layer to
  // manage LE logical links, fixed channels, and LE-specific L2CAP signaling
  // events (e.g. connection parameter update).
  fbl::RefPtr<data::Domain> data_domain_;

  // The GATT layer reference, used to add and remove ATT data bearers and
  // service discovery.
  fbl::RefPtr<gatt::GATT> gatt_;

  // Local GATT service registry.
  std::unique_ptr<gatt::LocalServiceManager> gatt_registry_;

  // Event handler ID for the HCI Disconnection Complete event.
  hci::CommandChannel::EventHandlerId disconn_cmpl_handler_id_;

  // Event handler ID for the HCI LE Connection Update Complete event.
  hci::CommandChannel::EventHandlerId conn_update_cmpl_handler_id_;

  // Callbacks used by unit tests to observe connection state events.
  ConnectionParametersCallback test_conn_params_cb_;
  DisconnectCallback test_disconn_cb_;

  // Outstanding connection requests based on remote device ID.
  std::unordered_map<std::string, PendingRequestData> pending_requests_;

  // Mapping from device identifiers to currently open LE connections.
  ConnectionMap connections_;

  // Performs the Direct Connection Establishment procedure. |connector_| must
  // out-live this connection manager.
  hci::LowEnergyConnector* connector_;  // weak

  // Keep this as the last member to make sure that all weak pointers are
  // invalidated before other members get destroyed.
  fxl::WeakPtrFactory<LowEnergyConnectionManager> weak_ptr_factory_;

  FXL_DISALLOW_COPY_AND_ASSIGN(LowEnergyConnectionManager);
};

}  // namespace gap
}  // namespace btlib

#endif  // GARNET_DRIVERS_BLUETOOTH_LIB_GAP_LOW_ENERGY_CONNECTION_MANAGER_H_
