// Copyright 2023 The Pigweed Authors
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License. You may obtain a copy of
// the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations under
// the License.

#include "pw_bluetooth_sapphire/internal/host/transport/sco_data_channel.h"

#include "pw_bluetooth/controller.h"
#include "pw_bluetooth_sapphire/internal/host/testing/controller_test.h"
#include "pw_bluetooth_sapphire/internal/host/testing/mock_controller.h"
#include "pw_bluetooth_sapphire/internal/host/testing/test_helpers.h"
#include "pw_bluetooth_sapphire/internal/host/testing/test_packets.h"

namespace bt::hci {
namespace {

using ScoCodingFormat = pw::bluetooth::Controller::ScoCodingFormat;
using ScoEncoding = pw::bluetooth::Controller::ScoEncoding;
using ScoSampleRate = pw::bluetooth::Controller::ScoSampleRate;

constexpr hci_spec::ConnectionHandle kConnectionHandle0 = 0x0000;
constexpr hci_spec::ConnectionHandle kConnectionHandle1 = 0x0001;
constexpr size_t kBufferMaxNumPackets = 2;

bt::StaticPacket<pw::bluetooth::emboss::SynchronousConnectionParametersWriter>
MsbcConnectionParams() {
  bt::StaticPacket<pw::bluetooth::emboss::SynchronousConnectionParametersWriter>
      out;
  auto view = out.view();
  view.transmit_bandwidth().Write(0);
  view.receive_bandwidth().Write(0);
  view.transmit_coding_format().coding_format().Write(
      pw::bluetooth::emboss::CodingFormat::MSBC);
  view.transmit_coding_format().company_id().Write(0);
  view.transmit_coding_format().vendor_codec_id().Write(0);
  view.receive_coding_format().coding_format().Write(
      pw::bluetooth::emboss::CodingFormat::MSBC);
  view.receive_coding_format().company_id().Write(0);
  view.receive_coding_format().vendor_codec_id().Write(0);
  view.transmit_codec_frame_size_bytes().Write(0);
  view.receive_codec_frame_size_bytes().Write(0);
  view.input_bandwidth().Write(32000);
  view.output_bandwidth().Write(32000);
  view.input_coding_format().coding_format().Write(
      pw::bluetooth::emboss::CodingFormat::MSBC);
  view.input_coding_format().company_id().Write(0);
  view.input_coding_format().vendor_codec_id().Write(0);
  view.output_coding_format().coding_format().Write(
      pw::bluetooth::emboss::CodingFormat::MSBC);
  view.output_coding_format().company_id().Write(0);
  view.output_coding_format().vendor_codec_id().Write(0);
  view.input_coded_data_size_bits().Write(16);
  view.output_coded_data_size_bits().Write(16);
  view.input_pcm_data_format().Write(
      pw::bluetooth::emboss::PcmDataFormat::UNSIGNED);
  view.output_pcm_data_format().Write(
      pw::bluetooth::emboss::PcmDataFormat::UNSIGNED);
  view.input_pcm_sample_payload_msb_position().Write(0);
  view.output_pcm_sample_payload_msb_position().Write(0);
  view.input_data_path().Write(pw::bluetooth::emboss::ScoDataPath::HCI);
  view.output_data_path().Write(pw::bluetooth::emboss::ScoDataPath::HCI);
  view.input_transport_unit_size_bits().Write(0);
  view.output_transport_unit_size_bits().Write(0);
  view.max_latency_ms().Write(0);
  view.packet_types().BackingStorage().WriteUInt(0);
  view.retransmission_effort().Write(
      pw::bluetooth::emboss::SynchronousConnectionParameters::
          ScoRetransmissionEffort::NONE);
  return out;
}

bt::StaticPacket<pw::bluetooth::emboss::SynchronousConnectionParametersWriter>
cvsd_connection_params() {
  bt::StaticPacket<pw::bluetooth::emboss::SynchronousConnectionParametersWriter>
      out;
  auto view = out.view();
  view.transmit_bandwidth().Write(0);
  view.receive_bandwidth().Write(0);
  view.transmit_coding_format().coding_format().Write(
      pw::bluetooth::emboss::CodingFormat::CVSD);
  view.transmit_coding_format().company_id().Write(0);
  view.transmit_coding_format().vendor_codec_id().Write(0);
  view.receive_coding_format().coding_format().Write(
      pw::bluetooth::emboss::CodingFormat::CVSD);
  view.receive_coding_format().company_id().Write(0);
  view.receive_coding_format().vendor_codec_id().Write(0);
  view.transmit_codec_frame_size_bytes().Write(0);
  view.receive_codec_frame_size_bytes().Write(0);
  view.input_bandwidth().Write(8000);
  view.output_bandwidth().Write(8000);
  view.input_coding_format().coding_format().Write(
      pw::bluetooth::emboss::CodingFormat::CVSD);
  view.input_coding_format().company_id().Write(0);
  view.input_coding_format().vendor_codec_id().Write(0);
  view.output_coding_format().coding_format().Write(
      pw::bluetooth::emboss::CodingFormat::CVSD);
  view.output_coding_format().company_id().Write(0);
  view.output_coding_format().vendor_codec_id().Write(0);
  view.input_coded_data_size_bits().Write(8);
  view.output_coded_data_size_bits().Write(8);
  view.input_pcm_data_format().Write(
      pw::bluetooth::emboss::PcmDataFormat::UNSIGNED);
  view.output_pcm_data_format().Write(
      pw::bluetooth::emboss::PcmDataFormat::UNSIGNED);
  view.input_pcm_sample_payload_msb_position().Write(0);
  view.output_pcm_sample_payload_msb_position().Write(0);
  view.input_data_path().Write(pw::bluetooth::emboss::ScoDataPath::HCI);
  view.output_data_path().Write(pw::bluetooth::emboss::ScoDataPath::HCI);
  view.input_transport_unit_size_bits().Write(0);
  view.output_transport_unit_size_bits().Write(0);
  view.max_latency_ms().Write(0);
  view.packet_types().BackingStorage().WriteUInt(0);
  view.retransmission_effort().Write(
      pw::bluetooth::emboss::SynchronousConnectionParameters::
          ScoRetransmissionEffort::NONE);
  return out;
}
class FakeScoConnection : public ScoDataChannel::ConnectionInterface {
 public:
  explicit FakeScoConnection(
      ScoDataChannel* data_channel,
      hci_spec::ConnectionHandle handle = kConnectionHandle0,
      bt::StaticPacket<
          pw::bluetooth::emboss::SynchronousConnectionParametersWriter> params =
          MsbcConnectionParams())
      : handle_(handle),
        params_(std::move(params)),
        data_channel_(data_channel),
        weak_interface_(this) {}

