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

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

#include "fbl/ref_ptr.h"
#include "lib/fit/single_threaded_executor.h"
#include "lib/gtest/test_loop_fixture.h"
#include "src/connectivity/bluetooth/core/bt-host/att/att.h"
#include "src/connectivity/bluetooth/core/bt-host/hci-spec/protocol.h"
#include "src/connectivity/bluetooth/core/bt-host/hci/connection.h"
#include "src/connectivity/bluetooth/core/bt-host/hci/mock_acl_data_channel.h"
#include "src/connectivity/bluetooth/core/bt-host/l2cap/l2cap_defs.h"
#include "src/connectivity/bluetooth/core/bt-host/sm/smp.h"

namespace bt::l2cap::internal {
namespace {
using Conn = hci::Connection;
class L2CAP_LogicalLinkTest : public ::gtest::TestLoopFixture {
 public:
  L2CAP_LogicalLinkTest() = default;
  ~L2CAP_LogicalLinkTest() override = default;
  DISALLOW_COPY_AND_ASSIGN_ALLOW_MOVE(L2CAP_LogicalLinkTest);

 protected:
  void SetUp() override { NewLogicalLink(); }
  void TearDown() override {
    if (link_) {
      link_->Close();
      link_ = nullptr;
    }
  }
  void NewLogicalLink(Conn::LinkType type = Conn::LinkType::kLE) {
    const hci::ConnectionHandle kConnHandle = 0x0001;
    const size_t kMaxPayload = kDefaultMTU;
    auto query_service_cb = [](hci::ConnectionHandle, PSM) { return std::nullopt; };
    link_ = LogicalLink::New(kConnHandle, type, Conn::Role::kMaster, &executor_, kMaxPayload,
                             std::move(query_service_cb), &acl_data_channel_,
                             /*random_channel_ids=*/true);
  }
  LogicalLink* link() const { return link_.get(); }
  void DeleteLink() { link_ = nullptr; }

  hci::testing::MockAclDataChannel* acl_data_channel() { return &acl_data_channel_; }

 private:
  fbl::RefPtr<LogicalLink> link_;
  fit::single_threaded_executor executor_;
  hci::testing::MockAclDataChannel acl_data_channel_;
};

using L2CAP_LogicalLinkDeathTest = L2CAP_LogicalLinkTest;

TEST_F(L2CAP_LogicalLinkDeathTest, DestructedWithoutClosingDies) {
  // Deleting the link without calling `Close` on it should trigger an assertion.
  ASSERT_DEATH_IF_SUPPORTED(DeleteLink(), ".*closed.*");
}

TEST_F(L2CAP_LogicalLinkTest, FixedChannelHasCorrectMtu) {
  fbl::RefPtr<Channel> fixed_chan = link()->OpenFixedChannel(kATTChannelId);
  ASSERT_TRUE(fixed_chan);
  EXPECT_EQ(kMaxMTU, fixed_chan->max_rx_sdu_size());
  EXPECT_EQ(kMaxMTU, fixed_chan->max_tx_sdu_size());
}

TEST_F(L2CAP_LogicalLinkTest, DropsBroadcastPackets) {
  link()->Close();
  NewLogicalLink(Conn::LinkType::kACL);
  fbl::RefPtr<Channel> connectionless_chan = link()->OpenFixedChannel(kConnectionlessChannelId);
  ASSERT_TRUE(connectionless_chan);

  size_t rx_count = 0;
  bool activated = connectionless_chan->Activate([&](ByteBufferPtr) { rx_count++; }, []() {});
  ASSERT_TRUE(activated);

  auto group_frame = CreateStaticByteBuffer(0x0A, 0x00,  // Length (PSM + info = 10)
                                            0x02, 0x00,  // Connectionless data channel
                                            0xF0, 0x0F,  // PSM
                                            'S', 'a', 'p', 'p', 'h', 'i', 'r', 'e'  // Info Payload
  );
  auto packet =
      hci::ACLDataPacket::New(0x0001, hci::ACLPacketBoundaryFlag::kCompletePDU,
                              hci::ACLBroadcastFlag::kActiveSlaveBroadcast, group_frame.size());
  ASSERT_TRUE(packet);
  packet->mutable_view()->mutable_payload_data().Write(group_frame);

  link()->HandleRxPacket(std::move(packet));

  // Should be dropped.
  EXPECT_EQ(0u, rx_count);
}

#define EXPECT_HIGH_PRIORITY(channel_id) \
  EXPECT_EQ(LogicalLink::ChannelPriority((channel_id)), hci::AclDataChannel::PacketPriority::kHigh)
#define EXPECT_LOW_PRIORITY(channel_id) \
  EXPECT_EQ(LogicalLink::ChannelPriority((channel_id)), hci::AclDataChannel::PacketPriority::kLow)

TEST_F(L2CAP_LogicalLinkTest, ChannelPriority) {
  EXPECT_HIGH_PRIORITY(kSignalingChannelId);
  EXPECT_HIGH_PRIORITY(kLESignalingChannelId);
  EXPECT_HIGH_PRIORITY(kSMPChannelId);
  EXPECT_HIGH_PRIORITY(kLESMPChannelId);

  EXPECT_LOW_PRIORITY(kFirstDynamicChannelId);
  EXPECT_LOW_PRIORITY(kLastACLDynamicChannelId);
  EXPECT_LOW_PRIORITY(kATTChannelId);
}

TEST_F(L2CAP_LogicalLinkTest, SetBrEdrAutomaticFlushTimeoutSucceeds) {
  link()->Close();
  NewLogicalLink(Conn::LinkType::kACL);
  constexpr zx::duration kTimeout(zx::msec(100));
  acl_data_channel()->set_set_bredr_automatic_flush_timeout_cb(
      [&](auto timeout, auto handle, auto cb) {
        EXPECT_EQ(timeout, kTimeout);
        EXPECT_EQ(handle, link()->handle());
        cb(fit::ok());
      });

  bool cb_called = false;
  link()->SetBrEdrAutomaticFlushTimeout(kTimeout, [&](auto result) {
    cb_called = true;
    EXPECT_TRUE(result.is_ok());
  });
  EXPECT_TRUE(cb_called);
}

TEST_F(L2CAP_LogicalLinkTest, SetBrEdrAutomaticFlushTimeoutFailsForLELink) {
  constexpr zx::duration kTimeout(zx::msec(100));
  // LE links are unsupported, so result should be an error.
  link()->Close();
  NewLogicalLink(Conn::LinkType::kLE);

  // No command should be sent.
  acl_data_channel()->set_set_bredr_automatic_flush_timeout_cb(
      [&](auto timeout, auto handle, auto cb) { FAIL(); });

  bool cb_called = false;
  link()->SetBrEdrAutomaticFlushTimeout(kTimeout, [&](auto result) {
    cb_called = true;
    EXPECT_TRUE(result.is_error());
    EXPECT_EQ(result.error(), hci::StatusCode::kInvalidHCICommandParameters);
  });
  EXPECT_TRUE(cb_called);
}

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