// 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.

#include "src/connectivity/bluetooth/core/bt-host/l2cap/bredr_command_handler.h"

#include <lib/async/cpp/task.h>

#include <memory>
#include <unordered_map>
#include <vector>

#include "lib/gtest/test_loop_fixture.h"
#include "src/connectivity/bluetooth/core/bt-host/common/test_helpers.h"
#include "src/connectivity/bluetooth/core/bt-host/l2cap/channel_configuration.h"
#include "src/connectivity/bluetooth/core/bt-host/l2cap/fake_signaling_channel.h"
#include "src/connectivity/bluetooth/core/bt-host/l2cap/l2cap.h"

namespace bt {
namespace l2cap {
namespace internal {
namespace {

using TestBase = ::gtest::TestLoopFixture;

constexpr uint16_t kPsm = 0x0001;
constexpr ChannelId kLocalCId = 0x0040;
constexpr ChannelId kRemoteCId = 0x60a3;

class L2CAP_BrEdrCommandHandlerTest : public TestBase {
 public:
  L2CAP_BrEdrCommandHandlerTest() = default;
  ~L2CAP_BrEdrCommandHandlerTest() override = default;
  DISALLOW_COPY_AND_ASSIGN_ALLOW_MOVE(L2CAP_BrEdrCommandHandlerTest);

 protected:
  // TestLoopFixture overrides
  void SetUp() override {
    TestBase::SetUp();
    signaling_channel_ = std::make_unique<testing::FakeSignalingChannel>(dispatcher());
    command_handler_ = std::make_unique<BrEdrCommandHandler>(
        fake_sig(), fit::bind_member(this, &L2CAP_BrEdrCommandHandlerTest::OnRequestFail));
    request_fail_callback_ = nullptr;
    failed_requests_ = 0;
  }

  void TearDown() override {
    request_fail_callback_ = nullptr;
    signaling_channel_ = nullptr;
    command_handler_ = nullptr;
    TestBase::TearDown();
  }

  testing::FakeSignalingChannel* fake_sig() const { return signaling_channel_.get(); }
  BrEdrCommandHandler* cmd_handler() const { return command_handler_.get(); }
  size_t failed_requests() const { return failed_requests_; }

  void set_request_fail_callback(fit::closure request_fail_callback) {
    ZX_ASSERT(!request_fail_callback_);
    request_fail_callback_ = std::move(request_fail_callback);
  }

 private:
  void OnRequestFail() {
    failed_requests_++;
    if (request_fail_callback_) {
      request_fail_callback_();
    }
  }

