//
//  Copyright (C) 2015 Google, Inc.
//
//  Licensed under the Apache License, Version 2.0 (the "License");
//  you may not use this file except in compliance with the License.
//  You may obtain a copy of the License at:
//
//  http://www.apache.org/licenses/LICENSE-2.0
//
//  Unless required by applicable law or agreed to in writing, software
//  distributed under the License is distributed on an "AS IS" BASIS,
//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//  See the License for the specific language governing permissions and
//  limitations under the License.
//

#pragma once

#include <deque>
#include <functional>
#include <mutex>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector>

#include <base/macros.h>

#include "service/bluetooth_instance.h"
#include "service/common/bluetooth/service.h"
#include "service/common/bluetooth/uuid.h"
#include "service/hal/bluetooth_gatt_interface.h"

namespace bluetooth {

// A GattServer instance represents an application's handle to perform GATT
// server-role operations. Instances cannot be created directly and should be
// obtained through the factory.
class GattServer : public BluetoothInstance,
                   private hal::BluetoothGattInterface::ServerObserver {
 public:
  // Delegate interface is used to handle incoming requests and confirmations
  // for a GATT service.
  class Delegate {
   public:
    Delegate() = default;
    virtual ~Delegate() = default;

    // Called when there is an incoming read request for the characteristic with
    // ID |characteristic_id| from a remote device with address
    // |device_address|. |request_id| can be used to respond to this request by
    // calling SendResponse below.
    virtual void OnCharacteristicReadRequest(GattServer* gatt_server,
                                             const std::string& device_address,
                                             int request_id, int offset,
                                             bool is_long, uint16_t handle) = 0;

    // Called when there is an incoming read request for the descriptor with
    // ID |descriptor_id| from a remote device with address |device_address|.
    // |request_id| can be used to respond to this request by
    // calling SendResponse below.
    virtual void OnDescriptorReadRequest(GattServer* gatt_server,
                                         const std::string& device_address,
                                         int request_id, int offset,
                                         bool is_long, uint16_t handle) = 0;

    // Called when there is an incoming write request for the characteristic
    // with ID |characteristic_id| from a remote device with address
    // |device_address|. |request_id| can be used to respond to this request by
    // calling SendResponse, if the |need_response| parameter is true. Otherwise
    // this is a "Write Without Reponse" procedure and SendResponse will fail.
    // If |is_prepare_write| is true, then the write should not be committed
    // immediately as this is a "Prepared Write Request". Instead, the Delegate
    // should hold on to the value and either discard it or complete the write
    // when it receives the OnExecuteWriteRequest event.
    virtual void OnCharacteristicWriteRequest(
        GattServer* gatt_server, const std::string& device_address,
        int request_id, int offset, bool is_prepare_write, bool need_response,
        const std::vector<uint8_t>& value, uint16_t handle) = 0;

    // Called when there is an incoming write request for the descriptor
    // with ID |descriptor_id| from a remote device with address
    // |device_address|. |request_id| can be used to respond to this request by
    // calling SendResponse, if the |need_response| parameter is true. Otherwise
    // this is a "Write Without Response" procedure and SendResponse will fail.
    // If |is_prepare_write| is true, then the write should not be committed
    // immediately as this is a "Prepared Write Request". Instead, the Delegate
    // should hold on to the value and either discard it or complete the write
    // when it receives the OnExecuteWriteRequest event.
    virtual void OnDescriptorWriteRequest(
        GattServer* gatt_server, const std::string& device_address,
        int request_id, int offset, bool is_prepare_write, bool need_response,
        const std::vector<uint8_t>& value, uint16_t handle) = 0;

    // Called when there is an incoming "Execute Write Request". If |is_execute|
    // is true, then the Delegate should commit all previously prepared writes.
    // Otherwise, all prepared writes should be aborted. The Delegate should
    // call "SendResponse" to complete the procedure.
    virtual void OnExecuteWriteRequest(GattServer* gatt_server,
                                       const std::string& device_address,
                                       int request_id, bool is_execute) = 0;

    virtual void OnConnectionStateChanged(GattServer* gatt_server,
                                          const std::string& device_addres,
                                          bool connected) = 0;

   private:
    DISALLOW_COPY_AND_ASSIGN(Delegate);
  };

  // The desctructor automatically unregisters this instance from the stack.
  ~GattServer() override;

  // Assigns a delegate to this instance. |delegate| must out-live this
  // GattServer instance.
  void SetDelegate(Delegate* delegate);

  // BluetoothClientInstace overrides:
  const UUID& GetAppIdentifier() const override;
  int GetInstanceId() const override;

  // Callback type used to report the status of an asynchronous GATT server
  // operation.
  using ResultCallback =
      std::function<void(BLEStatus status, const Service& id)>;
  using GattCallback = std::function<void(GATTError error)>;

  // Add service declaration. This method immediately
  // returns false if a service hasn't been started. Otherwise, |callback| will
  // be called asynchronously with the result of the operation.
  //
  // TODO(armansito): It is unclear to me what it means for this function to
  // fail. What is the state that we're in? Is the service declaration over so
  // we can add other services to this server instance? Do we need to clean up
  // all the entries or does the upper-layer need to remove the service? Or are
  // we in a stuck-state where the service declaration hasn't ended?
  bool AddService(const bluetooth::Service&, const ResultCallback& callback);

  // Sends a response for a pending notification. |request_id| and
  // |device_address| should match those that were received through one of the
  // Delegate callbacks. |value| and |offset| are used for read requests and
  // prepare write requests and should match the value of the attribute. Returns
  // false if the pending request could not be resolved using the given
  // parameters or if the call to the underlying stack fails.
  bool SendResponse(const std::string& device_address, int request_id,
                    GATTError error, int offset,
                    const std::vector<uint8_t>& value);

  // Sends an ATT Handle-Value Notification to the device with BD_ADDR
  // |device_address| for the characteristic with handle |handle| and
  // value |value|. If |confirm| is true, then an ATT Handle-Value Indication
  // will be sent instead, which requires the remote to confirm receipt. Returns
  // false if there was an immediate error in initiating the notification
  // procedure. Otherwise, returns true and reports the asynchronous result of
  // the operation in |callback|.
  //
  // If |confirm| is true, then |callback| will be run when the remote device
  // sends a ATT Handle-Value Confirmation packet. Otherwise, it will be run as
  // soon as the notification has been sent out.
  bool SendNotification(const std::string& device_address,
                        const uint16_t handle, bool confirm,
                        const std::vector<uint8_t>& value,
                        const GattCallback& callback);

 private:
  friend class GattServerFactory;

  // Used for the internal remote connection tracking. Keeps track of the
  // request ID and the device address for the connection. If |request_id| is -1
  // then no ATT read/write request is currently pending.
  struct Connection {
    Connection(int conn_id, const RawAddress& bdaddr)
        : conn_id(conn_id), bdaddr(bdaddr) {}
    Connection() : conn_id(-1) { memset(&bdaddr, 0, sizeof(bdaddr)); }

    int conn_id;
    std::unordered_map<int, int> request_id_to_handle;
    RawAddress bdaddr;
  };

  // Used to keep track of a pending Handle-Value indication.
  struct PendingIndication {
    explicit PendingIndication(const GattCallback& callback)
        : has_success(false), callback(callback) {}

    bool has_success;
    GattCallback callback;
  };

  // Constructor shouldn't be called directly as instances are meant to be
  // obtained from the factory.
  GattServer(const UUID& uuid, int server_id);

  // hal::BluetoothGattInterface::ServerObserver overrides:
  void ConnectionCallback(hal::BluetoothGattInterface* gatt_iface, int conn_id,
                          int server_id, int connected,
                          const RawAddress& bda) override;
  void ServiceAddedCallback(hal::BluetoothGattInterface* gatt_iface, int status,
                            int server_if,
                            std::vector<btgatt_db_element_t>) override;
  void ServiceStoppedCallback(hal::BluetoothGattInterface* gatt_iface,
                              int status, int server_id,
                              int service_handle) override;
  void RequestReadCharacteristicCallback(
      hal::BluetoothGattInterface* gatt_iface, int conn_id, int trans_id,
      const RawAddress& bda, int attribute_handle, int offset,
      bool is_long) override;
  void RequestReadDescriptorCallback(hal::BluetoothGattInterface* gatt_iface,
                                     int conn_id, int trans_id,
                                     const RawAddress& bda,
                                     int attribute_handle, int offset,
                                     bool is_long) override;
  void RequestWriteCharacteristicCallback(
      hal::BluetoothGattInterface* gatt_iface, int conn_id, int trans_id,
      const RawAddress& bda, int attr_handle, int offset, bool need_rsp,
      bool is_prep, std::vector<uint8_t> value) override;
  void RequestWriteDescriptorCallback(hal::BluetoothGattInterface* gatt_iface,
                                      int conn_id, int trans_id,
                                      const RawAddress& bda, int attr_handle,
                                      int offset, bool need_rsp, bool is_prep,
                                      std::vector<uint8_t> value) override;
  void RequestExecWriteCallback(hal::BluetoothGattInterface* gatt_iface,
                                int conn_id, int trans_id,
                                const RawAddress& bda, int exec_write) override;
  void IndicationSentCallback(hal::BluetoothGattInterface* gatt_iface,
                              int conn_id, int status) override;

  // Helper function that notifies and clears the pending callback.
  void CleanUpPendingData();

  // Handles the next attribute entry in the pending service declaration.
  void HandleNextEntry(hal::BluetoothGattInterface* gatt_iface);

  // Helper method that returns a pointer to an internal Connection instance
  // that matches the given parameters.
  std::shared_ptr<Connection> GetConnection(int conn_id, const RawAddress& bda,
                                            int request_id);

  // See getters for documentation.
  UUID app_identifier_;
  int server_id_;

  // Mutex that synchronizes access to the entries below.
  std::mutex mutex_;
  ResultCallback pending_end_decl_cb_;

  // GATT connection mappings from stack-provided "conn_id" IDs and remote
  // device addresses to Connection structures. The conn_id map is one-to-one
  // while the conn_addr map is one to many, as a remote device may support
  // multiple transports (BR/EDR & LE) and use the same device address for both.
  std::unordered_map<int, std::shared_ptr<Connection>> conn_id_map_;
  std::unordered_map<std::string, std::vector<std::shared_ptr<Connection>>>
      conn_addr_map_;

  // Connections for which a Handle-Value indication is pending. Since there can
  // be multiple indications to the same device (in the case of a dual-mode
  // device with simulatenous BR/EDR & LE GATT connections), we also keep track
  // of whether there has been at least one successful confirmation.
  std::unordered_map<int, std::shared_ptr<PendingIndication>>
      pending_indications_;

  // Raw handle to the Delegate, which must outlive this GattServer instance.
  Delegate* delegate_;

  DISALLOW_COPY_AND_ASSIGN(GattServer);
};

// GattServerFactory is used to register and obtain a per-application GattServer
// instance. Users should call RegisterClient to obtain their own unique
// GattServer instance that has been registered with the Bluetooth stack.
class GattServerFactory : public BluetoothInstanceFactory,
                          private hal::BluetoothGattInterface::ServerObserver {
 public:
  // Don't construct/destruct directly except in tests. Instead, obtain a handle
  // from an Adapter instance.
  GattServerFactory();
  ~GattServerFactory() override;

  // BluetoothInstanceFactory override:
  bool RegisterInstance(const UUID& uuid,
                        const RegisterCallback& callback) override;

 private:
  // hal::BluetoothGattInterface::ServerObserver override:
  void RegisterServerCallback(hal::BluetoothGattInterface* gatt_iface,
                              int status, int server_id,
                              const bt_uuid_t& app_uuid) override;

  // Map of pending calls to register.
  std::mutex pending_calls_lock_;
  std::unordered_map<UUID, RegisterCallback> pending_calls_;

  DISALLOW_COPY_AND_ASSIGN(GattServerFactory);
};

}  // namespace bluetooth
