// 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_FAKE_LAYER_H_
#define SRC_CONNECTIVITY_BLUETOOTH_CORE_BT_HOST_GATT_FAKE_LAYER_H_

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

namespace bt::gatt::testing {

// This is a fake version of the root GATT object that can be injected in unit
// tests.
class FakeLayer final : public GATT {
 public:
  FakeLayer() = default;
  ~FakeLayer() override = default;

  // Create a new peer GATT service. Creates a peer entry if it doesn't already exist.
  // Notifies the remote service watcher if |notify| is true.
  //
  // Returns the fake remote service and a handle to the fake object.
  //
  // NOTE: the remote service watcher can also get triggered by calling DiscoverServices().
  std::pair<fbl::RefPtr<RemoteService>, fxl::WeakPtr<FakeClient>> AddPeerService(
      PeerId peer_id, const ServiceData& info, bool notify = false);

  // Assign a callback to be notified when a service discovery has been requested.
  using DiscoverServicesCallback = fit::function<void(PeerId, std::vector<UUID>)>;
  void SetDiscoverServicesCallback(DiscoverServicesCallback cb);

  // Assign the status that will be returned by the ListServices callback.
  void set_list_services_status(att::Status);

  // Assign a callback to be notified when the persist service changed CCC callback is set.
  using SetPersistServiceChangedCCCCallbackCallback = fit::function<void()>;
  void SetSetPersistServiceChangedCCCCallbackCallback(
      SetPersistServiceChangedCCCCallbackCallback cb);

  // Assign a callback to be notified when the retrieve service changed CCC callback is set.
  using SetRetrieveServiceChangedCCCCallbackCallback = fit::function<void()>;
  void SetSetRetrieveServiceChangedCCCCallbackCallback(
      SetRetrieveServiceChangedCCCCallbackCallback cb);

  // Directly force the fake layer to call the persist service changed CCC callback, to test the
  // GAP adapter and peer cache.
  void CallPersistServiceChangedCCCCallback(PeerId peer_id, bool notify, bool indicate);

  // Directly force the fake layer to call the retrieve service changed CCC callback, to test the
  // GAP adapter and peer cache.
  std::optional<ServiceChangedCCCPersistedData> CallRetrieveServiceChangedCCCCallback(
      PeerId peer_id);

  // GATT overrides:
  void AddConnection(PeerId peer_id, fbl::RefPtr<l2cap::Channel> att_chan) override;
  void RemoveConnection(PeerId peer_id) override;
  void RegisterService(ServicePtr service, ServiceIdCallback callback, ReadHandler read_handler,
                       WriteHandler write_handler, ClientConfigCallback ccc_callback) override;
  void UnregisterService(IdType service_id) override;
  void SendNotification(IdType service_id, IdType chrc_id, PeerId peer_id,
                        ::std::vector<uint8_t> value, bool indicate) override;
  void SetPersistServiceChangedCCCCallback(PersistServiceChangedCCCCallback callback) override;
  void SetRetrieveServiceChangedCCCCallback(RetrieveServiceChangedCCCCallback callback) override;
  void DiscoverServices(PeerId peer_id, std::vector<UUID> service_uuids) override;
  void RegisterRemoteServiceWatcher(RemoteServiceWatcher callback) override;
  void ListServices(PeerId peer_id, std::vector<UUID> uuids, ServiceListCallback callback) override;
  void FindService(PeerId peer_id, IdType service_id, RemoteServiceCallback callback) override;

 private:
  // Test callbacks
  DiscoverServicesCallback discover_services_cb_;
  SetPersistServiceChangedCCCCallbackCallback set_persist_service_changed_ccc_cb_cb_;
  SetRetrieveServiceChangedCCCCallbackCallback set_retrieve_service_changed_ccc_cb_cb_;

  // Emulated callbacks
  RemoteServiceWatcher remote_service_watcher_;

  PersistServiceChangedCCCCallback persist_service_changed_ccc_cb_;
  RetrieveServiceChangedCCCCallback retrieve_service_changed_ccc_cb_;

  att::Status list_services_status_;

  // Emulated GATT peer.
  struct TestPeer {
    TestPeer();
    ~TestPeer();

    FakeClient fake_client;
    std::vector<fbl::RefPtr<RemoteService>> services;

    DISALLOW_COPY_AND_ASSIGN_ALLOW_MOVE(TestPeer);
  };
  std::unordered_map<PeerId, TestPeer> peers_;

  DISALLOW_COPY_AND_ASSIGN_ALLOW_MOVE(FakeLayer);
};

}  // namespace bt::gatt::testing

#endif  // SRC_CONNECTIVITY_BLUETOOTH_CORE_BT_HOST_GATT_FAKE_LAYER_H_
