#include "test_packets.h"

#include "src/connectivity/bluetooth/core/bt-host/common/test_helpers.h"
#include "src/connectivity/bluetooth/core/bt-host/hci/hci.h"
#include "src/connectivity/bluetooth/core/bt-host/l2cap/fcs.h"
#include "src/connectivity/bluetooth/core/bt-host/l2cap/frame_headers.h"
#include "src/connectivity/bluetooth/core/bt-host/l2cap/l2cap.h"

namespace bt::l2cap::testing {

DynamicByteBuffer AclExtFeaturesInfoReq(l2cap::CommandId id, hci::ConnectionHandle handle) {
  return DynamicByteBuffer(StaticByteBuffer(
      // ACL data header (handle, length: 10)
      LowerBits(handle), UpperBits(handle), 0x0a, 0x00,

      // L2CAP B-frame header (length: 6, chanel-id: 0x0001 (ACL sig))
      0x06, 0x00, 0x01, 0x00,

      // Extended Features Information Request
      // (ID, length: 2, type)
      0x0a, id, 0x02, 0x00,
      LowerBits(static_cast<uint16_t>(InformationType::kExtendedFeaturesSupported)),
      UpperBits(static_cast<uint16_t>(InformationType::kExtendedFeaturesSupported))));
}

DynamicByteBuffer AclCommandRejectNotUnderstoodRsp(l2cap::CommandId id,
                                                   hci::ConnectionHandle handle,
                                                   ChannelId chan_id) {
  return DynamicByteBuffer(StaticByteBuffer(
      // ACL data header (handle: |link_handle|, length: 10 bytes)
      LowerBits(handle), UpperBits(handle), 0x0a, 0x00,
      // L2CAP B-frame header (length: 6 bytes, channel-id: 0x0001 (ACL sig))
      0x06, 0x00, LowerBits(chan_id), UpperBits(chan_id),
      // Information Response (type, ID, length: 2)
      l2cap::kCommandRejectCode, id, 0x02, 0x00,
      // Reason = Not Understood
      LowerBits(static_cast<uint16_t>(RejectReason::kNotUnderstood)),
      UpperBits(static_cast<uint16_t>(RejectReason::kNotUnderstood))));
}

DynamicByteBuffer AclExtFeaturesInfoRsp(l2cap::CommandId id, hci::ConnectionHandle handle,
                                        l2cap::ExtendedFeatures features) {
  const auto features_bytes = ToBytes(features);
  return DynamicByteBuffer(StaticByteBuffer(
      // ACL data header (handle: |link_handle|, length: 16 bytes)
      LowerBits(handle), UpperBits(handle), 0x10, 0x00,
      // L2CAP B-frame header (length: 12 bytes, channel-id: 0x0001 (ACL sig))
      0x0c, 0x00, 0x01, 0x00,
      // Information Response (type, ID, length: 8)
      l2cap::kInformationResponse, id, 0x08, 0x00,
      // Type = Features Mask
      0x02, 0x00,
      // Result = Success
      0x00, 0x00,
      // Data (Mask)
      features_bytes[0], features_bytes[1], features_bytes[2], features_bytes[3]));
}

DynamicByteBuffer AclFixedChannelsSupportedInfoReq(l2cap::CommandId id,
                                                   hci::ConnectionHandle handle) {
  return DynamicByteBuffer(StaticByteBuffer(
      // ACL data header (handle, length: 10)
      LowerBits(handle), UpperBits(handle), 0x0a, 0x00,

      // L2CAP B-frame header (length: 6, chanel-id: 0x0001 (ACL sig))
      0x06, 0x00, 0x01, 0x00,

      // Fixed Channels Supported Information Request
      // (ID, length: 2, info type)
      l2cap::kInformationRequest, id, 0x02, 0x00,
      LowerBits(static_cast<uint16_t>(InformationType::kFixedChannelsSupported)),
      UpperBits(static_cast<uint16_t>(InformationType::kFixedChannelsSupported))));
}

DynamicByteBuffer AclFixedChannelsSupportedInfoRsp(l2cap::CommandId id,
                                                   hci::ConnectionHandle handle,
                                                   l2cap::FixedChannelsSupported chan_mask) {
  const auto chan_bytes = ToBytes(chan_mask);
  return DynamicByteBuffer(StaticByteBuffer(
      // ACL data header (handle: |link_handle|, length: 20 bytes)
      LowerBits(handle), UpperBits(handle), 0x14, 0x00,
      // L2CAP B-frame header (length: 16 bytes, channel-id: 0x0001 (ACL sig))
      0x10, 0x00, 0x01, 0x00,
      // Information Response (type, ID, length: 12)
      l2cap::kInformationResponse, id, 0x0c, 0x00,
      // Type = Fixed Channels Supported
      0x03, 0x00,
      // Result = Success
      0x00, 0x00,
      // Data (Mask)
      chan_bytes[0], chan_bytes[1], chan_bytes[2], chan_bytes[3], chan_bytes[4], chan_bytes[5],
      chan_bytes[6], chan_bytes[7]));
}

DynamicByteBuffer AclNotSupportedInformationResponse(l2cap::CommandId id,
                                                     hci::ConnectionHandle handle) {
  return DynamicByteBuffer(StaticByteBuffer(
      // ACL data header (handle: |link_handle|, length: 12 bytes)
      LowerBits(handle), UpperBits(handle), 0x0c, 0x00,
      // L2CAP B-frame header (length: 8 bytes, channel-id: 0x0001 (ACL sig))
      0x08, 0x00, 0x01, 0x00,
      // Information Response (type, ID, length: 4)
      l2cap::kInformationResponse, id, 0x04, 0x00,
      // Type = invalid type
      0xFF, 0xFF,
      // Result
      LowerBits(static_cast<uint16_t>(l2cap::InformationResult::kNotSupported)),
      UpperBits(static_cast<uint16_t>(l2cap::InformationResult::kNotSupported))));
}

DynamicByteBuffer AclConfigReq(l2cap::CommandId id, hci::ConnectionHandle handle,
                               l2cap::ChannelId dst_id, l2cap::ChannelParameters params) {
  const auto mode = params.mode.value_or(l2cap::ChannelMode::kBasic);
  const auto mtu = params.max_rx_sdu_size.value_or(l2cap::kMaxMTU);

  switch (mode) {
    case l2cap::ChannelMode::kBasic:
      return DynamicByteBuffer(StaticByteBuffer(
          // ACL data header (handle, length: 16 bytes)
          LowerBits(handle), UpperBits(handle), 0x10, 0x00,
          // L2CAP B-frame header (length: 12, channel-id: 0x0001 (ACL sig))
          0x0c, 0x00, 0x01, 0x00,
          // Configuration Request (ID, length: 8, |dst_id|, flags: 0,
          0x04, id, 0x08, 0x00, LowerBits(dst_id), UpperBits(dst_id), 0x00, 0x00,
          // MTU option: (ID: 1, length: 2, mtu)
          0x01, 0x02, LowerBits(mtu), UpperBits(mtu)));
    case l2cap::ChannelMode::kEnhancedRetransmission:
      return DynamicByteBuffer(StaticByteBuffer(
          // ACL data header (handle, length: 27 bytes)
          LowerBits(handle), UpperBits(handle), 0x1b, 0x00,
          // L2CAP B-frame header (length: 23, channel-id: 0x0001 (ACL sig))
          0x17, 0x00, 0x01, 0x00,
          // Configuration Request (ID, length: 19, |dst_id|, flags: 0,
          0x04, id, 0x13, 0x00, LowerBits(dst_id), UpperBits(dst_id), 0x00, 0x00,
          // MTU option: (ID: 1, length: 2, mtu)
          0x01, 0x02, LowerBits(mtu), UpperBits(mtu),
          // Retransmission & Flow Control option (Type, Length = 9, mode, fields)
          0x04, 0x09, static_cast<uint8_t>(mode), l2cap::kErtmMaxUnackedInboundFrames,
          l2cap::kErtmMaxInboundRetransmissions, 0x00, 0x00, 0x00, 0x00,
          LowerBits(l2cap::kMaxInboundPduPayloadSize),
          UpperBits(l2cap::kMaxInboundPduPayloadSize)));
    default:
      ZX_ASSERT_MSG(false, "unsupported mode");
  }
}

DynamicByteBuffer AclConfigRsp(l2cap::CommandId id, hci::ConnectionHandle link_handle,
                               l2cap::ChannelId src_id, l2cap::ChannelParameters params) {
  const auto mode = params.mode.value_or(l2cap::ChannelMode::kBasic);
  const auto mtu = params.max_rx_sdu_size.value_or(l2cap::kMaxMTU);

  switch (mode) {
    case l2cap::ChannelMode::kBasic:
      return DynamicByteBuffer(StaticByteBuffer(
          // ACL data header (handle: |link_handle|, length: 18 bytes)
          LowerBits(link_handle), UpperBits(link_handle), 0x12, 0x00,
          // L2CAP B-frame header (length: 14 bytes, channel-id: 0x0001 (ACL sig))
          0x0e, 0x00, 0x01, 0x00,
          // Configuration Response (ID, length: 10, src cid, flags: 0,
          // result: success)
          0x05, id, 0x0a, 0x00, LowerBits(src_id), UpperBits(src_id), 0x00, 0x00, 0x00, 0x00,
          // MTU option: (ID: 1, length: 2, mtu)
          0x01, 0x02, LowerBits(mtu), UpperBits(mtu)));
    case l2cap::ChannelMode::kEnhancedRetransmission: {
      const auto rtx_timeout = kErtmReceiverReadyPollTimerDuration.to_msecs();
      const auto monitor_timeout = kErtmMonitorTimerDuration.to_msecs();
      return DynamicByteBuffer(StaticByteBuffer(
          // ACL data header (handle: |link_handle|, length: 29 bytes)
          LowerBits(link_handle), UpperBits(link_handle), 0x1d, 0x00,
          // L2CAP B-frame header (length: 25 bytes, channel-id: 0x0001 (ACL sig))
          0x19, 0x00, 0x01, 0x00,
          // Configuration Response (ID, length: 21, src cid, flags: 0,
          // result: success)
          0x05, id, 0x15, 0x00, LowerBits(src_id), UpperBits(src_id), 0x00, 0x00, 0x00, 0x00,
          // MTU option: (ID: 1, length: 2, mtu)
          0x01, 0x02, LowerBits(mtu), UpperBits(mtu),
          // Retransmission & Flow Control option (Type, Length = 9, mode, fields)
          0x04, 0x09, static_cast<uint8_t>(mode), l2cap::kErtmMaxUnackedInboundFrames,
          l2cap::kErtmMaxInboundRetransmissions, LowerBits(rtx_timeout), UpperBits(rtx_timeout),
          LowerBits(monitor_timeout), UpperBits(monitor_timeout),
          LowerBits(l2cap::kMaxInboundPduPayloadSize),
          UpperBits(l2cap::kMaxInboundPduPayloadSize)));
    }
    default:
      ZX_ASSERT_MSG(false, "unsupported mode");
  }
}

DynamicByteBuffer AclConnectionReq(l2cap::CommandId id, hci::ConnectionHandle link_handle,
                                   l2cap::ChannelId src_id, l2cap::PSM psm) {
  return DynamicByteBuffer(StaticByteBuffer(
      // ACL data header (handle: |link_handle|, length: 12 bytes)
      LowerBits(link_handle), UpperBits(link_handle), 0x0c, 0x00,

      // L2CAP B-frame header (length: 8 bytes, channel-id: 0x0001 (ACL sig))
      0x08, 0x00, 0x01, 0x00,

      // Connection Request (ID, length: 4, |psm|, |src_id|)
      0x02, id, 0x04, 0x00, LowerBits(psm), UpperBits(psm), LowerBits(src_id), UpperBits(src_id)));
}

DynamicByteBuffer AclConnectionRsp(l2cap::CommandId id, hci::ConnectionHandle link_handle,
                                   l2cap::ChannelId src_id, l2cap::ChannelId dst_id,
                                   l2cap::ConnectionResult result) {
  return DynamicByteBuffer(StaticByteBuffer(
      // ACL data header (handle: |link handle|, length: 16 bytes)
      LowerBits(link_handle), UpperBits(link_handle), 0x10, 0x00,
      // L2CAP B-frame header: length 12, channel-id 1 (signaling)
      0x0c, 0x00, 0x01, 0x00,
      // Connection Response (0x03), id, length 8
      l2cap::kConnectionResponse, id, 0x08, 0x00,
      // destination cid
      LowerBits(dst_id), UpperBits(dst_id),
      // source cid
      LowerBits(src_id), UpperBits(src_id),
      // Result
      LowerBits(static_cast<uint16_t>(result)), UpperBits(static_cast<uint16_t>(result)),
      // Status (no further information available)
      0x00, 0x00));
}

DynamicByteBuffer AclDisconnectionReq(l2cap::CommandId id, hci::ConnectionHandle link_handle,
                                      l2cap::ChannelId src_id, l2cap::ChannelId dst_id) {
  return DynamicByteBuffer(StaticByteBuffer(
      // ACL data header (handle: |link handle|, length: 12 bytes)
      LowerBits(link_handle), UpperBits(link_handle), 0x0c, 0x00,
      // L2CAP B-frame header: length 8, channel-id 1 (signaling)
      0x08, 0x00, 0x01, 0x00,
      // Disconnection Request, id, length 4
      l2cap::kDisconnectionRequest, id, 0x04, 0x00,
      // Destination CID
      LowerBits(dst_id), UpperBits(dst_id),
      // Source CID
      LowerBits(src_id), UpperBits(src_id)));
}

DynamicByteBuffer AclConnectionParameterUpdateReq(l2cap::CommandId id,
                                                  hci::ConnectionHandle link_handle,
                                                  uint16_t interval_min, uint16_t interval_max,
                                                  uint16_t slave_latency,
                                                  uint16_t timeout_multiplier) {
  return DynamicByteBuffer(StaticByteBuffer(
      // ACL data header (handle: |link handle|, length: 16 bytes)
      LowerBits(link_handle), UpperBits(link_handle), 0x10, 0x00,
      // L2CAP B-frame header: length 12, channel-id 5 (LE signaling)
      0x0c, 0x00, 0x05, 0x00,
      // Connection Parameter Update Request (0x12), id, length 8
      l2cap::kConnectionParameterUpdateRequest, id, 0x08, 0x00,
      // interval min
      LowerBits(interval_min), UpperBits(interval_min),
      // interval max
      LowerBits(interval_max), UpperBits(interval_max),
      // slave latency
      LowerBits(slave_latency), UpperBits(slave_latency),
      // timeout multiplier
      LowerBits(timeout_multiplier), UpperBits(timeout_multiplier)));
}

DynamicByteBuffer AclConnectionParameterUpdateRsp(l2cap::CommandId id,
                                                  hci::ConnectionHandle link_handle,
                                                  ConnectionParameterUpdateResult result) {
  return DynamicByteBuffer(StaticByteBuffer(
      // ACL data header (handle: |link handle|, length: 10 bytes)
      LowerBits(link_handle), UpperBits(link_handle), 0x0a, 0x00,
      // L2CAP B-frame header: length 6, channel-id 5 (LE signaling)
      0x06, 0x00, 0x05, 0x00,
      // Connection Parameter Update Response (0x13), id, length 2
      l2cap::kConnectionParameterUpdateResponse, id, 0x02, 0x00,
      // Result
      LowerBits(static_cast<uint16_t>(result)), UpperBits(static_cast<uint16_t>(result))));
}

DynamicByteBuffer AclSFrameReceiverReady(hci::ConnectionHandle link_handle,
                                         l2cap::ChannelId channel_id, uint8_t receive_seq_num,
                                         bool is_poll_request, bool is_poll_response) {
  StaticByteBuffer acl_packet{
      // ACL data header (handle: |link handle|, length: 8 bytes)
      LowerBits(link_handle), UpperBits(link_handle), 0x08, 0x00,

      // L2CAP B-frame header: length 4, channel-id
      0x04, 0x00, LowerBits(channel_id), UpperBits(channel_id),

      // Enhanced Control Field: F is_poll_response, P is_poll_request, Supervisory function 0 (RR),
      // Type S-Frame, ReqSeq receive_seq_num
      (is_poll_response ? 0b1000'0000 : 0) | (is_poll_request ? 0b1'0000 : 0) | 0b1,
      receive_seq_num & 0b11'1111,

      // Frame Check Sequence
      0x00, 0x00};
  const FrameCheckSequence fcs = ComputeFcs(
      acl_packet.view(sizeof(hci::ACLDataHeader),
                      acl_packet.size() - sizeof(hci::ACLDataHeader) - sizeof(FrameCheckSequence)));
  acl_packet[acl_packet.size() - 2] = LowerBits(fcs.fcs);
  acl_packet[acl_packet.size() - 1] = UpperBits(fcs.fcs);
  return DynamicByteBuffer(acl_packet);
}

DynamicByteBuffer AclIFrame(hci::ConnectionHandle link_handle, l2cap::ChannelId channel_id,
                            uint8_t receive_seq_num, uint8_t tx_seq, bool is_poll_response,
                            const ByteBuffer& payload) {
  const uint16_t l2cap_size =
      sizeof(internal::SimpleInformationFrameHeader) + payload.size() + sizeof(FrameCheckSequence);
  const uint16_t acl_size = l2cap_size + sizeof(BasicHeader);
  StaticByteBuffer headers(
      // ACL data header (handle: |link handle|, length)
      LowerBits(link_handle), UpperBits(link_handle), LowerBits(acl_size), UpperBits(acl_size),

      // L2CAP B-frame header: length, channel-id
      LowerBits(l2cap_size), UpperBits(l2cap_size), LowerBits(channel_id), UpperBits(channel_id),

      // Enhanced Control Field: F is_poll_response, TxSeq tx_seq, Type I-Frame,
      // ReqSeq receive_seq_num
      (is_poll_response ? 0b1000'0000 : 0) | ((tx_seq << 1) & 0b111'1110),
      receive_seq_num & 0b11'1111);

  FrameCheckSequence fcs = ComputeFcs(headers.view(sizeof(hci::ACLDataHeader), acl_size));
  fcs = ComputeFcs(payload.view(), fcs);

  DynamicByteBuffer acl_packet(headers.size() + payload.size() + sizeof(fcs));
  headers.Copy(&acl_packet);
  auto payload_destination = acl_packet.mutable_view(headers.size());
  payload.Copy(&payload_destination);
  acl_packet[acl_packet.size() - 2] = LowerBits(fcs.fcs);
  acl_packet[acl_packet.size() - 1] = UpperBits(fcs.fcs);
  return acl_packet;
}

}  // namespace bt::l2cap::testing
