// 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_DATA_FAKE_DOMAIN_H_
#define GARNET_DRIVERS_BLUETOOTH_LIB_DATA_FAKE_DOMAIN_H_

#include "garnet/drivers/bluetooth/lib/data/domain.h"
#include "garnet/drivers/bluetooth/lib/data/l2cap_socket_factory.h"

namespace btlib {

namespace l2cap {
namespace testing {
class FakeChannel;
}  // namespace testing
}  // namespace l2cap

namespace data {
namespace testing {

// This is a fake version of the Domain class that can be injected into other
// layers for unit testing.
class FakeDomain final : public Domain {
 public:
  inline static fbl::RefPtr<FakeDomain> Create() {
    return fbl::AdoptRef(new FakeDomain());
  }

  // Triggers a LE connection parameter update callback on the given link.
  void TriggerLEConnectionParameterUpdate(
      hci::ConnectionHandle handle,
      const hci::LEPreferredConnectionParameters& params);

  // Triggers the completed opening of an outbound dynamic channel on the given
  // link. The channels created will be provided to callers of OpenChannel,
  // where multiple requests for the same PSM will be handled in FIFO order.
  void TriggerOutboundL2capChannel(hci::ConnectionHandle handle, l2cap::PSM psm,
                                   l2cap::ChannelId id,
                                   l2cap::ChannelId remote_id);

  // Triggers the creation of an inbound dynamic channel on the given link. The
  // channels created will be provided to handlers passed to RegisterService.
  void TriggerInboundL2capChannel(hci::ConnectionHandle handle, l2cap::PSM psm,
                                  l2cap::ChannelId id,
                                  l2cap::ChannelId remote_id);

  // Triggers a link error callback on the given link.
  void TriggerLinkError(hci::ConnectionHandle handle);

  // Domain overrides:
  void Initialize() override;
  void ShutDown() override;
  void AddACLConnection(hci::ConnectionHandle handle,
                        hci::Connection::Role role,
                        l2cap::LinkErrorCallback link_error_callback,
                        async_dispatcher_t* dispatcher) override;
  void AddLEConnection(
      hci::ConnectionHandle handle, hci::Connection::Role role,
      l2cap::LinkErrorCallback link_error_callback,
      l2cap::LEFixedChannelsCallback channel_callback,
      l2cap::LEConnectionParameterUpdateCallback conn_param_callback,
      async_dispatcher_t* dispatcher) override;
  void RemoveConnection(hci::ConnectionHandle handle) override;
  void OpenL2capChannel(hci::ConnectionHandle handle, l2cap::PSM psm,
                        l2cap::ChannelCallback cb,
                        async_dispatcher_t* dispatcher) override;
  void OpenL2capChannel(hci::ConnectionHandle handle, l2cap::PSM psm,
                        SocketCallback socket_callback,
                        async_dispatcher_t* dispatcher) override;
  void RegisterService(l2cap::PSM psm, l2cap::ChannelCallback channel_callback,
                       async_dispatcher_t* dispatcher) override;
  void RegisterService(l2cap::PSM psm, SocketCallback socket_callback,
                       async_dispatcher_t* dispatcher) override;
  void UnregisterService(l2cap::PSM psm) override;

  // Called when a new channel gets opened. Tests can use this to obtain a
  // reference to all channels.
  using FakeChannelCallback =
      fit::function<void(fbl::RefPtr<l2cap::testing::FakeChannel>)>;
  void set_channel_callback(FakeChannelCallback callback) {
    chan_cb_ = std::move(callback);
  }

 private:
  friend class fbl::RefPtr<FakeDomain>;

  // TODO(armansito): Consider moving the following logic into an internal fake
  // that is L2CAP-specific.
  using ChannelDelivery =
      std::pair<l2cap::ChannelCallback, async_dispatcher_t*>;
  struct LinkData {
    hci::ConnectionHandle handle;
    hci::Connection::Role role;
    hci::Connection::LinkType type;

    async_dispatcher_t* dispatcher;

    // Dual-mode callbacks
    l2cap::LinkErrorCallback link_error_cb;
    std::unordered_map<l2cap::PSM, std::list<ChannelDelivery>>
        outbound_conn_cbs;

    // LE-only callbacks
    l2cap::LEConnectionParameterUpdateCallback le_conn_param_cb;
  };

  FakeDomain() = default;
  ~FakeDomain() override = default;

  LinkData* RegisterInternal(hci::ConnectionHandle handle,
                             hci::Connection::Role role,
                             hci::Connection::LinkType link_type,
                             l2cap::LinkErrorCallback link_error_callback,
                             async_dispatcher_t* dispatcher);
  fbl::RefPtr<l2cap::testing::FakeChannel> OpenFakeChannel(
      LinkData* link, l2cap::ChannelId id, l2cap::ChannelId remote_id);
  fbl::RefPtr<l2cap::testing::FakeChannel> OpenFakeFixedChannel(
      LinkData* link, l2cap::ChannelId id);
  LinkData& FindLinkData(hci::ConnectionHandle handle);

  bool initialized_ = false;
  std::unordered_map<hci::ConnectionHandle, LinkData> links_;
  FakeChannelCallback chan_cb_;
  std::unordered_map<l2cap::PSM, ChannelDelivery> inbound_conn_cbs_;

  // Makes sockets for RegisterService
  internal::L2capSocketFactory socket_factory_;

  FXL_DISALLOW_COPY_AND_ASSIGN(FakeDomain);
};

}  // namespace testing
}  // namespace data
}  // namespace btlib

#endif  // GARNET_DRIVERS_BLUETOOTH_LIB_DATA_FAKE_DOMAIN_H_