  ~FakeScoConnection() override = default;

  void QueuePacket(std::unique_ptr<ScoDataPacket> packet) {
    queued_packets_.push(std::move(packet));
    data_channel_->OnOutboundPacketReadable();
  }

  const std::vector<std::unique_ptr<ScoDataPacket>>& received_packets() const {
    return received_packets_;
  }
  const std::queue<std::unique_ptr<ScoDataPacket>>& queued_packets() const {
    return queued_packets_;
  }

  uint16_t hci_error_count() const { return hci_error_count_; }

  WeakPtr<ConnectionInterface> GetWeakPtr() {
    return weak_interface_.GetWeakPtr();
  }

  // ScoDataChannel::ConnectionInterface overrides:

  hci_spec::ConnectionHandle handle() const override { return handle_; }

  bt::StaticPacket<pw::bluetooth::emboss::SynchronousConnectionParametersWriter>
  parameters() override {
    return params_;
  }

  std::unique_ptr<ScoDataPacket> GetNextOutboundPacket() override {
    if (queued_packets_.empty()) {
      return nullptr;
    }
    std::unique_ptr<ScoDataPacket> packet = std::move(queued_packets_.front());
    queued_packets_.pop();
    return packet;
  }

  void ReceiveInboundPacket(std::unique_ptr<ScoDataPacket> packet) override {
    received_packets_.push_back(std::move(packet));
  }

  void OnHciError() override { hci_error_count_++; }

 private:
  hci_spec::ConnectionHandle handle_;
  bt::StaticPacket<pw::bluetooth::emboss::SynchronousConnectionParametersWriter>
      params_;
  std::queue<std::unique_ptr<ScoDataPacket>> queued_packets_;
  std::vector<std::unique_ptr<ScoDataPacket>> received_packets_;
  ScoDataChannel* data_channel_;
  uint16_t hci_error_count_ = 0;
  WeakSelf<ConnectionInterface> weak_interface_;
};

using TestingBase =
    bt::testing::FakeDispatcherControllerTest<bt::testing::MockController>;
class ScoDataChannelTest : public TestingBase {
 public:
  void SetUp() override {
    TestingBase::SetUp();

    DataBufferInfo buffer_info(/*max_data_length=*/10, kBufferMaxNumPackets);
    InitializeScoDataChannel(buffer_info);
  }
};

class ScoDataChannelSingleConnectionTest : public ScoDataChannelTest {
 public:
  void SetUp() override {
    ScoDataChannelTest::SetUp();

    test_device()->set_configure_sco_cb(
        [this](ScoCodingFormat format,
               ScoEncoding encoding,
               ScoSampleRate rate,
               fit::callback<void(pw::Status)> callback) {
          config_count_++;
          EXPECT_EQ(format, ScoCodingFormat::kMsbc);
          EXPECT_EQ(encoding, ScoEncoding::k16Bits);
          EXPECT_EQ(rate, ScoSampleRate::k16Khz);
          callback(PW_STATUS_OK);
        });

    test_device()->set_reset_sco_cb(
        [this](fit::callback<void(pw::Status)> callback) {
          reset_count_++;
          callback(PW_STATUS_OK);
        });

    connection_.emplace(sco_data_channel());

    sco_data_channel()->RegisterConnection(connection_->GetWeakPtr());
    EXPECT_EQ(config_count_, 1);
    EXPECT_EQ(reset_count_, 0);
  }

  void TearDown() override {
    sco_data_channel()->UnregisterConnection(connection_->handle());
    EXPECT_EQ(config_count_, 1);
    EXPECT_EQ(reset_count_, 1);
    test_device()->set_configure_sco_cb(nullptr);
    test_device()->set_reset_sco_cb(nullptr);
    ScoDataChannelTest::TearDown();
  }

