// 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_BLUETOOTH_CORE_BT_HOST_TESTING_FAKE_L2CAP_H_
#define SRC_CONNECTIVITY_BLUETOOTH_CORE_BT_HOST_TESTING_FAKE_L2CAP_H_

#include <lib/fit/function.h>

#include <unordered_map>

#include "fake_dynamic_channel.h"
#include "src/connectivity/bluetooth/core/bt-host/common/byte_buffer.h"
#include "src/connectivity/bluetooth/core/bt-host/hci/hci.h"
#include "src/connectivity/bluetooth/core/bt-host/l2cap/l2cap_defs.h"

namespace bt::testing {

// This class unpacks data units received from ACL-U and LE-U logical links
// into L2CAP SDUs and then routes them to indvidually-registered handler
// functions. Each FakePeer should have its own FakeL2cap instance and its
// own set of ACL-U and LE-U logical links.
// This class also manages the dynamic L2CAP channels, stored in
// FakeDynamicChannel objects.
// Generally, dynamic channels are created by means of ConnectionRequest packets
// sent over the fixed signaling channel, but FakeL2cap actually holds the
// channels created and modified by those requests.
// Services can register with FakeL2cap and then assign callbacks to individual
// FakeDynamicChannels (based on their PSMs), but those services do not own and
// cannot directly delete or create new channels without using the FakeL2cap
// instance managing those dynamic channels.
class FakeL2cap final {
 public:
  // Entities that instantiate FakeL2cap must provide a
  // SendFrameCallback function to handle adding necessary protocol data unit
  // header information to the packet and actually sending the packet using
  // the associated device.
  using SendFrameCallback =
      fit::function<void(hci::ConnectionHandle conn, l2cap::ChannelId cid, const ByteBuffer& pdu)>;

  // After registering a channel with RegisterHandler, ChannelReceiveCallback
  // is called with a received L2CAP Service Data Unit |sdu| when FakeL2cap
  // handles a packet for the registered channel. Includes the |handle| that
  // the L2CAP packet was received on.
  using ChannelReceiveCallback =
      fit::function<void(hci::ConnectionHandle handle, const ByteBuffer& sdu)>;

  // When FakeL2cap receives a packet with a ChannelID that does not have a
  // registered handler, it calls UnexpectedPduCallback (set via the
  // constructor or defaulted to a no-op). To aid with debugging, this callback
  // takes the entire Protocol Data Unit |pdu| (including the intact L2CAP
  // header). Also includes the |handle| that the L2CAP packet was received on.
  using UnexpectedPduCallback =
      fit::function<void(hci::ConnectionHandle handle, const ByteBuffer& pdu)>;

  // Each service that registers itself on a particular PSM provides a callback
  // that takes a pointer to the FakeDynamicChannel with its
  using FakeDynamicChannelCallback = fit::function<void(fxl::WeakPtr<FakeDynamicChannel>)>;

  // Calls |send_frame_callback| to send packets through the device
  // instantiating the FakeL2cap instance.
  // Calls |unexpected_pdu_callback| for packets received that don't have a
  // handler registered. Defaults to a no-op if no callback provided.
  // Assumes the largest possible dynamic channel ID is
  // l2cap::kLastACLDynamicChannelId.
  explicit FakeL2cap(
      SendFrameCallback send_frame_callback,
      UnexpectedPduCallback unexpected_pdu_callback = [](auto handle, auto& pdu) {},
      l2cap::ChannelId largest_channel_id = l2cap::kLastACLDynamicChannelId);

  // Public methods for services/clients that operate over L2CAP channels:
  // TODO (fxbug.dev/57535) Add Unit tests for public methods

  // Register |callback| to be called when a Service Data Unit (SDU) is
  // received on an L2CAP channel identified by |cid|. |callback| will be
  // retained until overwritten by another RegisterHandler call or this
  // class is destroyed. To remove a specific |callback|, overwrite it by
  // registering a no-op (or other handler) on the corresponding |cid|.
  // This should only be used for registering fixed channel handlers - use
  // RegisterDynamicChannel for dynamic channel management.
  void RegisterHandler(l2cap::ChannelId cid, ChannelReceiveCallback callback);

  // Register a |callback| function that configures a FakeDynamicChannel which
  // operates over a Protocol Service Multiplexer |psm|. When
  // RegisterDynamicChannelWithPsm() will call this FakeDynamicChannelCallback
  // if the channel is open.
  void RegisterService(l2cap::PSM psm, FakeDynamicChannelCallback callback);

  // The following methods are generally for use by the FakeSignalingServer when
  // creating and managing individual FakeDynamicChannel instances.

  // Register a new FakeDynamicChannel with an associated connection handle
  // |conn|, Protocol Service Multiplexer PSM, remote Channel ID
  // |remote_cid|, and local Channel ID |local_cid|.
  // This channel will be closed, as this function only allocates
  // a local ID for the channel. This function also does not register the
  // channel with the service associated with the channel's PSM, as this
  // happens after the channel is open.
  // Return status of if the registration was successful.
  // This should only be used for registering dynamic channels - use
  // RegisterHandler for fixed channel management.
  bool RegisterDynamicChannel(hci::ConnectionHandle conn, l2cap::PSM psm,
                              l2cap::ChannelId local_cid, l2cap::ChannelId remote_cid);

