// Copyright 2017 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 "transport.h"

#include "lib/inspect/cpp/inspector.h"
#include "src/connectivity/bluetooth/core/bt-host/common/byte_buffer.h"
#include "src/connectivity/bluetooth/core/bt-host/common/test_helpers.h"
#include "src/connectivity/bluetooth/core/bt-host/hci-spec/protocol.h"
#include "src/connectivity/bluetooth/core/bt-host/testing/controller_test.h"
#include "src/connectivity/bluetooth/core/bt-host/testing/mock_controller.h"

namespace bt::hci {

namespace {

using TransportTest = bt::testing::ControllerTest<bt::testing::MockController>;
using TransportDeathTest = TransportTest;

class TransportTestWithoutSco : public TransportTest {
 public:
  void SetUp() override { TransportTest::SetUp(/*sco_enabled=*/false); }
};

TEST_F(TransportTest, CommandChannelTimeoutShutsDownChannelAndNotifiesClosedCallback) {
  size_t closed_cb_count = 0;
  transport()->SetTransportClosedCallback([&] { closed_cb_count++; });

  constexpr zx::duration kCommandTimeout = zx::sec(12);

  StaticByteBuffer req_reset(LowerBits(hci_spec::kReset),
                             UpperBits(hci_spec::kReset),  // HCI_Reset opcode
                             0x00                          // parameter_total_size
  );

  // Expect the HCI_Reset command but dont send a reply back to make the command
  // time out.
  EXPECT_CMD_PACKET_OUT(test_device(), req_reset);
  StartTestDevice();

  size_t cb_count = 0;
  CommandChannel::TransactionId id1, id2;
  auto cb = [&cb_count, &id1, &id2](CommandChannel::TransactionId callback_id,
                                    const EventPacket& event) {
    cb_count++;
    EXPECT_TRUE(callback_id == id1 || callback_id == id2);
    EXPECT_EQ(hci_spec::kCommandStatusEventCode, event.event_code());

    const auto params = event.params<hci_spec::CommandStatusEventParams>();
    EXPECT_EQ(hci_spec::StatusCode::kUnspecifiedError, params.status);
    EXPECT_EQ(hci_spec::kReset, params.command_opcode);
  };

  auto packet = CommandPacket::New(hci_spec::kReset);
  id1 = cmd_channel()->SendCommand(std::move(packet), cb);
  ASSERT_NE(0u, id1);

  packet = CommandPacket::New(hci_spec::kReset);
  id2 = cmd_channel()->SendCommand(std::move(packet), cb);
  ASSERT_NE(0u, id2);

  // Run the loop until the command timeout task gets scheduled.
  RunLoopUntilIdle();
  ASSERT_EQ(0u, cb_count);
  EXPECT_EQ(0u, closed_cb_count);

  RunLoopFor(kCommandTimeout);
  EXPECT_EQ(2u, cb_count);
  EXPECT_EQ(1u, closed_cb_count);
}

TEST_F(TransportDeathTest, AttachInspectBeforeInitializeACLDataChannelCrashes) {
  inspect::Inspector inspector;
  EXPECT_DEATH_IF_SUPPORTED(transport()->AttachInspect(inspector.GetRoot()), ".*");
}

TEST_F(TransportTest, HciErrorClosesTransportWithSco) {
  StartTestDevice();

  size_t closed_cb_count = 0;
  transport()->SetTransportClosedCallback([&] { closed_cb_count++; });

  EXPECT_TRUE(transport()->InitializeScoDataChannel(
      DataBufferInfo(/*max_data_length=*/1, /*max_num_packets=*/1)));
  RunLoopUntilIdle();

  test_device()->Stop(ZX_ERR_PEER_CLOSED);
  RunLoopUntilIdle();
  EXPECT_EQ(closed_cb_count, 1u);
}

TEST_F(TransportTestWithoutSco, GetScoChannelFailure) {
  size_t closed_cb_count = 0;
  transport()->SetTransportClosedCallback([&] { closed_cb_count++; });
  EXPECT_FALSE(transport()->InitializeScoDataChannel(
      DataBufferInfo(/*max_data_length=*/1, /*max_num_packets=*/1)));
  RunLoopUntilIdle();
  EXPECT_EQ(closed_cb_count, 0u);
}

TEST_F(TransportTest, InitializeScoFailsBufferNotAvailable) {
  EXPECT_FALSE(transport()->InitializeScoDataChannel(
      DataBufferInfo(/*max_data_length=*/0, /*max_num_packets=*/0)));
}

}  // namespace
}  // namespace bt::hci