  FakeScoConnection* connection() { return &connection_.value(); }

 private:
  std::optional<FakeScoConnection> connection_;
  int config_count_ = 0;
  int reset_count_ = 0;
};

TEST_F(ScoDataChannelSingleConnectionTest, SendManyMsbcPackets) {
  // Queue 1 more than than the max number of packets (1 packet will remain
  // queued).
  for (size_t i = 0; i <= kBufferMaxNumPackets; i++) {
    std::unique_ptr<ScoDataPacket> packet =
        ScoDataPacket::New(kConnectionHandle0, /*payload_size=*/1);
    packet->mutable_view()->mutable_payload_data()[0] = static_cast<uint8_t>(i);

    // The last packet should remain queued.
    if (i < kBufferMaxNumPackets) {
      EXPECT_SCO_PACKET_OUT(test_device(),
                            StaticByteBuffer(LowerBits(kConnectionHandle0),
                                             UpperBits(kConnectionHandle0),
                                             0x01,  // payload length
                                             static_cast<uint8_t>(i)));
    }
    connection()->QueuePacket(std::move(packet));
    RunUntilIdle();
  }

  EXPECT_TRUE(test_device()->AllExpectedScoPacketsSent());

  EXPECT_SCO_PACKET_OUT(
      test_device(),
      StaticByteBuffer(LowerBits(kConnectionHandle0),
                       UpperBits(kConnectionHandle0),
                       0x01,  // payload length
                       static_cast<uint8_t>(kBufferMaxNumPackets)));
  test_device()->SendCommandChannelPacket(
      bt::testing::NumberOfCompletedPacketsPacket(kConnectionHandle0, 1));
  RunUntilIdle();
  EXPECT_TRUE(test_device()->AllExpectedScoPacketsSent());
}

TEST_F(ScoDataChannelSingleConnectionTest, ReceiveManyPackets) {
  for (uint8_t i = 0; i < 20; i++) {
    SCOPED_TRACE(i);
    StaticByteBuffer packet(LowerBits(kConnectionHandle0),
                            UpperBits(kConnectionHandle0),
                            0x01,  // payload length
                            i      // payload
    );
    test_device()->SendScoDataChannelPacket(packet);
    RunUntilIdle();
    ASSERT_EQ(connection()->received_packets().size(),
              static_cast<size_t>(i) + 1);
    EXPECT_TRUE(ContainersEqual(
        connection()->received_packets()[i]->view().data(), packet));
  }
}

TEST_F(ScoDataChannelTest, RegisterTwoConnectionsAndUnregisterFirstConnection) {
  int config_count = 0;
  test_device()->set_configure_sco_cb(
      [&](auto, auto, auto, fit::callback<void(pw::Status)> callback) {
        config_count++;
        callback(PW_STATUS_OK);
      });

  int reset_count = 0;
  test_device()->set_reset_sco_cb(
      [&](fit::callback<void(pw::Status)> callback) {
        reset_count++;
        callback(PW_STATUS_OK);
      });

  FakeScoConnection connection_0(sco_data_channel());
  sco_data_channel()->RegisterConnection(connection_0.GetWeakPtr());
  EXPECT_EQ(config_count, 1);
  EXPECT_EQ(reset_count, 0);

  FakeScoConnection connection_1(sco_data_channel(), kConnectionHandle1);
  sco_data_channel()->RegisterConnection(connection_1.GetWeakPtr());
  EXPECT_EQ(config_count, 1);
  EXPECT_EQ(reset_count, 0);

  StaticByteBuffer packet_0(LowerBits(kConnectionHandle0),
                            UpperBits(kConnectionHandle0),
                            0x01,  // payload length
                            0x00   // payload
  );
  test_device()->SendScoDataChannelPacket(packet_0);
  RunUntilIdle();
  ASSERT_EQ(connection_0.received_packets().size(), 1u);
  ASSERT_EQ(connection_1.received_packets().size(), 0u);

  StaticByteBuffer packet_1(LowerBits(kConnectionHandle1),
                            UpperBits(kConnectionHandle1),
                            0x01,  // payload length
                            0x01   // payload
  );
  test_device()->SendScoDataChannelPacket(packet_1);
  RunUntilIdle();
  ASSERT_EQ(connection_0.received_packets().size(), 1u);
  // The packet should be received even though connection_1 isn't the active
  // connection.
  ASSERT_EQ(connection_1.received_packets().size(), 1u);

  EXPECT_SCO_PACKET_OUT(test_device(), packet_0);
  std::unique_ptr<ScoDataPacket> out_packet_0 =
      ScoDataPacket::New(/*payload_size=*/1);
  out_packet_0->mutable_view()->mutable_data().Write(packet_0);
  out_packet_0->InitializeFromBuffer();
  connection_0.QueuePacket(std::move(out_packet_0));
  RunUntilIdle();
  EXPECT_TRUE(test_device()->AllExpectedScoPacketsSent());
  test_device()->SendCommandChannelPacket(
      bt::testing::NumberOfCompletedPacketsPacket(kConnectionHandle0, 1));

  std::unique_ptr<ScoDataPacket> out_packet_1 =
      ScoDataPacket::New(/*payload_size=*/1);
  out_packet_1->mutable_view()->mutable_data().Write(packet_1);
  out_packet_1->InitializeFromBuffer();
  // The packet should be sent even though connection_1 isn't the active
  // connection.
  EXPECT_SCO_PACKET_OUT(test_device(), packet_1);
  connection_1.QueuePacket(std::move(out_packet_1));
  RunUntilIdle();
  EXPECT_TRUE(test_device()->AllExpectedScoPacketsSent());
  // This is necessary because kBufferMaxNumPackets is 2, so we won't be able to
  // send any more packets until at least 1 is ACKed by the controller.
  test_device()->SendCommandChannelPacket(
      bt::testing::NumberOfCompletedPacketsPacket(kConnectionHandle1, 1));

  // connection_1 should become the active connection (+1 to config_count).
  sco_data_channel()->UnregisterConnection(connection_0.handle());
  EXPECT_EQ(config_count, 2);
  EXPECT_EQ(reset_count, 0);
  RunUntilIdle();

  out_packet_1 = ScoDataPacket::New(/*payload_size=*/1);
  out_packet_1->mutable_view()->mutable_data().Write(packet_1);
  out_packet_1->InitializeFromBuffer();
  // Now that connection_1 is the active connection, packets should still be
  // sent.
  EXPECT_SCO_PACKET_OUT(test_device(), packet_1);
  connection_1.QueuePacket(std::move(out_packet_1));
  RunUntilIdle();
  EXPECT_TRUE(test_device()->AllExpectedScoPacketsSent());

  // There are no active connections now (+1 to reset_count).
  sco_data_channel()->UnregisterConnection(connection_1.handle());
  EXPECT_EQ(config_count, 2);
  EXPECT_EQ(reset_count, 1);
}

TEST_F(ScoDataChannelTest,
       RegisterTwoConnectionsAndClearControllerPacketCountOfFirstConnection) {
  test_device()->set_configure_sco_cb(
      [](auto, auto, auto, fit::callback<void(pw::Status)> cb) {
        cb(PW_STATUS_OK);
      });
  test_device()->set_reset_sco_cb(
      [](fit::callback<void(pw::Status)> cb) { cb(PW_STATUS_OK); });

  FakeScoConnection connection_0(sco_data_channel());
  sco_data_channel()->RegisterConnection(connection_0.GetWeakPtr());

  FakeScoConnection connection_1(sco_data_channel(), kConnectionHandle1);
  sco_data_channel()->RegisterConnection(connection_1.GetWeakPtr());

  auto packet_0 = StaticByteBuffer(LowerBits(kConnectionHandle0),
                                   UpperBits(kConnectionHandle0),
                                   0x01,  // payload length
                                   0x00   // payload
  );
  auto packet_1 = StaticByteBuffer(LowerBits(kConnectionHandle0),
                                   UpperBits(kConnectionHandle0),
                                   0x01,  // payload length
                                   0x01   // payload
  );
  auto packet_2 = StaticByteBuffer(LowerBits(kConnectionHandle1),
                                   UpperBits(kConnectionHandle1),
                                   0x01,  // payload length
                                   0x02   // payload
  );

  EXPECT_SCO_PACKET_OUT(test_device(), packet_0);
  std::unique_ptr<ScoDataPacket> out_packet_0 =
      ScoDataPacket::New(/*payload_size=*/1);
  out_packet_0->mutable_view()->mutable_data().Write(packet_0);
  out_packet_0->InitializeFromBuffer();
  connection_0.QueuePacket(std::move(out_packet_0));
  RunUntilIdle();
  EXPECT_TRUE(test_device()->AllExpectedScoPacketsSent());

  // The second packet should fill up the controller buffer
  // (kBufferMaxNumPackets).
  ASSERT_EQ(kBufferMaxNumPackets, 2u);
  EXPECT_SCO_PACKET_OUT(test_device(), packet_1);
  std::unique_ptr<ScoDataPacket> out_packet_1 =
      ScoDataPacket::New(/*payload_size=*/1);
  out_packet_1->mutable_view()->mutable_data().Write(packet_1);
  out_packet_1->InitializeFromBuffer();
  connection_0.QueuePacket(std::move(out_packet_1));
  RunUntilIdle();
  EXPECT_TRUE(test_device()->AllExpectedScoPacketsSent());

  std::unique_ptr<ScoDataPacket> out_packet_2 =
      ScoDataPacket::New(/*payload_size=*/1);
  out_packet_2->mutable_view()->mutable_data().Write(packet_2);
  out_packet_2->InitializeFromBuffer();
  // The packet should NOT be sent because the controller buffer is full.
  connection_1.QueuePacket(std::move(out_packet_2));
  RunUntilIdle();

  // connection_1 should become the active connection, but out_packet_2 can't be
  // sent yet.
  sco_data_channel()->UnregisterConnection(connection_0.handle());
  RunUntilIdle();
  EXPECT_EQ(connection_1.queued_packets().size(), 1u);

  // Clearing the pending packet count for connection_0 should result in
  // packet_2 being sent.
  EXPECT_SCO_PACKET_OUT(test_device(), packet_2);
  sco_data_channel()->ClearControllerPacketCount(connection_0.handle());
  RunUntilIdle();
  EXPECT_TRUE(test_device()->AllExpectedScoPacketsSent());

  // There are no active connections now.
  sco_data_channel()->UnregisterConnection(connection_1.handle());
  sco_data_channel()->ClearControllerPacketCount(connection_1.handle());
  RunUntilIdle();
}

TEST_F(ScoDataChannelSingleConnectionTest,
       IgnoreInboundPacketForUnknownConnectionHandle) {
  // kConnectionHandle1 is not registered.
  auto packet = StaticByteBuffer(LowerBits(kConnectionHandle1),
                                 UpperBits(kConnectionHandle1),
                                 0x01,  // payload length
                                 0x07   // payload
  );
  test_device()->SendScoDataChannelPacket(packet);
  RunUntilIdle();
  EXPECT_EQ(connection()->received_packets().size(), 0u);
}

TEST_F(ScoDataChannelSingleConnectionTest,
       IgnoreNumberOfCompletedPacketsEventForUnknownConnectionHandle) {
  // Queue 1 more than than the max number of packets (1 packet will remain
  // queued).
  for (size_t i = 0; i <= kBufferMaxNumPackets; i++) {
    std::unique_ptr<ScoDataPacket> packet =
        ScoDataPacket::New(kConnectionHandle0, /*payload_size=*/1);
    packet->mutable_view()->mutable_payload_data()[0] = static_cast<uint8_t>(i);

    // The last packet should remain queued.
    if (i < kBufferMaxNumPackets) {
      EXPECT_SCO_PACKET_OUT(test_device(),
                            StaticByteBuffer(LowerBits(kConnectionHandle0),
                                             UpperBits(kConnectionHandle0),
                                             0x01,  // payload length
                                             static_cast<uint8_t>(i)));
    }
    connection()->QueuePacket(std::move(packet));
    RunUntilIdle();
  }
  EXPECT_EQ(connection()->queued_packets().size(), 1u);
  EXPECT_TRUE(test_device()->AllExpectedScoPacketsSent());

  // kConnectionHandle1 is not registered, so this event should be ignored (no
  // packets should be sent).
  test_device()->SendCommandChannelPacket(
      bt::testing::NumberOfCompletedPacketsPacket(kConnectionHandle1, 1));
  RunUntilIdle();
  EXPECT_EQ(connection()->queued_packets().size(), 1u);
}

TEST_F(ScoDataChannelSingleConnectionTest, ReceiveTooSmallPacket) {
  StaticByteBuffer invalid_packet(LowerBits(kConnectionHandle0),
                                  UpperBits(kConnectionHandle0));
  test_device()->SendScoDataChannelPacket(invalid_packet);
  RunUntilIdle();
  // Packet should be ignored.
  EXPECT_EQ(connection()->received_packets().size(), 0u);

  // The next valid packet should not be ignored.
  auto valid_packet = StaticByteBuffer(LowerBits(kConnectionHandle0),
                                       UpperBits(kConnectionHandle0),
                                       0x01,  // correct payload length
                                       0x01   // payload
  );
  test_device()->SendScoDataChannelPacket(valid_packet);
  RunUntilIdle();
  EXPECT_EQ(connection()->received_packets().size(), 1u);
}

TEST_F(ScoDataChannelSingleConnectionTest,
       ReceivePacketWithIncorrectHeaderLengthField) {
  auto packet = StaticByteBuffer(LowerBits(kConnectionHandle0),
                                 UpperBits(kConnectionHandle0),
                                 0x03,  // incorrect payload length
                                 0x00   // payload
  );
  test_device()->SendScoDataChannelPacket(packet);
  RunUntilIdle();
  // Packet should be ignored.
  EXPECT_EQ(connection()->received_packets().size(), 0u);

  // The next valid packet should not be ignored.
  packet = StaticByteBuffer(LowerBits(kConnectionHandle0),
                            UpperBits(kConnectionHandle0),
                            0x01,  // correct payload length
                            0x01   // payload
  );
  test_device()->SendScoDataChannelPacket(packet);
  RunUntilIdle();
  EXPECT_EQ(connection()->received_packets().size(), 1u);
}

TEST_F(ScoDataChannelTest, CvsdConnectionEncodingBits8SampleRate8Khz) {
  int config_count = 0;

  test_device()->set_configure_sco_cb(
      [&](ScoCodingFormat format,
          ScoEncoding encoding,
          ScoSampleRate rate,
          fit::callback<void(pw::Status)> callback) {
        config_count++;
        EXPECT_EQ(format, ScoCodingFormat::kCvsd);
        EXPECT_EQ(encoding, ScoEncoding::k8Bits);
        EXPECT_EQ(rate, ScoSampleRate::k8Khz);
        callback(PW_STATUS_OK);
      });

  int reset_count = 0;
  test_device()->set_reset_sco_cb(
      [&](fit::callback<void(pw::Status)> callback) {
        reset_count++;
        callback(PW_STATUS_OK);
      });

  FakeScoConnection connection_0(
      sco_data_channel(), kConnectionHandle0, cvsd_connection_params());
  sco_data_channel()->RegisterConnection(connection_0.GetWeakPtr());
  EXPECT_EQ(config_count, 1);
  EXPECT_EQ(reset_count, 0);
}

TEST_F(ScoDataChannelTest, CvsdConnectionEncodingBits16SampleRate8Khz) {
  int config_count = 0;
  test_device()->set_configure_sco_cb(
      [&](ScoCodingFormat format,
          ScoEncoding encoding,
          ScoSampleRate rate,
          fit::callback<void(pw::Status)> callback) {
        config_count++;
        EXPECT_EQ(format, ScoCodingFormat::kCvsd);
        EXPECT_EQ(encoding, ScoEncoding::k16Bits);
        EXPECT_EQ(rate, ScoSampleRate::k8Khz);
        callback(PW_STATUS_OK);
      });

  int reset_count = 0;
  test_device()->set_reset_sco_cb(
      [&](fit::callback<void(pw::Status)> callback) {
        reset_count++;
        callback(PW_STATUS_OK);
      });

  bt::StaticPacket<pw::bluetooth::emboss::SynchronousConnectionParametersWriter>
      params = cvsd_connection_params();
  auto view = params.view();
  view.input_coded_data_size_bits().Write(16);
  view.output_coded_data_size_bits().Write(16);
  // Bandwidth = sample size (2 bytes/sample) * sample rate (8000 samples/sec) =
  // 16000 bytes/sec
  view.output_bandwidth().Write(16000);
  view.input_bandwidth().Write(16000);
  FakeScoConnection connection(sco_data_channel(), kConnectionHandle0, params);
  sco_data_channel()->RegisterConnection(connection.GetWeakPtr());
  EXPECT_EQ(config_count, 1);
  EXPECT_EQ(reset_count, 0);
}

TEST_F(ScoDataChannelTest, CvsdConnectionEncodingBits16SampleRate16Khz) {
  int config_count = 0;
  test_device()->set_configure_sco_cb(
      [&](ScoCodingFormat format,
          ScoEncoding encoding,
          ScoSampleRate rate,
          fit::callback<void(pw::Status)> callback) {
        config_count++;
        EXPECT_EQ(format, ScoCodingFormat::kCvsd);
        EXPECT_EQ(encoding, ScoEncoding::k16Bits);
        EXPECT_EQ(rate, ScoSampleRate::k16Khz);
        callback(PW_STATUS_OK);
      });

  int reset_count = 0;
  test_device()->set_reset_sco_cb(
      [&](fit::callback<void(pw::Status)> callback) {
        reset_count++;
        callback(PW_STATUS_OK);
      });

  bt::StaticPacket<pw::bluetooth::emboss::SynchronousConnectionParametersWriter>
      params = cvsd_connection_params();
  auto view = params.view();
  view.input_coded_data_size_bits().Write(16);
  view.output_coded_data_size_bits().Write(16);
  // Bandwidth = sample size (2 bytes/sample) * sample rate (16,000 samples/sec)
  // = 32,000 bytes/sec
  view.output_bandwidth().Write(32000);
  view.input_bandwidth().Write(32000);
  FakeScoConnection connection(sco_data_channel(), kConnectionHandle0, params);
  sco_data_channel()->RegisterConnection(connection.GetWeakPtr());
  EXPECT_EQ(config_count, 1);
  EXPECT_EQ(reset_count, 0);
}

TEST_F(ScoDataChannelTest, CvsdConnectionInvalidSampleSizeAndRate) {
  int config_count = 0;
  test_device()->set_configure_sco_cb(
      [&](ScoCodingFormat format,
          ScoEncoding encoding,
          ScoSampleRate rate,
          fit::callback<void(pw::Status)> callback) {
        config_count++;
        EXPECT_EQ(format, ScoCodingFormat::kCvsd);
        EXPECT_EQ(encoding, ScoEncoding::k16Bits);
        EXPECT_EQ(rate, ScoSampleRate::k16Khz);
        callback(PW_STATUS_OK);
      });

  int reset_count = 0;
  test_device()->set_reset_sco_cb(
      [&](fit::callback<void(pw::Status)> callback) {
        reset_count++;
        callback(PW_STATUS_OK);
      });

  bt::StaticPacket<pw::bluetooth::emboss::SynchronousConnectionParametersWriter>
      params = cvsd_connection_params();
  auto view = params.view();
  // Invalid sample size will be replaced with sample size of 16 bits.
  view.input_coded_data_size_bits().Write(0u);
  view.output_coded_data_size_bits().Write(0u);
  // Invalid rate will be replaced with 16kHz.
  view.output_bandwidth().Write(1);
  view.input_bandwidth().Write(1);
  FakeScoConnection connection(sco_data_channel(), kConnectionHandle0, params);
  sco_data_channel()->RegisterConnection(connection.GetWeakPtr());
  EXPECT_EQ(config_count, 1);
  EXPECT_EQ(reset_count, 0);
}

TEST_F(ScoDataChannelTest,
       ConfigureCallbackCalledAfterTransportDestroyedDoesNotUseAfterFree) {
  fit::callback<void(pw::Status)> config_cb = nullptr;
  test_device()->set_configure_sco_cb(
      [&](ScoCodingFormat format,
          ScoEncoding encoding,
          ScoSampleRate rate,
          fit::callback<void(pw::Status)> callback) {
        config_cb = std::move(callback);
      });

  int reset_count = 0;
  test_device()->set_reset_sco_cb(
      [&](fit::callback<void(pw::Status)> callback) {
        reset_count++;
        callback(PW_STATUS_OK);
      });

  FakeScoConnection connection(sco_data_channel());
  sco_data_channel()->RegisterConnection(connection.GetWeakPtr());
  EXPECT_TRUE(config_cb);
  EXPECT_EQ(reset_count, 0);

  DeleteTransport();
  RunUntilIdle();

  // Callback should not use-after-free.
  config_cb(PW_STATUS_OK);
  RunUntilIdle();
}

TEST_F(
    ScoDataChannelTest,
    RegisterAndUnregisterFirstConnectionAndRegisterSecondConnectionBeforeFirstConfigCompletes) {
  std::vector<fit::callback<void(pw::Status)>> config_callbacks;
  test_device()->set_configure_sco_cb(
      [&](auto, auto, auto, fit::callback<void(pw::Status)> callback) {
        config_callbacks.emplace_back(std::move(callback));
      });

  int reset_count = 0;
  test_device()->set_reset_sco_cb(
      [&](fit::callback<void(pw::Status)> callback) {
        reset_count++;
        callback(PW_STATUS_OK);
      });

  FakeScoConnection connection_0(sco_data_channel());
  sco_data_channel()->RegisterConnection(connection_0.GetWeakPtr());
  EXPECT_EQ(config_callbacks.size(), 1u);
  sco_data_channel()->UnregisterConnection(connection_0.handle());
  EXPECT_EQ(reset_count, 1);

  FakeScoConnection connection_1(sco_data_channel(), kConnectionHandle1);
  auto packet = StaticByteBuffer(LowerBits(kConnectionHandle1),
                                 UpperBits(kConnectionHandle1),
                                 0x01,  // payload length
                                 0x00   // payload
  );
  std::unique_ptr<ScoDataPacket> sco_packet =
      ScoDataPacket::New(/*payload_size=*/1);
  sco_packet->mutable_view()->mutable_data().Write(packet);
  sco_packet->InitializeFromBuffer();
  connection_1.QueuePacket(std::move(sco_packet));

  sco_data_channel()->RegisterConnection(connection_1.GetWeakPtr());
  EXPECT_EQ(config_callbacks.size(), 2u);
  // sco_packet should not be sent yet.
  RunUntilIdle();
  // The first callback completing should not complete the second connection
  // configuration.
  config_callbacks[0](PW_STATUS_OK);
  // sco_packet should not be sent yet.
  RunUntilIdle();
  EXPECT_EQ(connection_1.queued_packets().size(), 1u);
  // Queued packet should be sent after second callback called.
  config_callbacks[1](PW_STATUS_OK);
  EXPECT_SCO_PACKET_OUT(test_device(), packet);
  RunUntilIdle();
  EXPECT_TRUE(test_device()->AllExpectedScoPacketsSent());
}

TEST_F(ScoDataChannelSingleConnectionTest,
       ReceiveNumberOfCompletedPacketsEventWithInconsistentNumberOfHandles) {
  // Queue 1 more than than the max number of packets (1 packet will remain
  // queued).
  for (size_t i = 0; i <= kBufferMaxNumPackets; i++) {
    std::unique_ptr<ScoDataPacket> packet =
        ScoDataPacket::New(kConnectionHandle0, /*payload_size=*/1);
    packet->mutable_view()->mutable_payload_data()[0] = static_cast<uint8_t>(i);

    // The last packet should remain queued.
    if (i < kBufferMaxNumPackets) {
      EXPECT_SCO_PACKET_OUT(test_device(),
                            StaticByteBuffer(LowerBits(kConnectionHandle0),
                                             UpperBits(kConnectionHandle0),
                                             0x01,  // payload length
                                             static_cast<uint8_t>(i)));
    }
    connection()->QueuePacket(std::move(packet));
    RunUntilIdle();
  }
  EXPECT_TRUE(test_device()->AllExpectedScoPacketsSent());

  // The handle in the event should still be processed even though the number of
  // handles is wrong.
  EXPECT_SCO_PACKET_OUT(
      test_device(),
      StaticByteBuffer(LowerBits(kConnectionHandle0),
                       UpperBits(kConnectionHandle0),
                       0x01,  // payload length
                       static_cast<uint8_t>(kBufferMaxNumPackets)));

  constexpr uint16_t num_packets = 1;
  StaticByteBuffer event{
      0x13,
      0x05,  // Number Of Completed Packet HCI event header, parameters length
      0x09,  // Incorrect number of handles
      LowerBits(kConnectionHandle0),
      UpperBits(kConnectionHandle0),
      LowerBits(num_packets),
      UpperBits(num_packets)};
  test_device()->SendCommandChannelPacket(event);
  RunUntilIdle();
  EXPECT_TRUE(test_device()->AllExpectedScoPacketsSent());
}

TEST_F(ScoDataChannelTest, RegisterTwoConnectionsAndFirstConfigurationFails) {
  int config_count = 0;
  test_device()->set_configure_sco_cb(
      [&](ScoCodingFormat format,
          ScoEncoding encoding,
          ScoSampleRate rate,
          fit::callback<void(pw::Status)> callback) {
        config_count++;
        if (config_count == 1) {
          callback(pw::Status::InvalidArgument());
          return;
        }
        callback(PW_STATUS_OK);
      });

  int reset_count = 0;
  test_device()->set_reset_sco_cb(
      [&](fit::callback<void(pw::Status)> callback) {
        reset_count++;
        callback(PW_STATUS_OK);
      });

  FakeScoConnection connection_0(sco_data_channel());
  sco_data_channel()->RegisterConnection(connection_0.GetWeakPtr());
  EXPECT_EQ(config_count, 1);
  EXPECT_EQ(reset_count, 0);
  EXPECT_EQ(connection_0.hci_error_count(), 0);

  FakeScoConnection connection_1(sco_data_channel(), kConnectionHandle1);
  sco_data_channel()->RegisterConnection(connection_1.GetWeakPtr());
  EXPECT_EQ(config_count, 1);
  EXPECT_EQ(reset_count, 0);

  // The first configuration error should be processed & the configuration of
  // connection_1 should succeed.
  RunUntilIdle();
  EXPECT_EQ(connection_0.hci_error_count(), 1);
  EXPECT_EQ(config_count, 2);
  EXPECT_EQ(reset_count, 0);

  auto packet_0 = StaticByteBuffer(LowerBits(kConnectionHandle0),
                                   UpperBits(kConnectionHandle0),
                                   0x01,  // payload length
                                   0x00   // payload
  );
  test_device()->SendScoDataChannelPacket(packet_0);
  RunUntilIdle();
  // packet_0 should not be received since connection_0 failed configuration and
  // was unregistered.
  ASSERT_EQ(connection_0.received_packets().size(), 0u);

  auto packet_1 = StaticByteBuffer(LowerBits(kConnectionHandle1),
                                   UpperBits(kConnectionHandle1),
                                   0x01,  // payload length
                                   0x01   // payload
  );
  test_device()->SendScoDataChannelPacket(packet_1);
  RunUntilIdle();
  ASSERT_EQ(connection_1.received_packets().size(), 1u);

  // There are no active connections now (+1 to reset_count).
  sco_data_channel()->UnregisterConnection(connection_1.handle());
  EXPECT_EQ(config_count, 2);
  EXPECT_EQ(reset_count, 1);
}

TEST_F(ScoDataChannelTest, UnsupportedCodingFormatTreatedAsCvsd) {
  int config_count = 0;
  test_device()->set_configure_sco_cb(
      [&](ScoCodingFormat format,
          ScoEncoding encoding,
          ScoSampleRate rate,
          fit::callback<void(pw::Status)> callback) {
        config_count++;
        EXPECT_EQ(format, ScoCodingFormat::kCvsd);
        callback(PW_STATUS_OK);
      });

  int reset_count = 0;
  test_device()->set_reset_sco_cb(
      [&](fit::callback<void(pw::Status)> callback) {
        reset_count++;
        callback(PW_STATUS_OK);
      });

  bt::StaticPacket<pw::bluetooth::emboss::SynchronousConnectionParametersWriter>
      params = cvsd_connection_params();
  auto view = params.view();
  view.output_coding_format().coding_format().Write(
      pw::bluetooth::emboss::CodingFormat::U_LAW);
  view.input_coding_format().coding_format().Write(
      pw::bluetooth::emboss::CodingFormat::U_LAW);
  FakeScoConnection connection_0(
      sco_data_channel(), kConnectionHandle0, params);
  sco_data_channel()->RegisterConnection(connection_0.GetWeakPtr());
  EXPECT_EQ(config_count, 1);
  EXPECT_EQ(reset_count, 0);
}

TEST_F(ScoDataChannelSingleConnectionTest,
       NumberOfCompletedPacketsExceedsPendingPackets) {
  // Queue 1 more than than the max number of packets (1 packet will remain
  // queued).
  for (size_t i = 0; i <= kBufferMaxNumPackets; i++) {
    std::unique_ptr<ScoDataPacket> packet =
        ScoDataPacket::New(kConnectionHandle0, /*payload_size=*/1);
    packet->mutable_view()->mutable_payload_data()[0] = static_cast<uint8_t>(i);

    // The last packet should remain queued.
    if (i < kBufferMaxNumPackets) {
      EXPECT_SCO_PACKET_OUT(test_device(),
                            StaticByteBuffer(LowerBits(kConnectionHandle0),
                                             UpperBits(kConnectionHandle0),
                                             0x01,  // payload length
                                             static_cast<uint8_t>(i)));
    }
    connection()->QueuePacket(std::move(packet));
    RunUntilIdle();
  }

  EXPECT_TRUE(test_device()->AllExpectedScoPacketsSent());

  EXPECT_SCO_PACKET_OUT(
      test_device(),
      StaticByteBuffer(LowerBits(kConnectionHandle0),
                       UpperBits(kConnectionHandle0),
                       0x01,  // payload length
                       static_cast<uint8_t>(kBufferMaxNumPackets)));
  test_device()->SendCommandChannelPacket(
      bt::testing::NumberOfCompletedPacketsPacket(kConnectionHandle0,
                                                  kBufferMaxNumPackets + 1));
  RunUntilIdle();
  EXPECT_TRUE(test_device()->AllExpectedScoPacketsSent());
}

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