// Copyright 2020 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_WEAVE_ADAPTATION_BLE_MANAGER_IMPL_H_
#define SRC_CONNECTIVITY_WEAVE_ADAPTATION_BLE_MANAGER_IMPL_H_

#if WEAVE_DEVICE_CONFIG_ENABLE_WOBLE

#include <fuchsia/bluetooth/gatt/cpp/fidl.h>
#include <fuchsia/bluetooth/le/cpp/fidl.h>
#include <lib/sys/cpp/component_context.h>

namespace nl {
namespace Weave {
namespace DeviceLayer {
namespace Internal {

namespace testing {
class BLEManagerTest;
}  // namespace testing

namespace {
// Maximum length of device name - To avoid advertisement failure due to large advertise data.
constexpr int kMaxDeviceNameLength = 23;

// The application has enabled WoBLE advertising.
constexpr int kFlag_AdvertisingEnabled = 0x0001;
// The application has enabled fast advertising.
constexpr int kFlag_FastAdvertisingEnabled = 0x0002;
// The system is currently WoBLE advertising.
constexpr int kFlag_Advertising = 0x0004;
// The application has configured a custom BLE device name.
constexpr int kFlag_UseCustomDeviceName = 0x0008;
// The application has published Weave GATT service
constexpr int kFlag_GATTServicePublished = 0x0010;
}  // namespace

/**
 * Concrete implementation of the NetworkProvisioningServer singleton object for the Fuchsia
 * platform.
 */
class BLEManagerImpl final : public BLEManager,
                             private ::nl::Ble::BleLayer,
                             private BlePlatformDelegate,
                             private BleApplicationDelegate,
                             private fuchsia::bluetooth::gatt::LocalServiceDelegate {
  // Allow the BLEManager interface class to delegate method calls to
  // the implementation methods provided by this class.
  friend BLEManager;
  friend class testing::BLEManagerTest;

  // ===== Members that implement the BLEManager internal interface.

  WEAVE_ERROR _Init(void);
  WoBLEServiceMode _GetWoBLEServiceMode(void);
  WEAVE_ERROR _SetWoBLEServiceMode(WoBLEServiceMode service_mode);
  bool _IsAdvertisingEnabled(void);
  WEAVE_ERROR _SetAdvertisingEnabled(bool advertising_enable);
  bool _IsFastAdvertisingEnabled(void);
  WEAVE_ERROR _SetFastAdvertisingEnabled(bool fast_advertising_enable);
  bool _IsAdvertising(void);
  WEAVE_ERROR _GetDeviceName(char *device_name, size_t device_name_size);
  WEAVE_ERROR _SetDeviceName(const char *device_name);
  uint16_t _NumConnections(void);
  void _OnPlatformEvent(const WeaveDeviceEvent *event);
  ::nl::Ble::BleLayer *_GetBleLayer(void) const;

  // ===== Members that implement virtual methods on BlePlatformDelegate.

  bool SubscribeCharacteristic(BLE_CONNECTION_OBJECT conId, const WeaveBleUUID *svcId,
                               const WeaveBleUUID *charId) override;
  bool UnsubscribeCharacteristic(BLE_CONNECTION_OBJECT conId, const WeaveBleUUID *svcId,
                                 const WeaveBleUUID *charId) override;
  bool CloseConnection(BLE_CONNECTION_OBJECT conId) override;
  uint16_t GetMTU(BLE_CONNECTION_OBJECT conId) const override;
  bool SendIndication(BLE_CONNECTION_OBJECT conId, const WeaveBleUUID *svcId,
                      const WeaveBleUUID *charId, PacketBuffer *pBuf) override;
  bool SendWriteRequest(BLE_CONNECTION_OBJECT conId, const WeaveBleUUID *svcId,
                        const WeaveBleUUID *charId, PacketBuffer *pBuf) override;
  bool SendReadRequest(BLE_CONNECTION_OBJECT conId, const WeaveBleUUID *svcId,
                       const WeaveBleUUID *charId, PacketBuffer *pBuf) override;
  bool SendReadResponse(BLE_CONNECTION_OBJECT conId, BLE_READ_REQUEST_CONTEXT requestContext,
                        const WeaveBleUUID *svcId, const WeaveBleUUID *charId) override;

  // ===== Members that implement virtual methods on BleApplicationDelegate.

  void NotifyWeaveConnectionClosed(BLE_CONNECTION_OBJECT conId) override;

  // ===== Members that implement virtual methods on LocalServiceDelegate

  void OnCharacteristicConfiguration(uint64_t characteristic_id, std::string peer_id, bool notify,
                                     bool indicate) override;
  void OnReadValue(uint64_t id, int32_t offset, OnReadValueCallback callback) override;
  void OnWriteValue(uint64_t id, uint16_t offset, std::vector<uint8_t> value,
                    OnWriteValueCallback callback) override;
  void OnWriteWithoutResponse(uint64_t id, uint16_t offset, std::vector<uint8_t> value) override;

  // Drives the global |BLEManagerImpl| instance's BLE state.
  // This method will be scheduled on and called from platform manager's event loop.
  // |arg| holds pointer to BLEManagerImpl instance for which this method is scheduled.
  static void DriveBLEState(intptr_t arg);

  // Drives the weave BLE service.
  // This method publishes and advertises weave service if configured to do so.
  void DriveBLEState(void);

  // ===== Members for internal use by the following friends.

  friend BLEManager &BLEMgr(void);
  friend BLEManagerImpl &BLEMgrImpl(void);

  static BLEManagerImpl sInstance;

  // ===== Private members reserved for use by this class only.

  struct WoBLEConState {
    WoBLEConState(BLEManagerImpl *connection_instance) : instance(connection_instance) {}
    BLEManagerImpl *instance;
    PacketBuffer *pending_ind_buf;
    std::string peer_id;
  };

  WoBLEConState woble_connection_;

  char device_name_[kMaxDeviceNameLength + 1];
  uint16_t flags_;
  WoBLEServiceMode service_mode_;

  // Proxy to the gatt.Server service.
  fuchsia::bluetooth::gatt::ServerSyncPtr gatt_server_;
  fidl::Binding<fuchsia::bluetooth::gatt::LocalServiceDelegate> gatt_binding_;
  fuchsia::bluetooth::gatt::LocalServiceSyncPtr service_;
  // Proxy to the le.Peripheral service which we use for advertising to solicit connections.
  fuchsia::bluetooth::le::PeripheralSyncPtr peripheral_;
  fidl::InterfacePtr<fuchsia::bluetooth::le::AdvertisingHandle> adv_handle_;

 public:
  BLEManagerImpl();
};

/**
 * Returns a reference to the public interface of the BLEManager singleton object.
 *
 * Internal components should use this to access features of the BLEManager object
 * that are common to all platforms.
 */
inline BLEManager &BLEMgr(void) { return BLEManagerImpl::sInstance; }

/**
 * Returns the platform-specific implementation of the BLEManager singleton object.
 *
 * Internal components can use this to gain access to features of the BLEManager
 * that are specific to the Fuchsia platform.
 */
inline BLEManagerImpl &BLEMgrImpl(void) { return BLEManagerImpl::sInstance; }

inline ::nl::Ble::BleLayer *BLEManagerImpl::_GetBleLayer() const { return (BleLayer *)(this); }

inline BLEManager::WoBLEServiceMode BLEManagerImpl::_GetWoBLEServiceMode(void) {
  return service_mode_;
}

inline bool BLEManagerImpl::_IsAdvertisingEnabled(void) {
  return GetFlag(flags_, kFlag_AdvertisingEnabled);
}

inline bool BLEManagerImpl::_IsFastAdvertisingEnabled(void) { return false; }

inline bool BLEManagerImpl::_IsAdvertising(void) { return GetFlag(flags_, kFlag_Advertising); }

}  // namespace Internal
}  // namespace DeviceLayer
}  // namespace Weave
}  // namespace nl

#endif  // WEAVE_DEVICE_CONFIG_ENABLE_WOBLE

#endif  // SRC_CONNECTIVITY_WEAVE_ADAPTATION_BLE_MANAGER_IMPL_H_