  std::unique_ptr<testing::FakeSignalingChannel> signaling_channel_;
  std::unique_ptr<BrEdrCommandHandler> command_handler_;
  fit::closure request_fail_callback_;
  size_t failed_requests_;
};

TEST_F(L2CAP_BrEdrCommandHandlerTest, OutboundConnReqRej) {
  constexpr ChannelId kBadLocalCId = 0x0005;  // Not a dynamic channel

  // Connection Request payload
  auto expected_conn_req = CreateStaticByteBuffer(
      // PSM
      LowerBits(kPsm), UpperBits(kPsm),

      // Source CID
      LowerBits(kBadLocalCId), UpperBits(kBadLocalCId));

  // Command Reject payload
  auto rej_rsp = CreateStaticByteBuffer(
      // Reject Reason (invalid channel ID)
      LowerBits(static_cast<uint16_t>(RejectReason::kInvalidCID)),
      UpperBits(static_cast<uint16_t>(RejectReason::kInvalidCID)),

      // Local (relative to rejecter) CID
      LowerBits(kInvalidChannelId), UpperBits(kInvalidChannelId),

      // Remote (relative to rejecter) CID
      LowerBits(kBadLocalCId), UpperBits(kBadLocalCId));
  EXPECT_OUTBOUND_REQ(*fake_sig(), kConnectionRequest, expected_conn_req.view(),
                      {SignalingChannel::Status::kReject, rej_rsp.view()});

  bool cb_called = false;
  auto on_conn_rsp = [&cb_called,
                      kBadLocalCId](const BrEdrCommandHandler::ConnectionResponse& rsp) {
    cb_called = true;
    EXPECT_EQ(BrEdrCommandHandler::Status::kReject, rsp.status());
    EXPECT_EQ(kInvalidChannelId, rsp.remote_cid());
    EXPECT_EQ(kBadLocalCId, rsp.local_cid());
    return BrEdrCommandHandler::ResponseHandlerAction::kCompleteOutboundTransaction;
  };

  EXPECT_TRUE(cmd_handler()->SendConnectionRequest(kPsm, kBadLocalCId, std::move(on_conn_rsp)));
  RunLoopUntilIdle();
  EXPECT_TRUE(cb_called);
}

TEST_F(L2CAP_BrEdrCommandHandlerTest, OutboundConnReqRejNotEnoughBytesInRejection) {
  constexpr ChannelId kBadLocalCId = 0x0005;  // Not a dynamic channel

  // Connection Request payload
  auto expected_conn_req = CreateStaticByteBuffer(
      // PSM
      LowerBits(kPsm), UpperBits(kPsm),

      // Source CID
      LowerBits(kBadLocalCId), UpperBits(kBadLocalCId));

  // Command Reject payload (the invalid channel IDs are missing)
  auto rej_rsp = CreateStaticByteBuffer(
      // Reject Reason (invalid channel ID)
      LowerBits(static_cast<uint16_t>(RejectReason::kInvalidCID)),
      UpperBits(static_cast<uint16_t>(RejectReason::kInvalidCID)));

  EXPECT_OUTBOUND_REQ(*fake_sig(), kConnectionRequest, expected_conn_req.view(),
                      {SignalingChannel::Status::kReject, rej_rsp.view()});

  bool cb_called = false;
  auto on_conn_rsp = [&cb_called](const BrEdrCommandHandler::ConnectionResponse& rsp) {
    cb_called = true;
    return BrEdrCommandHandler::ResponseHandlerAction::kCompleteOutboundTransaction;
  };

  EXPECT_TRUE(cmd_handler()->SendConnectionRequest(kPsm, kBadLocalCId, std::move(on_conn_rsp)));
  RunLoopUntilIdle();
  EXPECT_FALSE(cb_called);
}

TEST_F(L2CAP_BrEdrCommandHandlerTest, OutboundConnReqRspOk) {
  // Connection Request payload
  auto expected_conn_req = CreateStaticByteBuffer(
      // PSM
      LowerBits(kPsm), UpperBits(kPsm),

      // Source CID
      LowerBits(kLocalCId), UpperBits(kLocalCId));

  // Connection Response payload
  auto ok_conn_rsp = CreateStaticByteBuffer(
      // Destination CID
      LowerBits(kRemoteCId), UpperBits(kRemoteCId),

      // Source CID
      LowerBits(kLocalCId), UpperBits(kLocalCId),

      // Result (Successful)
      0x00, 0x00,

      // Status (No further information available)
      0x00, 0x00);
  EXPECT_OUTBOUND_REQ(*fake_sig(), kConnectionRequest, expected_conn_req.view(),
                      {SignalingChannel::Status::kSuccess, ok_conn_rsp.view()});

  bool cb_called = false;
  auto on_conn_rsp = [&cb_called](const BrEdrCommandHandler::ConnectionResponse& rsp) {
    cb_called = true;
    EXPECT_EQ(BrEdrCommandHandler::Status::kSuccess, rsp.status());
    EXPECT_EQ(kRemoteCId, rsp.remote_cid());
    EXPECT_EQ(kLocalCId, rsp.local_cid());
    EXPECT_EQ(ConnectionResult::kSuccess, rsp.result());
    EXPECT_EQ(ConnectionStatus::kNoInfoAvailable, rsp.conn_status());
    return SignalingChannel::ResponseHandlerAction::kCompleteOutboundTransaction;
  };

  EXPECT_TRUE(cmd_handler()->SendConnectionRequest(kPsm, kLocalCId, std::move(on_conn_rsp)));
  RunLoopUntilIdle();
  EXPECT_TRUE(cb_called);
}

TEST_F(L2CAP_BrEdrCommandHandlerTest, OutboundConnReqRspPendingAuthThenOk) {
  // Connection Request payload
  auto expected_conn_req = CreateStaticByteBuffer(
      // PSM
      LowerBits(kPsm), UpperBits(kPsm),

      // Source CID
      LowerBits(kLocalCId), UpperBits(kLocalCId));

  // Connection Response payload
  auto pend_conn_rsp = CreateStaticByteBuffer(
      // Destination CID
      LowerBits(kRemoteCId), UpperBits(kRemoteCId),

      // Source CID
      LowerBits(kLocalCId), UpperBits(kLocalCId),

      // Result (Pending)
      0x01, 0x00,

      // Status (Authorization pending)
      0x02, 0x00);

  auto ok_conn_rsp = CreateStaticByteBuffer(
      // Destination CID
      LowerBits(kRemoteCId), UpperBits(kRemoteCId),

      // Source CID
      LowerBits(kLocalCId), UpperBits(kLocalCId),

      // Result (Successful)
      0x00, 0x00,

      // Status (No further information available)
      0x00, 0x00);
  EXPECT_OUTBOUND_REQ(*fake_sig(), kConnectionRequest, expected_conn_req.view(),
                      {SignalingChannel::Status::kSuccess, pend_conn_rsp.view()},
                      {SignalingChannel::Status::kSuccess, ok_conn_rsp.view()});

  int cb_count = 0;
  auto on_conn_rsp = [&cb_count](const BrEdrCommandHandler::ConnectionResponse& rsp) {
    cb_count++;
    EXPECT_EQ(kRemoteCId, rsp.remote_cid());
    EXPECT_EQ(kLocalCId, rsp.local_cid());
    if (cb_count == 1) {
      EXPECT_EQ(BrEdrCommandHandler::Status::kSuccess, rsp.status());
      EXPECT_EQ(ConnectionResult::kPending, rsp.result());
      EXPECT_EQ(ConnectionStatus::kAuthorizationPending, rsp.conn_status());
      return SignalingChannel::ResponseHandlerAction::kExpectAdditionalResponse;
    } else if (cb_count == 2) {
      EXPECT_EQ(BrEdrCommandHandler::Status::kSuccess, rsp.status());
      EXPECT_EQ(ConnectionResult::kSuccess, rsp.result());
      EXPECT_EQ(ConnectionStatus::kNoInfoAvailable, rsp.conn_status());
    }
    return SignalingChannel::ResponseHandlerAction::kCompleteOutboundTransaction;
  };

  EXPECT_TRUE(cmd_handler()->SendConnectionRequest(kPsm, kLocalCId, std::move(on_conn_rsp)));
  RunLoopUntilIdle();
  EXPECT_EQ(2, cb_count);
}

TEST_F(L2CAP_BrEdrCommandHandlerTest, OutboundConnReqRspTimeOut) {
  // Connection Request payload
  auto expected_conn_req = CreateStaticByteBuffer(
      // PSM
      LowerBits(kPsm), UpperBits(kPsm),

      // Source CID
      LowerBits(kLocalCId), UpperBits(kLocalCId));

  EXPECT_OUTBOUND_REQ(*fake_sig(), kConnectionRequest, expected_conn_req.view(),
                      {SignalingChannel::Status::kTimeOut, {}});

  ASSERT_EQ(0u, failed_requests());

  auto on_conn_rsp = [](auto&) {
    ADD_FAILURE();
    return SignalingChannel::ResponseHandlerAction::kCompleteOutboundTransaction;
  };
  EXPECT_TRUE(cmd_handler()->SendConnectionRequest(kPsm, kLocalCId, std::move(on_conn_rsp)));
  RETURN_IF_FATAL(RunLoopUntilIdle());
  EXPECT_EQ(1u, failed_requests());
}

TEST_F(L2CAP_BrEdrCommandHandlerTest, InboundInfoReqRspNotSupported) {
  BrEdrCommandHandler::InformationRequestCallback cb = [](InformationType type, auto responder) {
    EXPECT_EQ(InformationType::kConnectionlessMTU, type);
    responder->SendNotSupported();
  };
  cmd_handler()->ServeInformationRequest(std::move(cb));

  // Information Request payload
  auto info_req = CreateStaticByteBuffer(
      // Type = Connectionless MTU
      0x01, 0x00);

  // Information Response payload
  auto expected_rsp = CreateStaticByteBuffer(
      // Type = Connectionless MTU
      0x01, 0x00,

      // Result = Not supported
      0x01, 0x00);

  RETURN_IF_FATAL(fake_sig()->ReceiveExpect(kInformationRequest, info_req, expected_rsp));
}

TEST_F(L2CAP_BrEdrCommandHandlerTest, InboundInfoReqRspConnlessMtu) {
  BrEdrCommandHandler::InformationRequestCallback cb = [](InformationType type, auto responder) {
    EXPECT_EQ(InformationType::kConnectionlessMTU, type);
    responder->SendConnectionlessMtu(0x02dc);
  };
  cmd_handler()->ServeInformationRequest(std::move(cb));

  // Information Request payload
  auto info_req = CreateStaticByteBuffer(
      // Type = Connectionless MTU
      0x01, 0x00);

  // Information Response payload
  auto expected_rsp = CreateStaticByteBuffer(
      // Type = Connectionless MTU
      0x01, 0x00,

      // Result = Success
      0x00, 0x00,

      // Data (MTU)
      0xdc, 0x02);

  RETURN_IF_FATAL(fake_sig()->ReceiveExpect(kInformationRequest, info_req, expected_rsp));
}

TEST_F(L2CAP_BrEdrCommandHandlerTest, InboundInfoReqRspExtendedFeatures) {
  BrEdrCommandHandler::InformationRequestCallback cb = [](InformationType type, auto responder) {
    EXPECT_EQ(InformationType::kExtendedFeaturesSupported, type);
    responder->SendExtendedFeaturesSupported(0xfaceb00c);
  };
  cmd_handler()->ServeInformationRequest(std::move(cb));

  // Information Request payload
  auto info_req = CreateStaticByteBuffer(
      // Type = Features Mask
      0x02, 0x00);

  // Information Response payload
  auto expected_rsp = CreateStaticByteBuffer(
      // Type = Features Mask
      0x02, 0x00,

      // Result = Success
      0x00, 0x00,

      // Data (Mask)
      0x0c, 0xb0, 0xce, 0xfa);

  RETURN_IF_FATAL(fake_sig()->ReceiveExpect(kInformationRequest, info_req, expected_rsp));
}

TEST_F(L2CAP_BrEdrCommandHandlerTest, InboundInfoReqRspFixedChannels) {
  BrEdrCommandHandler::InformationRequestCallback cb = [](InformationType type, auto responder) {
    EXPECT_EQ(InformationType::kFixedChannelsSupported, type);
    responder->SendFixedChannelsSupported(0xcafef00d4badc0deUL);
  };
  cmd_handler()->ServeInformationRequest(std::move(cb));

  // Information Request payload
  auto info_req = CreateStaticByteBuffer(
      // Type = Fixed Channels
      0x03, 0x00);

  // Configuration Response payload
  auto expected_rsp = CreateStaticByteBuffer(
      // Type = Fixed Channels
      0x03, 0x00,

      // Result = Success
      0x00, 0x00,

      // Data (Mask)
      0xde, 0xc0, 0xad, 0x4b, 0x0d, 0xf0, 0xfe, 0xca);

  RETURN_IF_FATAL(fake_sig()->ReceiveExpect(kInformationRequest, info_req, expected_rsp));
}

TEST_F(L2CAP_BrEdrCommandHandlerTest, InboundConfigReqEmptyRspOkEmpty) {
  BrEdrCommandHandler::ConfigurationRequestCallback cb =
      [](ChannelId local_cid, uint16_t flags, ChannelConfiguration config, auto responder) {
        EXPECT_EQ(kLocalCId, local_cid);
        EXPECT_EQ(0x6006, flags);
        EXPECT_FALSE(config.mtu_option().has_value());
        EXPECT_FALSE(config.retransmission_flow_control_option().has_value());
        EXPECT_EQ(0u, config.unknown_options().size());

        responder->Send(kRemoteCId, 0x0001, ConfigurationResult::kPending,
                        ChannelConfiguration::ConfigurationOptions());
      };
  cmd_handler()->ServeConfigurationRequest(std::move(cb));

  // Configuration Request payload
  auto config_req = CreateStaticByteBuffer(
      // Destination Channel ID
      LowerBits(kLocalCId), UpperBits(kLocalCId),

      // Flags
      0x06, 0x60);

  // Configuration Response payload
  auto expected_rsp = CreateStaticByteBuffer(
      // Destination Channel ID
      LowerBits(kRemoteCId), UpperBits(kRemoteCId),

      // Flags
      0x01, 0x00,

      // Result = Pending
      0x04, 0x00);

  RETURN_IF_FATAL(fake_sig()->ReceiveExpect(kConfigurationRequest, config_req, expected_rsp));
}

TEST_F(L2CAP_BrEdrCommandHandlerTest, OutboundConfigReqRspPendingEmpty) {
  // Configuration Request payload
  auto expected_config_req = CreateStaticByteBuffer(
      // Destination CID
      LowerBits(kRemoteCId), UpperBits(kRemoteCId),

      // Flags (non-zero to test encoding)
      0x01, 0x00,

      // Data (Config Options)
      0x01,       // Type = MTU
      0x02,       // Length = 2
      0x30, 0x00  // MTU = 48
  );

  // Configuration Response payload
  auto pending_config_req = CreateStaticByteBuffer(
      // Source CID
      LowerBits(kLocalCId), UpperBits(kLocalCId),

      // Flags (non-zero to test encoding)
      0x04, 0x00,

      // Result = Pending
      0x04, 0x00,

      // Data (Config Options)
      0x01,       // Type = MTU
      0x02,       // Length = 2
      0x60, 0x00  // MTU = 96
  );

  EXPECT_OUTBOUND_REQ(*fake_sig(), kConfigurationRequest, expected_config_req.view(),
                      {SignalingChannel::Status::kSuccess, pending_config_req.view()});

  bool cb_called = false;
  BrEdrCommandHandler::ConfigurationResponseCallback on_config_rsp =
      [&cb_called](const BrEdrCommandHandler::ConfigurationResponse& rsp) {
        cb_called = true;
        EXPECT_EQ(SignalingChannel::Status::kSuccess, rsp.status());
        EXPECT_EQ(kLocalCId, rsp.local_cid());
        EXPECT_EQ(0x0004, rsp.flags());
        EXPECT_EQ(ConfigurationResult::kPending, rsp.result());
        EXPECT_TRUE(rsp.config().mtu_option().has_value());
        EXPECT_EQ(96u, rsp.config().mtu_option()->mtu());
        return SignalingChannel::ResponseHandlerAction::kCompleteOutboundTransaction;
      };

  ChannelConfiguration config;
  config.set_mtu_option(ChannelConfiguration::MtuOption(48));

  EXPECT_TRUE(cmd_handler()->SendConfigurationRequest(kRemoteCId, 0x0001, config.Options(),
                                                      std::move(on_config_rsp)));
  RunLoopUntilIdle();
  EXPECT_TRUE(cb_called);
}

TEST_F(L2CAP_BrEdrCommandHandlerTest, OutboundConfigReqRspTimeOut) {
  // Configuration Request payload
  auto expected_config_req = CreateStaticByteBuffer(
      // Destination CID
      LowerBits(kRemoteCId), UpperBits(kRemoteCId),

      // Flags (non-zero to test encoding)
      0x01, 0xf0,

      // Data (Config Options)
      0x01,       // Type = MTU
      0x02,       // Length = 2
      0x30, 0x00  // MTU = 48
  );

  // Disconnect Request payload
  auto expected_discon_req = CreateStaticByteBuffer(
      // Destination CID
      LowerBits(kRemoteCId), UpperBits(kRemoteCId),

      // Source CID
      LowerBits(kLocalCId), UpperBits(kLocalCId));

  EXPECT_OUTBOUND_REQ(*fake_sig(), kConfigurationRequest, expected_config_req.view(),
                      {SignalingChannel::Status::kTimeOut, {}});
  EXPECT_OUTBOUND_REQ(*fake_sig(), kDisconnectionRequest, expected_discon_req.view());

  set_request_fail_callback([this]() {
    // Should still be allowed to send requests even after one failed
    auto on_discon_rsp = [](auto&) {};
    EXPECT_TRUE(
        cmd_handler()->SendDisconnectionRequest(kRemoteCId, kLocalCId, std::move(on_discon_rsp)));
  });

  ASSERT_EQ(0u, failed_requests());

  auto on_config_rsp = [](auto&) {
    ADD_FAILURE();
    return SignalingChannel::ResponseHandlerAction::kCompleteOutboundTransaction;
  };

  ChannelConfiguration config;
  config.set_mtu_option(ChannelConfiguration::MtuOption(48));

  EXPECT_TRUE(cmd_handler()->SendConfigurationRequest(kRemoteCId, 0xf001, config.Options(),
                                                      std::move(on_config_rsp)));
  RETURN_IF_FATAL(RunLoopUntilIdle());
  EXPECT_EQ(1u, failed_requests());
}
TEST_F(L2CAP_BrEdrCommandHandlerTest, OutboundInfoReqRspOk) {
  // Information Request payload
  auto expected_info_req = CreateStaticByteBuffer(
      // Information Type
      LowerBits(static_cast<uint16_t>(InformationType::kExtendedFeaturesSupported)),
      UpperBits(static_cast<uint16_t>(InformationType::kExtendedFeaturesSupported)));

  // Information Response payload
  auto ok_info_rsp = CreateStaticByteBuffer(
      // Information Type
      LowerBits(static_cast<uint16_t>(InformationType::kExtendedFeaturesSupported)),
      UpperBits(static_cast<uint16_t>(InformationType::kExtendedFeaturesSupported)),

      // Information Result
      LowerBits(static_cast<uint16_t>(InformationResult::kSuccess)),
      UpperBits(static_cast<uint16_t>(InformationResult::kSuccess)),

      // Data (extended features mask, 4 bytes)
      LowerBits(kExtendedFeaturesBitFixedChannels), 0, 0, 0);

  EXPECT_OUTBOUND_REQ(*fake_sig(), kInformationRequest, expected_info_req.view(),
                      {SignalingChannel::Status::kSuccess, ok_info_rsp.view()});

  bool cb_called = false;
  BrEdrCommandHandler::InformationResponseCallback on_info_cb =
      [&cb_called](const BrEdrCommandHandler::InformationResponse& rsp) {
        cb_called = true;
        EXPECT_EQ(SignalingChannel::Status::kSuccess, rsp.status());
        EXPECT_EQ(InformationResult::kSuccess, rsp.result());
        EXPECT_EQ(InformationType::kExtendedFeaturesSupported, rsp.type());
        EXPECT_EQ(kExtendedFeaturesBitFixedChannels, rsp.extended_features());
      };

  EXPECT_TRUE(cmd_handler()->SendInformationRequest(InformationType::kExtendedFeaturesSupported,
                                                    std::move(on_info_cb)));
  RunLoopUntilIdle();
  EXPECT_TRUE(cb_called);
}

TEST_F(L2CAP_BrEdrCommandHandlerTest, OutboundInfoReqRspNotSupported) {
  // Information Request payload
  auto expected_info_req = CreateStaticByteBuffer(
      // Information Type
      LowerBits(static_cast<uint16_t>(InformationType::kConnectionlessMTU)),
      UpperBits(static_cast<uint16_t>(InformationType::kConnectionlessMTU)));

  // Information Response payload
  auto error_info_rsp = CreateStaticByteBuffer(
      // Information Type
      LowerBits(static_cast<uint16_t>(InformationType::kConnectionlessMTU)),
      UpperBits(static_cast<uint16_t>(InformationType::kConnectionlessMTU)),

      // Information Result
      LowerBits(static_cast<uint16_t>(InformationResult::kNotSupported)),
      UpperBits(static_cast<uint16_t>(InformationResult::kNotSupported)));

  EXPECT_OUTBOUND_REQ(*fake_sig(), kInformationRequest, expected_info_req.view(),
                      {SignalingChannel::Status::kSuccess, error_info_rsp.view()});

  bool cb_called = false;
  BrEdrCommandHandler::InformationResponseCallback on_info_cb =
      [&cb_called](const BrEdrCommandHandler::InformationResponse& rsp) {
        cb_called = true;
        EXPECT_EQ(SignalingChannel::Status::kSuccess, rsp.status());
        EXPECT_EQ(InformationResult::kNotSupported, rsp.result());
        EXPECT_EQ(InformationType::kConnectionlessMTU, rsp.type());
      };

  EXPECT_TRUE(cmd_handler()->SendInformationRequest(InformationType::kConnectionlessMTU,
                                                    std::move(on_info_cb)));
  RunLoopUntilIdle();
  EXPECT_TRUE(cb_called);
}

TEST_F(L2CAP_BrEdrCommandHandlerTest, OutboundInfoReqRspHeaderNotEnoughBytes) {
  // Information Request payload
  auto expected_info_req = CreateStaticByteBuffer(
      // Information Type
      LowerBits(static_cast<uint16_t>(InformationType::kExtendedFeaturesSupported)),
      UpperBits(static_cast<uint16_t>(InformationType::kExtendedFeaturesSupported)));

  // Information Response payload
  auto malformed_info_rsp = CreateStaticByteBuffer(
      // 1 of 4 bytes expected of an Information Response just to be able to parse it.
      LowerBits(static_cast<uint16_t>(InformationType::kExtendedFeaturesSupported)));

  EXPECT_OUTBOUND_REQ(*fake_sig(), kInformationRequest, expected_info_req.view(),
                      {SignalingChannel::Status::kSuccess, malformed_info_rsp.view()});

  bool cb_called = false;
  BrEdrCommandHandler::InformationResponseCallback on_info_cb =
      [&cb_called](const BrEdrCommandHandler::InformationResponse& rsp) { cb_called = true; };

  EXPECT_TRUE(cmd_handler()->SendInformationRequest(InformationType::kExtendedFeaturesSupported,
                                                    std::move(on_info_cb)));
  RunLoopUntilIdle();
  EXPECT_FALSE(cb_called);
}

TEST_F(L2CAP_BrEdrCommandHandlerTest, OutboundInfoReqRspPayloadNotEnoughBytes) {
  // Information Request payload
  auto expected_info_req = CreateStaticByteBuffer(
      // Information Type
      LowerBits(static_cast<uint16_t>(InformationType::kExtendedFeaturesSupported)),
      UpperBits(static_cast<uint16_t>(InformationType::kExtendedFeaturesSupported)));

  // Information Response payload
  auto malformed_info_rsp = CreateStaticByteBuffer(
      // Information Type
      LowerBits(static_cast<uint16_t>(InformationType::kExtendedFeaturesSupported)),
      UpperBits(static_cast<uint16_t>(InformationType::kExtendedFeaturesSupported)),

      // Information Result
      LowerBits(static_cast<uint16_t>(InformationResult::kSuccess)),
      UpperBits(static_cast<uint16_t>(InformationResult::kSuccess)),

      // Data (2 of 4 bytes expected of an extended features mask)
      0, 0);

  EXPECT_OUTBOUND_REQ(*fake_sig(), kInformationRequest, expected_info_req.view(),
                      {SignalingChannel::Status::kSuccess, malformed_info_rsp.view()});

  bool cb_called = false;
  BrEdrCommandHandler::InformationResponseCallback on_info_cb =
      [&cb_called](const BrEdrCommandHandler::InformationResponse& rsp) { cb_called = true; };

  EXPECT_TRUE(cmd_handler()->SendInformationRequest(InformationType::kExtendedFeaturesSupported,
                                                    std::move(on_info_cb)));
  RunLoopUntilIdle();
  EXPECT_FALSE(cb_called);
}

// Accept and pass a valid Information Response even if it doesn't have the type
// requested.
TEST_F(L2CAP_BrEdrCommandHandlerTest, OutboundInfoReqRspWrongType) {
  // Information Request payload
  auto expected_info_req = CreateStaticByteBuffer(
      // Information Type
      LowerBits(static_cast<uint16_t>(InformationType::kExtendedFeaturesSupported)),
      UpperBits(static_cast<uint16_t>(InformationType::kExtendedFeaturesSupported)));

  // Information Response payload
  auto mismatch_info_rsp = CreateStaticByteBuffer(
      // Information Type
      LowerBits(static_cast<uint16_t>(InformationType::kConnectionlessMTU)),
      UpperBits(static_cast<uint16_t>(InformationType::kConnectionlessMTU)),

      // Information Result
      LowerBits(static_cast<uint16_t>(InformationResult::kSuccess)),
      UpperBits(static_cast<uint16_t>(InformationResult::kSuccess)),

      // Data (connectionless broadcast MTU, 2 bytes)
      0x40, 0);

  EXPECT_OUTBOUND_REQ(*fake_sig(), kInformationRequest, expected_info_req.view(),
                      {SignalingChannel::Status::kSuccess, mismatch_info_rsp.view()});

  bool cb_called = false;
  BrEdrCommandHandler::InformationResponseCallback on_info_cb =
      [&cb_called](const BrEdrCommandHandler::InformationResponse& rsp) {
        cb_called = true;
        EXPECT_EQ(SignalingChannel::Status::kSuccess, rsp.status());
        EXPECT_EQ(InformationResult::kSuccess, rsp.result());
        EXPECT_EQ(InformationType::kConnectionlessMTU, rsp.type());
        EXPECT_EQ(0x40, rsp.connectionless_mtu());
      };

  EXPECT_TRUE(cmd_handler()->SendInformationRequest(InformationType::kExtendedFeaturesSupported,
                                                    std::move(on_info_cb)));
  RunLoopUntilIdle();
  EXPECT_TRUE(cb_called);
}

// Allow types of information besides those known to BrEdrCommandHandler.
TEST_F(L2CAP_BrEdrCommandHandlerTest, OutboundInfoReqUnknownType) {
  // Information Request payload
  auto expected_info_req = CreateStaticByteBuffer(
      // Information Type
      0x04, 0);

  // Information Response payload
  auto ok_info_rsp = CreateStaticByteBuffer(
      // Information Type
      0x04, 0,

      // Information Result
      LowerBits(static_cast<uint16_t>(InformationResult::kSuccess)),
      UpperBits(static_cast<uint16_t>(InformationResult::kSuccess)),

      // Data (some payload)
      't', 'e', 's', 't');

  EXPECT_OUTBOUND_REQ(*fake_sig(), kInformationRequest, expected_info_req.view(),
                      {SignalingChannel::Status::kSuccess, ok_info_rsp.view()});

  bool cb_called = false;
  BrEdrCommandHandler::InformationResponseCallback on_info_cb =
      [&cb_called](const BrEdrCommandHandler::InformationResponse& rsp) {
        cb_called = true;
        EXPECT_EQ(SignalingChannel::Status::kSuccess, rsp.status());
        EXPECT_EQ(InformationResult::kSuccess, rsp.result());
        EXPECT_EQ(static_cast<InformationType>(0x04), rsp.type());
      };

  EXPECT_TRUE(cmd_handler()->SendInformationRequest(static_cast<InformationType>(0x04),
                                                    std::move(on_info_cb)));
  RunLoopUntilIdle();
  EXPECT_TRUE(cb_called);
}

TEST_F(L2CAP_BrEdrCommandHandlerTest, InboundConnReqRspPending) {
  BrEdrCommandHandler::ConnectionRequestCallback cb = [](PSM psm, ChannelId remote_cid,
                                                         auto responder) {
    EXPECT_EQ(kPsm, psm);
    EXPECT_EQ(kRemoteCId, remote_cid);
    responder->Send(kLocalCId, ConnectionResult::kPending, ConnectionStatus::kAuthorizationPending);
  };
  cmd_handler()->ServeConnectionRequest(std::move(cb));

  // Connection Request payload
  auto conn_req = CreateStaticByteBuffer(
      // PSM
      LowerBits(kPsm), UpperBits(kPsm),

      // Source CID (relative to requester)
      LowerBits(kRemoteCId), UpperBits(kRemoteCId));

  // Connection Response payload
  auto conn_rsp = CreateStaticByteBuffer(
      // Destination CID (relative to requester)
      LowerBits(kLocalCId), UpperBits(kLocalCId),

      // Source CID (relative to requester)
      LowerBits(kRemoteCId), UpperBits(kRemoteCId),

      // Connection Result
      LowerBits(static_cast<uint16_t>(ConnectionResult::kPending)),
      UpperBits(static_cast<uint16_t>(ConnectionResult::kPending)),

      // Connection Status
      LowerBits(static_cast<uint16_t>(ConnectionStatus::kAuthorizationPending)),
      UpperBits(static_cast<uint16_t>(ConnectionStatus::kAuthorizationPending)));

  RETURN_IF_FATAL(fake_sig()->ReceiveExpect(kConnectionRequest, conn_req, conn_rsp));
}

TEST_F(L2CAP_BrEdrCommandHandlerTest, InboundConnReqBadPsm) {
  constexpr uint16_t kBadPsm = 0x0002;

  // Request callback shouldn't even be called for an invalid PSM.
  bool req_cb_called = false;
  BrEdrCommandHandler::ConnectionRequestCallback cb =
      [&req_cb_called](PSM psm, ChannelId remote_cid, auto responder) { req_cb_called = true; };
  cmd_handler()->ServeConnectionRequest(std::move(cb));

  // Connection Request payload
  auto conn_req = CreateStaticByteBuffer(
      // PSM
      LowerBits(kBadPsm), UpperBits(kBadPsm),

      // Source CID (relative to requester)
      LowerBits(kRemoteCId), UpperBits(kRemoteCId));

  // Connection Response payload
  auto conn_rsp = CreateStaticByteBuffer(
      // Destination CID (relative to requester)
      LowerBits(kInvalidChannelId), UpperBits(kInvalidChannelId),

      // Source CID (relative to requester)
      LowerBits(kRemoteCId), UpperBits(kRemoteCId),

      // Connection Result
      LowerBits(static_cast<uint16_t>(ConnectionResult::kPSMNotSupported)),
      UpperBits(static_cast<uint16_t>(ConnectionResult::kPSMNotSupported)),

      // Connection Status
      LowerBits(static_cast<uint16_t>(ConnectionStatus::kNoInfoAvailable)),
      UpperBits(static_cast<uint16_t>(ConnectionStatus::kNoInfoAvailable)));

  RETURN_IF_FATAL(fake_sig()->ReceiveExpect(kConnectionRequest, conn_req, conn_rsp));
  EXPECT_FALSE(req_cb_called);
}

TEST_F(L2CAP_BrEdrCommandHandlerTest, InboundConnReqNonDynamicSrcCId) {
  // Request callback shouldn't even be called for an invalid Source Channel ID.
  bool req_cb_called = false;
  BrEdrCommandHandler::ConnectionRequestCallback cb =
      [&req_cb_called](PSM psm, ChannelId remote_cid, auto responder) { req_cb_called = true; };
  cmd_handler()->ServeConnectionRequest(std::move(cb));

  // Connection Request payload
  auto conn_req = CreateStaticByteBuffer(
      // PSM
      LowerBits(kPsm), UpperBits(kPsm),

      // Source CID: fixed channel for Security Manager (relative to requester)
      LowerBits(kSMPChannelId), UpperBits(kSMPChannelId));

  // Connection Response payload
  auto conn_rsp = CreateStaticByteBuffer(
      // Destination CID (relative to requester)
      LowerBits(kInvalidChannelId), UpperBits(kInvalidChannelId),

      // Source CID (relative to requester)
      LowerBits(kSMPChannelId), UpperBits(kSMPChannelId),

      // Connection Result
      LowerBits(static_cast<uint16_t>(ConnectionResult::kInvalidSourceCID)),
      UpperBits(static_cast<uint16_t>(ConnectionResult::kInvalidSourceCID)),

      // Connection Status
      LowerBits(static_cast<uint16_t>(ConnectionStatus::kNoInfoAvailable)),
      UpperBits(static_cast<uint16_t>(ConnectionStatus::kNoInfoAvailable)));

  RETURN_IF_FATAL(fake_sig()->ReceiveExpect(kConnectionRequest, conn_req, conn_rsp));
  EXPECT_FALSE(req_cb_called);
}

}  // namespace
}  // namespace internal
}  // namespace l2cap
}  // namespace bt