  // Call the DynamicChannelCallback associated with the service operating
  // on the channel's PSM once this channel has been opened.
  // Applications should only call this function after confirming that the
  // channel associated with the connection handle |conn| and local channel ID
  // |local_cid| is already open, as the DynamicChannelCallback associated with
  // the PSM will assume that it can operate over the channel.
  // Return status of if the registration was successful.
  bool RegisterDynamicChannelWithPsm(hci::ConnectionHandle conn, l2cap::ChannelId local_cid);

  // Return true if there is a FakeDynamicChannelCallback registered for
  // Protocol Service Multiplexer |psm|, return false otherwise.
  bool ServiceRegisteredForPsm(l2cap::PSM psm);

  // Methods to observe and manipulate L2CAP channel states:

  // Return the first local dynamic Channel Id that does not already have a
  // FakeDynamicChannel object associated with it. This incrementally checks
  // each individual ID starting from l2cap::kFirstDynamicChannelId up to this
  // FakeL2cap instance's largest_channel_id_, so runtime increases linearly
  // with the number of consecutive registered channels but can be limited by
  // limiting the value of largest_channel_id_ when initializing FakeL2cap. If
  // there are no available Channel IDs, returns l2cap::kInvalidChannelId.
  // Requires identification of the specific ConnectionHandle |conn| associated
  // with this connection.
  l2cap::ChannelId FindAvailableDynamicChannelId(hci::ConnectionHandle conn);

  // Find the FakeDynamicChannel object with the local channel ID |local_cid|
  // and connection handle |conn| in the dynamic_channels_ map. If there is no
  // channel registered with the |local_cid|, return a nullptr.
  fxl::WeakPtr<FakeDynamicChannel> FindDynamicChannelByLocalId(hci::ConnectionHandle conn,
                                                               l2cap::ChannelId local_cid);

  // Find the FakeDynamicChannel object with the connection handle |conn| and
  // local channel ID |remote_cid| in the dynamic_channels_ map. If there is
  // no channel registered with the |remote_cid|, return a nullptr.
  fxl::WeakPtr<FakeDynamicChannel> FindDynamicChannelByRemoteId(hci::ConnectionHandle conn,
                                                                l2cap::ChannelId remote_cid);

  // Remove a dynamic channel associated with the connection handle |conn| and locassigned
  // |local_cid|. Will call the channel's ChannelClosedCallback if it has one, set the channel to
  // closed, and then delete the value from the map FakeL2cap uses to store
  // the channels (which should also destroy the channel itself),
  // This is the only way that dynamic channels should be deleted - if they are
  // torn down individually, FakeL2cap will incorrectly hold that local_cid.
  void DeleteDynamicChannelByLocalId(hci::ConnectionHandle conn, l2cap::ChannelId local_cid);

  // Routes the |pdu| to the appropriate calllback function by extracting the
  // ChannelID of the received packet |pdu| and calling the corresponding
  // registered handler function (and providing it with the |handle| the packet
  // was received on and the payload Service Data Unit |sdu|.
  void HandlePdu(hci::ConnectionHandle conn, const ByteBuffer& pdu);

  // Return the SendFrameCallback associated with this FakeL2cap instance.
  SendFrameCallback& send_frame_callback() { return send_frame_callback_; }

 private:
  // Map of channel IDs and corresponding functions. Use an unordered map for
  // constant-time (in the best case) for search/insertion/deletion when
  // accessing calllbacks associated with specific channel IDs.
  std::unordered_map<l2cap::ChannelId, ChannelReceiveCallback> callbacks_;

  // Map of dynamically allocated Channel IDs and corresponding channels. Use
  // an unordered map for constant-time search/insertion/deletion when
  // accessing channels associated with specific channel IDs.
  std::unordered_map<hci::ConnectionHandle,
                     std::unordered_map<l2cap::ChannelId, std::unique_ptr<FakeDynamicChannel>>>
      dynamic_channels_;

  // Map of individual channel configuration callbacks associated with
  // individual services
  std::unordered_map<l2cap::PSM, FakeDynamicChannelCallback> registered_services_;

  // Function provided by the device that instantiates the FakeL2cap instance
  // that adds PDU header information and actually sends the packet.
  SendFrameCallback send_frame_callback_;

  // Handler function associated with unexpected PDUs. Defaults to a no-op.
  UnexpectedPduCallback unexpected_pdu_callback_;

  // Largest dynamic channel ID this FakeL2cap instance can allocate IDs for.
  // Defaults to l2cap::kLastACLDynamicChannelId.
  l2cap::ChannelId largest_channel_id_;
  DISALLOW_COPY_AND_ASSIGN_ALLOW_MOVE(FakeL2cap);
};

}  // namespace bt::testing

#endif  // SRC_CONNECTIVITY_BLUETOOTH_CORE_BT_HOST_TESTING_FAKE_L2CAP_H_
