// Copyright 2019 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 "helpers.h"

#include <algorithm>
#include <iterator>

#include <gmock/gmock.h>
#include <gtest/gtest.h>

#include "adapter_test_fixture.h"
#include "fuchsia/bluetooth/cpp/fidl.h"
#include "fuchsia/bluetooth/le/cpp/fidl.h"
#include "fuchsia/bluetooth/sys/cpp/fidl.h"
#include "lib/fidl/cpp/comparison.h"
#include "src/connectivity/bluetooth/core/bt-host/common/advertising_data.h"
#include "src/connectivity/bluetooth/core/bt-host/common/test_helpers.h"
#include "src/connectivity/bluetooth/core/bt-host/common/uuid.h"
#include "src/connectivity/bluetooth/core/bt-host/gap/gap.h"
#include "src/connectivity/bluetooth/core/bt-host/sco/sco.h"
#include "src/connectivity/bluetooth/core/bt-host/sdp/sdp.h"
#include "src/connectivity/bluetooth/core/bt-host/sm/types.h"

namespace fble = fuchsia::bluetooth::le;
namespace fbt = fuchsia::bluetooth;
namespace fsys = fuchsia::bluetooth::sys;
namespace fbg = fuchsia::bluetooth::gatt;
namespace fbredr = fuchsia::bluetooth::bredr;
namespace faudio = fuchsia::hardware::audio;

namespace fuchsia::bluetooth {
// Make UUIDs equality comparable for advanced testing matchers. ADL rules mandate the namespace.
bool operator==(const Uuid& a, const Uuid& b) { return fidl::Equals(a, b); }
}  // namespace fuchsia::bluetooth

namespace bthost::fidl_helpers {
namespace {

// Constants as BT stack types
const bt::UInt128 kTestKeyValue{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
const bt::sm::SecurityProperties kTestSecurity(bt::sm::SecurityLevel::kSecureAuthenticated, 16,
                                               true);
const bt::sm::LTK kTestLtk(kTestSecurity, bt::hci::LinkKey(kTestKeyValue, 0, 0));
const bt::sm::Key kTestKey(kTestSecurity, kTestKeyValue);

// Constants as FIDL types
const fbt::Address kPublicAddrFidl = fbt::Address{fbt::AddressType::PUBLIC, {1, 0, 0, 0, 0, 0}};
const fbt::Address kRandomAddrFidl = fbt::Address{fbt::AddressType::RANDOM, {2, 0, 0, 0, 0, 0}};

const bt::DeviceAddress kTestPeerAddr(bt::DeviceAddress::Type::kBREDR, {1, 0, 0, 0, 0, 0});

const fsys::PeerKey kTestKeyFidl{
    .security =
        fsys::SecurityProperties{
            .authenticated = true,
            .secure_connections = true,
            .encryption_key_size = 16,
        },
    .data = fsys::Key{.value = kTestKeyValue},
};
const fsys::Ltk kTestLtkFidl{.key = kTestKeyFidl, .ediv = 0, .rand = 0};

TEST(FIDL_HelpersTest, HostErrorToFidl) {
  EXPECT_EQ(fsys::Error::FAILED, HostErrorToFidl(bt::HostError::kFailed));
  EXPECT_EQ(fsys::Error::TIMED_OUT, HostErrorToFidl(bt::HostError::kTimedOut));
  EXPECT_EQ(fsys::Error::INVALID_ARGUMENTS, HostErrorToFidl(bt::HostError::kInvalidParameters));
  EXPECT_EQ(fsys::Error::CANCELED, HostErrorToFidl(bt::HostError::kCanceled));
  EXPECT_EQ(fsys::Error::IN_PROGRESS, HostErrorToFidl(bt::HostError::kInProgress));
  EXPECT_EQ(fsys::Error::NOT_SUPPORTED, HostErrorToFidl(bt::HostError::kNotSupported));
  EXPECT_EQ(fsys::Error::PEER_NOT_FOUND, HostErrorToFidl(bt::HostError::kNotFound));

  // All other errors currently map to FAILED.
  EXPECT_EQ(fsys::Error::FAILED, HostErrorToFidl(bt::HostError::kProtocolError));
}

TEST(FIDL_HelpersTest, GattStatusToFidl) {
  // Host errors
  EXPECT_EQ(fbg::Error::INVALID_RESPONSE,
            GattStatusToFidl(bt::att::Status(bt::HostError::kPacketMalformed)));
  EXPECT_EQ(fbg::Error::FAILURE, GattStatusToFidl(bt::att::Status(bt::HostError::kTimedOut)));

  // Protocol errors
  EXPECT_EQ(fbg::Error::INSUFFICIENT_AUTHORIZATION,
            GattStatusToFidl(bt::att::Status(bt::att::ErrorCode::kInsufficientAuthorization)));
  EXPECT_EQ(fbg::Error::INSUFFICIENT_AUTHENTICATION,
            GattStatusToFidl(bt::att::Status(bt::att::ErrorCode::kInsufficientAuthentication)));
  EXPECT_EQ(fbg::Error::INSUFFICIENT_ENCRYPTION_KEY_SIZE,
            GattStatusToFidl(bt::att::Status(bt::att::ErrorCode::kInsufficientEncryptionKeySize)));
  EXPECT_EQ(fbg::Error::INSUFFICIENT_ENCRYPTION,
            GattStatusToFidl(bt::att::Status(bt::att::ErrorCode::kInsufficientEncryption)));
  EXPECT_EQ(fbg::Error::READ_NOT_PERMITTED,
            GattStatusToFidl(bt::att::Status(bt::att::ErrorCode::kReadNotPermitted)));
  EXPECT_EQ(fbg::Error::FAILURE,
            GattStatusToFidl(bt::att::Status(bt::att::ErrorCode::kUnlikelyError)));
}

TEST(FIDL_HelpersTest, AddressBytesFrommString) {
  EXPECT_FALSE(AddressBytesFromString(""));
  EXPECT_FALSE(AddressBytesFromString("FF"));
  EXPECT_FALSE(AddressBytesFromString("FF:FF:FF:FF:"));
  EXPECT_FALSE(AddressBytesFromString("FF:FF:FF:FF:FF:F"));
  EXPECT_FALSE(AddressBytesFromString("FF:FF:FF:FF:FF:FZ"));
  EXPECT_FALSE(AddressBytesFromString("FF:FF:FF:FF:FF:FZ"));
  EXPECT_FALSE(AddressBytesFromString("FF:FF:FF:FF:FF:FF "));
  EXPECT_FALSE(AddressBytesFromString(" FF:FF:FF:FF:FF:FF"));

  auto addr1 = AddressBytesFromString("FF:FF:FF:FF:FF:FF");
  EXPECT_TRUE(addr1);
  EXPECT_EQ("FF:FF:FF:FF:FF:FF", addr1->ToString());

  auto addr2 = AddressBytesFromString("03:7F:FF:02:0F:01");
  EXPECT_TRUE(addr2);
  EXPECT_EQ("03:7F:FF:02:0F:01", addr2->ToString());
}

TEST(FIDL_HelpersTest, AdvertisingIntervalFromFidl) {
  EXPECT_EQ(bt::gap::AdvertisingInterval::FAST1,
            AdvertisingIntervalFromFidl(fble::AdvertisingModeHint::VERY_FAST));
  EXPECT_EQ(bt::gap::AdvertisingInterval::FAST2,
            AdvertisingIntervalFromFidl(fble::AdvertisingModeHint::FAST));
  EXPECT_EQ(bt::gap::AdvertisingInterval::SLOW,
            AdvertisingIntervalFromFidl(fble::AdvertisingModeHint::SLOW));
}

TEST(FIDL_HelpersTest, UuidFromFidl) {
  fbt::Uuid input;
  input.value = {{0xFB, 0x34, 0x9B, 0x5F, 0x80, 0x00, 0x00, 0x80, 0x00, 0x10, 0x00, 0x00, 0x0d,
                  0x18, 0x00, 0x00}};

  // We expect the input bytes to be carried over directly.
  bt::UUID output = UuidFromFidl(input);
  EXPECT_EQ("0000180d-0000-1000-8000-00805f9b34fb", output.ToString());
  EXPECT_EQ(2u, output.CompactSize());
}

TEST(FIDL_HelpersTest, AdvertisingDataFromFidlEmpty) {
  fble::AdvertisingData input;
  ASSERT_TRUE(input.IsEmpty());

  std::optional<bt::AdvertisingData> maybe_data = AdvertisingDataFromFidl(input);
  ASSERT_TRUE(maybe_data.has_value());
  auto output = std::move(*maybe_data);

  EXPECT_TRUE(output.service_uuids().empty());
  EXPECT_TRUE(output.service_data_uuids().empty());
  EXPECT_TRUE(output.manufacturer_data_ids().empty());
  EXPECT_TRUE(output.uris().empty());
  EXPECT_FALSE(output.appearance());
  EXPECT_FALSE(output.tx_power());
  EXPECT_FALSE(output.local_name());
}

TEST(FIDL_HelpersTest, AdvertisingDataFromFidlName) {
  constexpr char kTestName[] = "💩";
  fble::AdvertisingData input;
  input.set_name(kTestName);

  std::optional<bt::AdvertisingData> maybe_data = AdvertisingDataFromFidl(input);
  ASSERT_TRUE(maybe_data.has_value());
  auto output = std::move(*maybe_data);
  EXPECT_TRUE(output.local_name());
  EXPECT_EQ(kTestName, *output.local_name());
}

TEST(FIDL_HelpersTest, AdvertisingDataFromFidlAppearance) {
  fble::AdvertisingData input;
  input.set_appearance(fuchsia::bluetooth::Appearance::HID_DIGITIZER_TABLET);

  std::optional<bt::AdvertisingData> maybe_data = AdvertisingDataFromFidl(input);
  ASSERT_TRUE(maybe_data.has_value());
  auto output = std::move(*maybe_data);

  EXPECT_TRUE(output.appearance());

  // Value comes from the standard Bluetooth "assigned numbers" document.
  EXPECT_EQ(0x03C5, *output.appearance());
}

TEST(FIDL_HelpersTest, AdvertisingDataFromFidlTxPower) {
  constexpr int8_t kTxPower = -50;
  fble::AdvertisingData input;
  input.set_tx_power_level(kTxPower);

  std::optional<bt::AdvertisingData> maybe_data = AdvertisingDataFromFidl(input);
  ASSERT_TRUE(maybe_data.has_value());
  auto output = std::move(*maybe_data);

  EXPECT_TRUE(output.tx_power());
  EXPECT_EQ(kTxPower, *output.tx_power());
}

TEST(FIDL_HelpersTest, AdvertisingDataFromFidlUuids) {
  // The first two entries are duplicated. The resulting structure should contain no duplicates.
  const fbt::Uuid kUuid1{{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}};
  const fbt::Uuid kUuid2{{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}};
  const fbt::Uuid kUuid3{{16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1}};
  fble::AdvertisingData input;
  input.set_service_uuids({{kUuid1, kUuid2, kUuid3}});

  std::optional<bt::AdvertisingData> maybe_data = AdvertisingDataFromFidl(input);
  ASSERT_TRUE(maybe_data.has_value());
  auto output = std::move(*maybe_data);

  EXPECT_EQ(2u, output.service_uuids().size());
  EXPECT_EQ(1u, output.service_uuids().count(bt::UUID(kUuid1.value)));
  EXPECT_EQ(1u, output.service_uuids().count(bt::UUID(kUuid2.value)));
}

TEST(FIDL_HelpersTest, AdvertisingDataFromFidlServiceData) {
  const fbt::Uuid kUuid1{{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}};
  const fbt::Uuid kUuid2{{16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1}};
  const std::vector<uint8_t> kData1{{'h', 'e', 'l', 'l', 'o'}};
  const std::vector<uint8_t> kData2{{'b', 'y', 'e'}};

  fble::AdvertisingData input;
  input.set_service_data({{{kUuid1, kData1}, {kUuid2, kData2}}});

  std::optional<bt::AdvertisingData> maybe_data = AdvertisingDataFromFidl(input);
  ASSERT_TRUE(maybe_data.has_value());
  auto output = std::move(*maybe_data);
  EXPECT_EQ(2u, output.service_data_uuids().size());
  EXPECT_TRUE(ContainersEqual(bt::BufferView(kData1), output.service_data(bt::UUID(kUuid1.value))));
  EXPECT_TRUE(ContainersEqual(bt::BufferView(kData2), output.service_data(bt::UUID(kUuid2.value))));
}

TEST(FIDL_HelpersTest, AdvertisingDataFromFidlManufacturerData) {
  constexpr uint16_t kCompanyId1 = 1;
  constexpr uint16_t kCompanyId2 = 2;
  const std::vector<uint8_t> kData1{{'h', 'e', 'l', 'l', 'o'}};
  const std::vector<uint8_t> kData2{{'b', 'y', 'e'}};

  fble::AdvertisingData input;
  input.set_manufacturer_data({{{kCompanyId1, kData1}, {kCompanyId2, kData2}}});

  std::optional<bt::AdvertisingData> maybe_data = AdvertisingDataFromFidl(input);
  ASSERT_TRUE(maybe_data.has_value());
  auto output = std::move(*maybe_data);
  EXPECT_EQ(2u, output.manufacturer_data_ids().size());
  EXPECT_TRUE(ContainersEqual(bt::BufferView(kData1), output.manufacturer_data(kCompanyId1)));
  EXPECT_TRUE(ContainersEqual(bt::BufferView(kData2), output.manufacturer_data(kCompanyId2)));
}

std::string UuidToString(fbt::Uuid uuid) {
  std::string s;
  for (uint8_t byte : uuid.value) {
    s += std::to_string(static_cast<uint16_t>(byte)) + ", ";
  }
  return s;
}
// Each field for this test first attempts to perform the too-long conversion, and then verifies
// that the bounds are where expected by performing a successful conversion with a field that just
// fits in the encoded version. This also enables using the same `input` throughout the test.
TEST(FIDL_HelpersTest, AdvertisingDataFromFidlWithFieldsTooLong) {
  fble::AdvertisingData input;
  // The length of the AD name field must be <= 248 bytes per v5.2, Vol 4, Part E, 7.3.11 and Vol 3,
  // Part C, 12.1.`
  {
    std::string name_that_fits(bt::kMaxNameLength, 'a');
    std::string too_long_name(bt::kMaxNameLength + 1, 'b');
    input.set_name(too_long_name);
    EXPECT_FALSE(AdvertisingDataFromFidl(input).has_value());
    input.set_name(name_that_fits);
    EXPECT_TRUE(AdvertisingDataFromFidl(input).has_value());
  }
  {
    // This is the longest encoding scheme known to Fuchsia BT, so this represents the longest
    // string allowed (and subsequently, too long to be allowed) by both FIDL and internal
    // invariants.
    std::string uri = "ms-settings-cloudstorage:";
    uri += std::string(fble::MAX_URI_LENGTH - uri.size(), '.');
    input.set_uris({uri});
    EXPECT_FALSE(AdvertisingDataFromFidl(input).has_value());
    // This string should fit when it is one character shorter.
    uri.pop_back();
    input.set_uris({uri});
    EXPECT_TRUE(AdvertisingDataFromFidl(input).has_value());
  }
  // Ensure encoded service data that is too long is rejected.
  {
    const fbt::Uuid kUuid1{.value = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}};
    // |kUuid1| = 16 bytes, i.e. 14 bytes longer than the shortest possible encoded UUID (2 bytes).
    std::vector too_long_data(fble::MAX_SERVICE_DATA_LENGTH - 13, uint8_t{0xAB});
    input.set_service_data(std::vector({fble::ServiceData{.uuid = kUuid1, .data = too_long_data}}));
    EXPECT_FALSE(AdvertisingDataFromFidl(input).has_value());
    // A vector that is 1 byte shorter than too_long_data should convert successfully
    std::vector data_that_fits(too_long_data.size() - 1, too_long_data[0]);
    input.set_service_data(
        std::vector({fble::ServiceData{.uuid = kUuid1, .data = data_that_fits}}));
    EXPECT_TRUE(AdvertisingDataFromFidl(input).has_value());
  }
  // Ensure encoded manufacturer data that is too long is rejected.
  {
    uint16_t company_id = 0x1212;
    std::vector too_long_data(fble::MAX_MANUFACTURER_DATA_LENGTH + 1, uint8_t{0xAB});
    input.set_manufacturer_data(
        std::vector({fble::ManufacturerData{.company_id = company_id, .data = too_long_data}}));
    EXPECT_FALSE(AdvertisingDataFromFidl(input).has_value());
    // A vector that is 1 byte shorter than too_long_data should convert successfully
    std::vector data_that_fits(too_long_data.size() - 1, too_long_data[0]);
    input.set_manufacturer_data(
        std::vector({fble::ManufacturerData{.company_id = company_id, .data = data_that_fits}}));
    EXPECT_TRUE(AdvertisingDataFromFidl(input).has_value());
  }
  // Ensure input with too many service UUIDs is truncated (NOT rejected).
  {
    std::vector<fbt::Uuid> fbt_uuids;
    fbt::Uuid kBaseUuid{.value = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}};
    for (int i = 0; i < bt::kMax128BitUuids; ++i) {
      fbt::Uuid next_uuid = kBaseUuid;
      next_uuid.value[0] += i;
      fbt_uuids.push_back(next_uuid);
    }
    input.set_service_uuids(fbt_uuids);
    auto ad = AdvertisingDataFromFidl(input);
    EXPECT_TRUE(ad.has_value());
    std::unordered_set<bt::UUID> converted_uuids = ad->service_uuids();
    for (auto& fbt_uuid : fbt_uuids) {
      SCOPED_TRACE(UuidToString(fbt_uuid));
      EXPECT_TRUE(converted_uuids.find(bt::UUID(fbt_uuid.value)) != converted_uuids.end());
    }
    fbt::Uuid excessive_uuid = kBaseUuid;
    excessive_uuid.value[0] += bt::kMax128BitUuids + 1;
    fbt_uuids.push_back(excessive_uuid);
    input.set_service_uuids(fbt_uuids);
    ad = AdvertisingDataFromFidl(input);
    EXPECT_TRUE(ad.has_value());
    converted_uuids = ad->service_uuids();
    EXPECT_TRUE(converted_uuids.find(bt::UUID(excessive_uuid.value)) == converted_uuids.end());
  }
}

TEST(FIDL_HelpersTest, AdvertisingDataToFidlDeprecatedEmpty) {
  bt::AdvertisingData input;
  auto output = AdvertisingDataToFidlDeprecated(input);

  // All fields in |input| are not set. Therefore, output should have no set fields as well.
  EXPECT_FALSE(output.name);
  EXPECT_FALSE(output.tx_power_level);
  EXPECT_FALSE(output.appearance);
  EXPECT_FALSE(output.service_uuids);
  EXPECT_FALSE(output.service_data);
  EXPECT_FALSE(output.manufacturer_specific_data);
  EXPECT_FALSE(output.solicited_service_uuids);
  EXPECT_FALSE(output.uris);
}

TEST(FIDL_HelpersTest, AdvertisingDataToFidlDeprecated) {
  bt::AdvertisingData input;
  EXPECT_TRUE(input.SetLocalName("fuchsia"));
  input.SetTxPower(4);
  input.SetAppearance(0x1234);

  const uint16_t id = 0x5678;
  const bt::UUID test_uuid = bt::UUID(id);
  auto service_bytes = bt::CreateStaticByteBuffer(0x01, 0x02);
  EXPECT_TRUE(input.AddServiceUuid(test_uuid));
  EXPECT_TRUE(input.SetServiceData(test_uuid, service_bytes.view()));

  uint16_t company_id = 0x98;
  auto manufacturer_bytes = bt::CreateStaticByteBuffer(0x04, 0x03);
  EXPECT_TRUE(input.SetManufacturerData(company_id, manufacturer_bytes.view()));

  auto uri = "http://fuchsia.cl";
  EXPECT_TRUE(input.AddUri(uri));

  auto output = AdvertisingDataToFidlDeprecated(input);

  EXPECT_EQ("fuchsia", output.name);

  auto expected_power_level = fbt::Int8::New();
  expected_power_level->value = 4;
  EXPECT_EQ(expected_power_level->value, output.tx_power_level->value);

  auto expected_appearance = fbt::UInt16::New();
  expected_appearance->value = 0x1234;
  EXPECT_EQ(expected_appearance->value, output.appearance->value);

  EXPECT_EQ(1u, output.service_uuids->size());
  EXPECT_EQ(test_uuid.ToString(), output.service_uuids->front());

  EXPECT_EQ(1u, output.service_data->size());
  auto service_data = output.service_data->front();
  EXPECT_EQ(test_uuid.ToString(), service_data.uuid);
  EXPECT_TRUE(ContainersEqual(bt::BufferView(service_bytes), service_data.data));

  EXPECT_EQ(1u, output.manufacturer_specific_data->size());
  auto manufacturer_data = output.manufacturer_specific_data->front();
  EXPECT_EQ(company_id, manufacturer_data.company_id);
  EXPECT_TRUE(ContainersEqual(bt::BufferView(manufacturer_bytes), manufacturer_data.data));

  EXPECT_EQ(1u, output.uris->size());
  EXPECT_EQ(uri, output.uris->front());
}

TEST(FIDL_HelpersTest, AdvertisingDataToFidlEmpty) {
  bt::AdvertisingData input;
  auto output = AdvertisingDataToFidl(input);

  // All fields in |input| are not set. Therefore, output should have no set fields as well.
  EXPECT_FALSE(output.has_name());
  EXPECT_FALSE(output.has_tx_power_level());
  EXPECT_FALSE(output.has_appearance());
  EXPECT_FALSE(output.has_service_uuids());
  EXPECT_FALSE(output.has_service_data());
  EXPECT_FALSE(output.has_manufacturer_data());
  EXPECT_FALSE(output.has_uris());
}

TEST(FIDL_HelpersTest, AdvertisingDataToFidl) {
  bt::AdvertisingData input;
  EXPECT_TRUE(input.SetLocalName("fuchsia"));
  input.SetTxPower(4);
  const uint16_t kAppearance = 193u;  // WATCH_SPORTS
  input.SetAppearance(kAppearance);

  const uint16_t id = 0x5678;
  const bt::UUID test_uuid = bt::UUID(id);
  auto service_bytes = bt::CreateStaticByteBuffer(0x01, 0x02);
  EXPECT_TRUE(input.AddServiceUuid(test_uuid));
  EXPECT_TRUE(input.SetServiceData(test_uuid, service_bytes.view()));

  uint16_t company_id = 0x98;
  auto manufacturer_bytes = bt::CreateStaticByteBuffer(0x04, 0x03);
  EXPECT_TRUE(input.SetManufacturerData(company_id, manufacturer_bytes.view()));

  auto uri = "http://fuchsia.cl/461435";
  EXPECT_TRUE(input.AddUri(uri));

  auto output = AdvertisingDataToFidl(input);

  EXPECT_EQ("fuchsia", output.name());

  auto expected_power_level = fbt::Int8::New();
  expected_power_level->value = 4;
  EXPECT_EQ(expected_power_level->value, output.tx_power_level());

  EXPECT_EQ(fbt::Appearance{kAppearance}, output.appearance());

  EXPECT_EQ(1u, output.service_uuids().size());
  EXPECT_EQ(test_uuid, UuidFromFidl(output.service_uuids().front()));

  EXPECT_EQ(1u, output.service_data().size());
  auto service_data = output.service_data().front();
  EXPECT_EQ(test_uuid, UuidFromFidl(service_data.uuid));
  EXPECT_TRUE(ContainersEqual(bt::BufferView(service_bytes), service_data.data));

  EXPECT_EQ(1u, output.manufacturer_data().size());
  auto manufacturer_data = output.manufacturer_data().front();
  EXPECT_EQ(company_id, manufacturer_data.company_id);
  EXPECT_TRUE(ContainersEqual(bt::BufferView(manufacturer_bytes), manufacturer_data.data));

  EXPECT_THAT(output.uris(), ::testing::ElementsAre(uri));
}

TEST(FIDL_HelpersTest, AdvertisingDataToFidlOmitsNonEnumeratedAppearance) {
  // There is an "unknown" appearance, which is why this isn't named that.
  const uint16_t kNonEnumeratedAppearance = 0xFFFFu;
  bt::AdvertisingData input;
  input.SetAppearance(kNonEnumeratedAppearance);

  EXPECT_FALSE(AdvertisingDataToFidl(input).has_appearance());

  const uint16_t kKnownAppearance = 832u;  // HEART_RATE_SENSOR
  input.SetAppearance(kKnownAppearance);

  EXPECT_TRUE(AdvertisingDataToFidl(input).has_appearance());
}

TEST(FIDL_HelpersTest, LeSecurityModeFromFidl) {
  EXPECT_EQ(bt::gap::LeSecurityMode::Mode1, LeSecurityModeFromFidl(fsys::LeSecurityMode::MODE_1));
  EXPECT_EQ(bt::gap::LeSecurityMode::SecureConnectionsOnly,
            LeSecurityModeFromFidl(fsys::LeSecurityMode::SECURE_CONNECTIONS_ONLY));
  auto nonexistent_security_mode = static_cast<fsys::LeSecurityMode>(0xFF);
  EXPECT_EQ(bt::gap::LeSecurityMode::SecureConnectionsOnly,
            LeSecurityModeFromFidl(nonexistent_security_mode));
}

TEST(FIDL_HelpersTest, TechnologyTypeToFidl) {
  EXPECT_EQ(fsys::TechnologyType::LOW_ENERGY,
            TechnologyTypeToFidl(bt::gap::TechnologyType::kLowEnergy));
  EXPECT_EQ(fsys::TechnologyType::CLASSIC, TechnologyTypeToFidl(bt::gap::TechnologyType::kClassic));
  EXPECT_EQ(fsys::TechnologyType::DUAL_MODE,
            TechnologyTypeToFidl(bt::gap::TechnologyType::kDualMode));
}

TEST(FIDL_HelpersTest, SecurityLevelFromFidl) {
  const fsys::PairingSecurityLevel level = fsys::PairingSecurityLevel::AUTHENTICATED;
  EXPECT_EQ(bt::sm::SecurityLevel::kAuthenticated, SecurityLevelFromFidl(level));
}

TEST(FIDL_HelpersTest, SecurityLevelFromBadFidlFails) {
  int nonexistant_security_level = 500000;
  auto level = static_cast<fsys::PairingSecurityLevel>(nonexistant_security_level);
  EXPECT_EQ(std::nullopt, SecurityLevelFromFidl(level));
}

TEST(FIDL_HelpersTest, PeerToFidlMandatoryFields) {
  // Required by PeerCache expiry functions.
  async::TestLoop dispatcher;

  inspect::Inspector inspector;
  bt::gap::PeerCache cache;
  bt::DeviceAddress addr(bt::DeviceAddress::Type::kLEPublic, {0, 1, 2, 3, 4, 5});
  auto* peer = cache.NewPeer(addr, /*connectable=*/true);
  auto fidl = PeerToFidl(*peer);
  ASSERT_TRUE(fidl.has_id());
  EXPECT_EQ(peer->identifier().value(), fidl.id().value);
  ASSERT_TRUE(fidl.has_address());
  EXPECT_TRUE(
      fidl::Equals(fbt::Address{fbt::AddressType::PUBLIC, {{0, 1, 2, 3, 4, 5}}}, fidl.address()));
  ASSERT_TRUE(fidl.has_technology());
  EXPECT_EQ(fsys::TechnologyType::LOW_ENERGY, fidl.technology());
  ASSERT_TRUE(fidl.has_connected());
  EXPECT_FALSE(fidl.connected());
  ASSERT_TRUE(fidl.has_bonded());
  EXPECT_FALSE(fidl.bonded());

  EXPECT_FALSE(fidl.has_name());
  EXPECT_FALSE(fidl.has_appearance());
  EXPECT_FALSE(fidl.has_rssi());
  EXPECT_FALSE(fidl.has_tx_power());
  EXPECT_FALSE(fidl.has_device_class());
  EXPECT_FALSE(fidl.has_services());
  EXPECT_FALSE(fidl.has_le_services());
  EXPECT_FALSE(fidl.has_bredr_services());
}

TEST(FIDL_HelpersTest, PeerToFidlOptionalFields) {
  // Required by PeerCache expiry functions.
  async::TestLoop dispatcher;

  const int8_t kRssi = 5;
  const int8_t kTxPower = 6;
  const auto kAdv =
      bt::CreateStaticByteBuffer(0x02, 0x01, 0x01,               // Flags: General Discoverable
                                 0x03, 0x19, 192, 0,             // Appearance: Watch
                                 0x02, 0x0A, 0x06,               // Tx-Power: 5
                                 0x05, 0x09, 't', 'e', 's', 't'  // Complete Local Name: "test"
      );
  const std::vector kBrEdrServices = {bt::UUID(uint16_t{0x110a}), bt::UUID(uint16_t{0x110b})};

  inspect::Inspector inspector;
  bt::gap::PeerCache cache;
  bt::DeviceAddress addr(bt::DeviceAddress::Type::kLEPublic, {0, 1, 2, 3, 4, 5});
  auto* peer = cache.NewPeer(addr, /*connectable=*/true);
  peer->MutLe().SetAdvertisingData(kRssi, kAdv);
  peer->MutBrEdr().SetInquiryData(bt::hci::InquiryResult{
      bt::DeviceAddressBytes{{0, 1, 2, 3, 4, 5}}, bt::hci::PageScanRepetitionMode::kR0, 0, 0,
      bt::DeviceClass(bt::DeviceClass::MajorClass::kPeripheral), 0});
  for (auto& service : kBrEdrServices) {
    peer->MutBrEdr().AddService(service);
  }

  auto fidl = PeerToFidl(*peer);
  ASSERT_TRUE(fidl.has_name());
  EXPECT_EQ("test", fidl.name());
  ASSERT_TRUE(fidl.has_appearance());
  EXPECT_EQ(fbt::Appearance::WATCH, fidl.appearance());
  ASSERT_TRUE(fidl.has_rssi());
  EXPECT_EQ(kRssi, fidl.rssi());
  ASSERT_TRUE(fidl.has_tx_power());
  EXPECT_EQ(kTxPower, fidl.tx_power());
  ASSERT_TRUE(fidl.has_device_class());
  EXPECT_EQ(fbt::MAJOR_DEVICE_CLASS_PERIPHERAL, fidl.device_class().value);

  // Deprecated and never implemented (see fxbug.dev/57344).
  EXPECT_FALSE(fidl.has_services());

  // TODO(fxbug.dev/57344): Add a test when this field gets populated.
  EXPECT_FALSE(fidl.has_le_services());

  ASSERT_TRUE(fidl.has_bredr_services());
  std::vector<fbt::Uuid> expected_uuids;
  std::transform(kBrEdrServices.begin(), kBrEdrServices.end(), std::back_inserter(expected_uuids),
                 UuidToFidl);
  EXPECT_THAT(fidl.bredr_services(), ::testing::UnorderedElementsAreArray(expected_uuids));
}

TEST(FIDL_HelpersTest, ReliableModeFromFidl) {
  using WriteOptions = fuchsia::bluetooth::gatt::WriteOptions;
  using ReliableMode = fuchsia::bluetooth::gatt::ReliableMode;
  WriteOptions options;

  // No options set, so this should default to disabled.
  EXPECT_EQ(bt::gatt::ReliableMode::kDisabled, ReliableModeFromFidl(options));

  options.set_reliable_mode(ReliableMode::ENABLED);
  EXPECT_EQ(bt::gatt::ReliableMode::kEnabled, ReliableModeFromFidl(options));

  options.set_reliable_mode(ReliableMode::DISABLED);
  EXPECT_EQ(bt::gatt::ReliableMode::kDisabled, ReliableModeFromFidl(options));
}

// TODO: Set information w/o setting language, set a FIDL type that cannot be converted
// - make sure the expected attributes are set and have the correct type
// - make sure the profile descriptor sets the right attributes
TEST(FIDL_HelpersTest, ServiceDefinitionToServiceRecord) {
  fuchsia::bluetooth::bredr::ServiceDefinition def_should_fail;
  // Should fail to convert without service class UUIDs.
  auto rec_no_uuids = ServiceDefinitionToServiceRecord(def_should_fail);
  EXPECT_FALSE(rec_no_uuids.is_ok());
  // Should fail to convert when information set without language.
  def_should_fail.mutable_service_class_uuids()->emplace_back(
      fidl_helpers::UuidToFidl(bt::sdp::profile::kAudioSink));
  fuchsia::bluetooth::bredr::Information info_no_language;
  def_should_fail.mutable_information()->emplace_back(std::move(info_no_language));
  auto rec_no_language = ServiceDefinitionToServiceRecord(def_should_fail);
  EXPECT_FALSE(rec_no_language.is_ok());

  // Create definition for successful conversion.
  fuchsia::bluetooth::bredr::ServiceDefinition def;
  def.mutable_service_class_uuids()->emplace_back(
      fidl_helpers::UuidToFidl(bt::sdp::profile::kAudioSink));
  fuchsia::bluetooth::bredr::Information info;
  info.set_language("en");
  info.set_name("TEST");
  def.mutable_information()->emplace_back(std::move(info));
  fuchsia::bluetooth::bredr::ProtocolDescriptor l2cap_proto;
  l2cap_proto.protocol = fuchsia::bluetooth::bredr::ProtocolIdentifier::L2CAP;
  fuchsia::bluetooth::bredr::DataElement l2cap_data_el;
  l2cap_data_el.set_uint16(fuchsia::bluetooth::bredr::PSM_SDP);
  l2cap_proto.params.emplace_back(std::move(l2cap_data_el));
  def.mutable_protocol_descriptor_list()->emplace_back(std::move(l2cap_proto));
  fuchsia::bluetooth::bredr::ProtocolDescriptor avdtp_proto;
  avdtp_proto.protocol = fuchsia::bluetooth::bredr::ProtocolIdentifier::AVDTP;
  fuchsia::bluetooth::bredr::DataElement avdtp_data_el;
  avdtp_data_el.set_uint16(0x0103);  // Version 1.3
  avdtp_proto.params.emplace_back(std::move(avdtp_data_el));
  def.mutable_protocol_descriptor_list()->emplace_back(std::move(avdtp_proto));
  fuchsia::bluetooth::bredr::ProfileDescriptor prof_desc;
  prof_desc.profile_id =
      fuchsia::bluetooth::bredr::ServiceClassProfileIdentifier::ADVANCED_AUDIO_DISTRIBUTION;
  prof_desc.major_version = 1;
  prof_desc.minor_version = 3;
  def.mutable_profile_descriptors()->emplace_back(prof_desc);
  bt::sdp::AttributeId valid_att_id = 0x1111;
  fuchsia::bluetooth::bredr::Attribute valid_attribute;
  valid_attribute.element.set_uint8(0x01);
  valid_attribute.id = valid_att_id;
  def.mutable_additional_attributes()->emplace_back(std::move(valid_attribute));
  // Add an invalid additional attribute that should not convert.
  bt::sdp::AttributeId invalid_att_id = 0x1112;
  fuchsia::bluetooth::bredr::Attribute invalid_attribute;
  invalid_attribute.element.set_url("");
  invalid_attribute.id = invalid_att_id;
  def.mutable_additional_attributes()->emplace_back(std::move(invalid_attribute));

  // Confirm converted ServiceRecord fields match ServiceDefinition
  auto rec = ServiceDefinitionToServiceRecord(def);
  EXPECT_TRUE(rec.is_ok());

  // Confirm UUIDs match
  std::unordered_set<bt::UUID> attribute_uuid = {bt::sdp::profile::kAudioSink};
  EXPECT_TRUE(rec.value().FindUUID(attribute_uuid));

  // Confirm information fields match
  EXPECT_TRUE(rec.value().HasAttribute(bt::sdp::kLanguageBaseAttributeIdList));
  const bt::sdp::DataElement& lang_val =
      rec.value().GetAttribute(bt::sdp::kLanguageBaseAttributeIdList);
  auto triplets = lang_val.Get<std::vector<bt::sdp::DataElement>>();
  EXPECT_TRUE(triplets);
  EXPECT_TRUE(triplets->size() % 3 == 0);
  EXPECT_EQ(bt::sdp::DataElement::Type::kUnsignedInt, triplets->at(0).type());
  EXPECT_EQ(bt::sdp::DataElement::Type::kUnsignedInt, triplets->at(1).type());
  EXPECT_EQ(bt::sdp::DataElement::Type::kUnsignedInt, triplets->at(2).type());
  auto lang = triplets->at(0).Get<uint16_t>();
  EXPECT_TRUE(lang);
  EXPECT_EQ(0x656e, *lang);  // should be 'en' in ascii (but big-endian)
  auto encoding = triplets->at(1).Get<uint16_t>();
  EXPECT_TRUE(encoding);
  EXPECT_EQ(106, *encoding);  // should always be UTF-8
  auto base_attrid = triplets->at(2).Get<uint16_t>();
  EXPECT_TRUE(base_attrid);
  EXPECT_EQ(0x0100, *base_attrid);  // The primary language must be at 0x0100.
  EXPECT_TRUE(rec.value().HasAttribute(*base_attrid + bt::sdp::kServiceNameOffset));
  const bt::sdp::DataElement& name_elem =
      rec.value().GetAttribute(*base_attrid + bt::sdp::kServiceNameOffset);
  auto name = name_elem.Get<std::string>();
  EXPECT_TRUE(name);
  EXPECT_EQ("TEST", *name);

  // Confirm protocol +  descriptor list
  EXPECT_TRUE(rec.value().HasAttribute(bt::sdp::kProtocolDescriptorList));
  const bt::sdp::DataElement& protocol_val =
      rec.value().GetAttribute(bt::sdp::kProtocolDescriptorList);
  bt::DynamicByteBuffer protocol_block(protocol_val.WriteSize());
  protocol_val.Write(&protocol_block);
  auto expected_protocol_list =
      bt::CreateStaticByteBuffer(0x35, 0x10,  // Data Element Sequence (10 bytes)
                                 0x35, 0x06,  // Data Element Sequence (6 bytes)
                                 0x19,        // UUID (16 bits)
                                 0x01, 0x00,  // L2CAP Profile UUID
                                 0x09,        // uint16_t
                                 0x00, 0x01,  // PSM = SDP
                                 0x35, 0x06,  // Data Element Sequence (6 bytes)
                                 0x19,        // UUID
                                 0x00, 0x19,  // AVTDP Profile UUID
                                 0x09,        // uint16_t
                                 0x01, 0x03   // PSM_AVDTP
      );
  EXPECT_EQ(expected_protocol_list.size(), protocol_block.size());
  EXPECT_TRUE(ContainersEqual(expected_protocol_list, protocol_block));

  // Confirm profile descriptor list
  EXPECT_TRUE(rec.value().HasAttribute(bt::sdp::kBluetoothProfileDescriptorList));
  const bt::sdp::DataElement& profile_val =
      rec.value().GetAttribute(bt::sdp::kBluetoothProfileDescriptorList);
  bt::DynamicByteBuffer profile_block(profile_val.WriteSize());
  profile_val.Write(&profile_block);
  auto expected_profile_list =
      bt::CreateStaticByteBuffer(0x35, 0x08,  // Data Element Sequence (8 bytes)
                                 0x35, 0x06,  // Data Element Sequence (6 bytes)
                                 0x19,        // UUID
                                 0x11, 0x0d,  // Advanced Audio Identifier
                                 0x09,        // uint16_t
                                 0x01, 0x03   // Major and minor version
      );
  EXPECT_EQ(expected_profile_list.size(), profile_block.size());
  EXPECT_TRUE(ContainersEqual(expected_profile_list, profile_block));

  // Confirm additional attributes
  EXPECT_TRUE(rec.value().HasAttribute(valid_att_id));
  EXPECT_FALSE(rec.value().HasAttribute(invalid_att_id));
}

TEST(FIDL_HelpersTest, FidlToBrEdrSecurityRequirements) {
  fbredr::ChannelParameters params;
  EXPECT_EQ(
      FidlToBrEdrSecurityRequirements(params),
      (bt::gap::BrEdrSecurityRequirements{.authentication = false, .secure_connections = false}));

  params.set_security_requirements(fbredr::SecurityRequirements());
  EXPECT_EQ(
      FidlToBrEdrSecurityRequirements(params),
      (bt::gap::BrEdrSecurityRequirements{.authentication = false, .secure_connections = false}));

  params.mutable_security_requirements()->set_secure_connections_required(false);
  EXPECT_EQ(
      FidlToBrEdrSecurityRequirements(params),
      (bt::gap::BrEdrSecurityRequirements{.authentication = false, .secure_connections = false}));
  params.mutable_security_requirements()->clear_secure_connections_required();

  params.mutable_security_requirements()->set_authentication_required(false);
  EXPECT_EQ(
      FidlToBrEdrSecurityRequirements(params),
      (bt::gap::BrEdrSecurityRequirements{.authentication = false, .secure_connections = false}));

  params.mutable_security_requirements()->set_secure_connections_required(false);
  EXPECT_EQ(
      FidlToBrEdrSecurityRequirements(params),
      (bt::gap::BrEdrSecurityRequirements{.authentication = false, .secure_connections = false}));

  params.mutable_security_requirements()->set_authentication_required(true);
  EXPECT_EQ(
      FidlToBrEdrSecurityRequirements(params),
      (bt::gap::BrEdrSecurityRequirements{.authentication = true, .secure_connections = false}));

  params.mutable_security_requirements()->set_secure_connections_required(true);
  EXPECT_EQ(
      FidlToBrEdrSecurityRequirements(params),
      (bt::gap::BrEdrSecurityRequirements{.authentication = true, .secure_connections = true}));
}

TEST(FIDL_HelpersTest, AddressFromFidlBondingDataRandomAddressRejectedIfBredr) {
  fsys::BondingData bond;
  bond.set_address(kRandomAddrFidl);
  bond.set_bredr_bond(fsys::BredrBondData());

  EXPECT_EQ(std::nullopt, AddressFromFidlBondingData(bond));
}

TEST(FIDL_HelpersTest, AddressFromFidlBondingDataBredr) {
  fsys::BondingData bond;
  bond.set_address(kPublicAddrFidl);
  bond.set_bredr_bond(fsys::BredrBondData());

  auto addr = AddressFromFidlBondingData(bond);
  ASSERT_TRUE(addr);
  EXPECT_EQ(addr->type(), bt::DeviceAddress::Type::kBREDR);
}

TEST(FIDL_HelpersTest, AddressFromFidlBondingDataDualMode) {
  fsys::BondingData bond;
  bond.set_address(kPublicAddrFidl);
  bond.set_bredr_bond(fsys::BredrBondData());
  bond.set_le_bond(fsys::LeBondData());

  auto addr = AddressFromFidlBondingData(bond);
  ASSERT_TRUE(addr);
  EXPECT_EQ(addr->type(), bt::DeviceAddress::Type::kBREDR);
}

TEST(FIDL_HelpersTest, AddressFromFidlBondingDataLePublic) {
  fsys::BondingData bond;
  bond.set_address(kPublicAddrFidl);
  bond.set_le_bond(fsys::LeBondData());

  auto addr = AddressFromFidlBondingData(bond);
  ASSERT_TRUE(addr);
  EXPECT_EQ(addr->type(), bt::DeviceAddress::Type::kLEPublic);
}

TEST(FIDL_HelpersTest, AddressFromFidlBondingDataLeRandom) {
  fsys::BondingData bond;
  bond.set_address(kRandomAddrFidl);
  bond.set_le_bond(fsys::LeBondData());

  auto addr = AddressFromFidlBondingData(bond);
  ASSERT_TRUE(addr);
  EXPECT_EQ(addr->type(), bt::DeviceAddress::Type::kLERandom);
}

TEST(FIDL_HelpersTest, LePairingDataFromFidlEmpty) {
  bt::sm::PairingData result = LePairingDataFromFidl(fsys::LeBondData());
  EXPECT_FALSE(result.identity_address);
  EXPECT_FALSE(result.local_ltk);
  EXPECT_FALSE(result.peer_ltk);
  EXPECT_FALSE(result.irk);
  EXPECT_FALSE(result.csrk);
}

TEST(FIDL_HelpersTest, LePairingDataFromFidl) {
  fsys::LeBondData le;
  le.set_local_ltk(kTestLtkFidl);
  le.set_peer_ltk(kTestLtkFidl);
  le.set_irk(kTestKeyFidl);
  le.set_csrk(kTestKeyFidl);

  bt::sm::PairingData result = LePairingDataFromFidl(std::move(le));
  EXPECT_FALSE(result.identity_address);
  ASSERT_TRUE(result.local_ltk);
  ASSERT_TRUE(result.peer_ltk);
  ASSERT_TRUE(result.irk);
  ASSERT_TRUE(result.csrk);

  EXPECT_EQ(kTestLtk, *result.local_ltk);
  EXPECT_EQ(kTestLtk, *result.peer_ltk);
  EXPECT_EQ(kTestKey, *result.irk);
  EXPECT_EQ(kTestKey, *result.csrk);
}

TEST(FIDL_HelpersTest, BredrKeyFromFidlEmpty) {
  EXPECT_FALSE(BredrKeyFromFidl(fsys::BredrBondData()));
}

TEST(FIDL_HelpersTest, BredrKeyFromFidl) {
  const bt::sm::SecurityProperties kTestSecurity(bt::sm::SecurityLevel::kSecureAuthenticated, 16,
                                                 true);
  const bt::sm::LTK kTestLtk(kTestSecurity, bt::hci::LinkKey(kTestKeyValue, 0, 0));

  fsys::BredrBondData bredr;
  bredr.set_link_key(kTestKeyFidl);
  std::optional<bt::sm::LTK> result = BredrKeyFromFidl(bredr);
  ASSERT_TRUE(result);
  EXPECT_EQ(kTestLtk, *result);
}

TEST(FIDL_HelpersTest, BredrServicesFromFidlEmpty) {
  EXPECT_TRUE(BredrServicesFromFidl(fsys::BredrBondData()).empty());
}

TEST(FIDL_HelpersTest, BredrServicesFromFidl) {
  fsys::BredrBondData bredr;
  bredr.mutable_services()->push_back(UuidToFidl(bt::sdp::profile::kAudioSink));
  bredr.mutable_services()->push_back(UuidToFidl(bt::sdp::profile::kAudioSource));
  auto bredr_services = BredrServicesFromFidl(bredr);
  EXPECT_THAT(bredr_services, ::testing::UnorderedElementsAre(bt::sdp::profile::kAudioSource,
                                                              bt::sdp::profile::kAudioSink));
}

class FIDL_HelpersAdapterTest : public bthost::testing::AdapterTestFixture {};

TEST_F(FIDL_HelpersAdapterTest, HostInfoToFidl) {
  // Verify that the default parameters are populated as expected.
  auto host_info = HostInfoToFidl(*adapter());
  ASSERT_TRUE(host_info.has_id());
  ASSERT_TRUE(host_info.has_technology());
  ASSERT_TRUE(host_info.has_address());
  ASSERT_TRUE(host_info.has_local_name());
  ASSERT_TRUE(host_info.has_discoverable());
  ASSERT_TRUE(host_info.has_discovering());

  EXPECT_EQ(adapter()->identifier().value(), host_info.id().value);
  EXPECT_EQ(fsys::TechnologyType::DUAL_MODE, host_info.technology());
  EXPECT_EQ(fbt::AddressType::PUBLIC, host_info.address().type);
  EXPECT_TRUE(
      ContainersEqual(adapter()->state().controller_address().bytes(), host_info.address().bytes));
  EXPECT_EQ("fuchsia", host_info.local_name());
  EXPECT_FALSE(host_info.discoverable());
  EXPECT_FALSE(host_info.discovering());
}

TEST_F(FIDL_HelpersAdapterTest, PeerToFidlBondingData_NoTransportData) {
  auto* peer = adapter()->peer_cache()->NewPeer(kTestPeerAddr, /*connectable=*/true);
  fsys::BondingData data = PeerToFidlBondingData(*adapter(), *peer);
  ASSERT_TRUE(data.has_identifier());
  ASSERT_TRUE(data.has_local_address());
  ASSERT_TRUE(data.has_address());
  EXPECT_FALSE(data.has_name());
  EXPECT_FALSE(data.has_le_bond());
  EXPECT_FALSE(data.has_bredr_bond());

  EXPECT_EQ(peer->identifier().value(), data.identifier().value);
  EXPECT_TRUE(fidl::Equals((fbt::Address{fbt::AddressType::PUBLIC, std::array<uint8_t, 6>{0}}),
                           data.local_address()));
  EXPECT_TRUE(fidl::Equals(kPublicAddrFidl, data.address()));
}

TEST_F(FIDL_HelpersAdapterTest, PeerToFidlBondingData_BothTransportsPresentButNotBonded) {
  auto* peer = adapter()->peer_cache()->NewPeer(kTestPeerAddr, /*connectable=*/true);
  peer->MutLe();
  peer->MutBrEdr();

  fsys::BondingData data = PeerToFidlBondingData(*adapter(), *peer);
  ASSERT_TRUE(data.has_identifier());
  ASSERT_TRUE(data.has_local_address());
  ASSERT_TRUE(data.has_address());
  EXPECT_FALSE(data.has_le_bond());
  EXPECT_FALSE(data.has_bredr_bond());

  EXPECT_EQ(peer->identifier().value(), data.identifier().value);
  EXPECT_TRUE(fidl::Equals((fbt::Address{fbt::AddressType::PUBLIC, std::array<uint8_t, 6>{0}}),
                           data.local_address()));
  EXPECT_TRUE(fidl::Equals(kPublicAddrFidl, data.address()));
}

TEST_F(FIDL_HelpersAdapterTest, PeerToFidlBondingData_BredrServicesDiscoveredNotBonded) {
  auto* peer = adapter()->peer_cache()->NewPeer(kTestPeerAddr, /*connectable=*/true);
  peer->MutBrEdr().AddService(bt::UUID(uint16_t{0x1234}));

  fsys::BondingData data = PeerToFidlBondingData(*adapter(), *peer);
  EXPECT_FALSE(data.has_bredr_bond());
}

TEST_F(FIDL_HelpersAdapterTest, PeerToFidlBondingData_EmptyLeData) {
  auto* peer = adapter()->peer_cache()->NewPeer(kTestPeerAddr, /*connectable=*/true);
  peer->MutLe().SetBondData(bt::sm::PairingData());

  fsys::BondingData data = PeerToFidlBondingData(*adapter(), *peer);
  EXPECT_FALSE(data.has_bredr_bond());
  ASSERT_TRUE(data.has_le_bond());
  EXPECT_FALSE(data.le_bond().has_local_ltk());
  EXPECT_FALSE(data.le_bond().has_peer_ltk());
  EXPECT_FALSE(data.le_bond().has_irk());
  EXPECT_FALSE(data.le_bond().has_csrk());
}

TEST_F(FIDL_HelpersAdapterTest, PeerToFidlBondingData_LeData) {
  auto* peer = adapter()->peer_cache()->NewPeer(kTestPeerAddr, /*connectable=*/true);
  peer->MutLe().SetBondData(bt::sm::PairingData{
      .local_ltk = {kTestLtk},
      .peer_ltk = {kTestLtk},
      .irk = {kTestKey},
      .csrk = {kTestKey},
  });

  fsys::BondingData data = PeerToFidlBondingData(*adapter(), *peer);
  EXPECT_FALSE(data.has_bredr_bond());
  ASSERT_TRUE(data.has_le_bond());
  ASSERT_TRUE(data.le_bond().has_local_ltk());
  ASSERT_TRUE(data.le_bond().has_peer_ltk());
  ASSERT_TRUE(data.le_bond().has_irk());
  ASSERT_TRUE(data.le_bond().has_csrk());

  EXPECT_TRUE(fidl::Equals(kTestLtkFidl, data.le_bond().local_ltk()));
  EXPECT_TRUE(fidl::Equals(kTestLtkFidl, data.le_bond().peer_ltk()));
  EXPECT_TRUE(fidl::Equals(kTestKeyFidl, data.le_bond().irk()));
  EXPECT_TRUE(fidl::Equals(kTestKeyFidl, data.le_bond().csrk()));
}

TEST_F(FIDL_HelpersAdapterTest, PeerToFidlBondingData_BredrData) {
  auto* peer = adapter()->peer_cache()->NewPeer(kTestPeerAddr, /*connectable=*/true);
  peer->MutBrEdr().SetBondData(kTestLtk);

  fsys::BondingData data = PeerToFidlBondingData(*adapter(), *peer);
  EXPECT_FALSE(data.has_le_bond());
  ASSERT_TRUE(data.has_bredr_bond());
  ASSERT_TRUE(data.bredr_bond().has_link_key());
  EXPECT_TRUE(fidl::Equals(kTestKeyFidl, data.bredr_bond().link_key()));
}

TEST_F(FIDL_HelpersAdapterTest, PeerToFidlBondingData_IncludesBredrServices) {
  auto* peer = adapter()->peer_cache()->NewPeer(kTestPeerAddr, /*connectable=*/true);
  peer->MutBrEdr().SetBondData(kTestLtk);
  peer->MutBrEdr().AddService(bt::sdp::profile::kAudioSink);
  peer->MutBrEdr().AddService(bt::sdp::profile::kAudioSource);

  fsys::BondingData data = PeerToFidlBondingData(*adapter(), *peer);
  ASSERT_TRUE(data.has_bredr_bond());
  ASSERT_TRUE(data.bredr_bond().has_services());

  EXPECT_THAT(data.bredr_bond().services(),
              ::testing::UnorderedElementsAre(UuidToFidl(bt::sdp::profile::kAudioSink),
                                              UuidToFidl(bt::sdp::profile::kAudioSource)));
}

TEST_F(FIDL_HelpersAdapterTest, FidlToScoParameters) {
  fbredr::ScoConnectionParameters params;
  EXPECT_TRUE(FidlToScoParameters(params).is_error());
  params.set_parameter_set(fbredr::HfpParameterSet::MSBC_T2);
  EXPECT_TRUE(FidlToScoParameters(params).is_error());
  params.set_air_coding_format(fbredr::CodingFormat::MSBC);
  EXPECT_TRUE(FidlToScoParameters(params).is_error());
  params.set_air_frame_size(8u);
  EXPECT_TRUE(FidlToScoParameters(params).is_error());
  params.set_io_bandwidth(32000);
  EXPECT_TRUE(FidlToScoParameters(params).is_error());
  params.set_io_coding_format(fbredr::CodingFormat::LINEAR_PCM);
  EXPECT_TRUE(FidlToScoParameters(params).is_error());
  params.set_io_frame_size(16u);
  EXPECT_TRUE(FidlToScoParameters(params).is_error());
  params.set_io_pcm_data_format(faudio::SampleFormat::PCM_SIGNED);
  EXPECT_TRUE(FidlToScoParameters(params).is_error());
  params.set_io_pcm_sample_payload_msb_position(3u);
  EXPECT_TRUE(FidlToScoParameters(params).is_error());
  params.set_path(fbredr::DataPath::OFFLOAD);
  ASSERT_TRUE(FidlToScoParameters(params).is_ok());

  bt::hci::SynchronousConnectionParameters out = FidlToScoParameters(params).take_value();
  EXPECT_EQ(out.transmit_bandwidth, 8000u);
  EXPECT_EQ(out.receive_bandwidth, 8000u);

  EXPECT_EQ(out.transmit_coding_format.coding_format, bt::hci::CodingFormat::kMSbc);
  EXPECT_EQ(out.transmit_coding_format.company_id, 0u);
  EXPECT_EQ(out.transmit_coding_format.vendor_codec_id, 0u);

  EXPECT_EQ(out.receive_coding_format.coding_format, bt::hci::CodingFormat::kMSbc);
  EXPECT_EQ(out.receive_coding_format.company_id, 0u);
  EXPECT_EQ(out.receive_coding_format.vendor_codec_id, 0u);

  EXPECT_EQ(out.transmit_codec_frame_size_bytes, 8u);
  EXPECT_EQ(out.receive_codec_frame_size_bytes, 8u);

  EXPECT_EQ(out.input_bandwidth, 32000u);
  EXPECT_EQ(out.output_bandwidth, 32000u);

  EXPECT_EQ(out.input_coding_format.coding_format, bt::hci::CodingFormat::kLinearPcm);
  EXPECT_EQ(out.input_coding_format.company_id, 0u);
  EXPECT_EQ(out.input_coding_format.vendor_codec_id, 0u);

  EXPECT_EQ(out.output_coding_format.coding_format, bt::hci::CodingFormat::kLinearPcm);
  EXPECT_EQ(out.output_coding_format.company_id, 0u);
  EXPECT_EQ(out.output_coding_format.vendor_codec_id, 0u);

  EXPECT_EQ(out.input_coded_data_size_bits, 16u);
  EXPECT_EQ(out.output_coded_data_size_bits, 16u);

  EXPECT_EQ(out.input_pcm_data_format, bt::hci::PcmDataFormat::k2sComplement);
  EXPECT_EQ(out.output_pcm_data_format, bt::hci::PcmDataFormat::k2sComplement);

  EXPECT_EQ(out.input_pcm_sample_payload_msb_position, 3u);
  EXPECT_EQ(out.output_pcm_sample_payload_msb_position, 3u);

  EXPECT_EQ(out.input_data_path, static_cast<bt::hci::ScoDataPath>(6));
  EXPECT_EQ(out.output_data_path, static_cast<bt::hci::ScoDataPath>(6));

  EXPECT_EQ(out.input_transport_unit_size_bits, 0u);
  EXPECT_EQ(out.output_transport_unit_size_bits, 0u);

  EXPECT_EQ(out.max_latency_ms, bt::sco::kParameterSetMsbcT2.max_latency_ms);
  EXPECT_EQ(out.packet_types, bt::sco::kParameterSetMsbcT2.packet_types);
  EXPECT_EQ(out.retransmission_effort, bt::sco::kParameterSetMsbcT2.retransmission_effort);

  // When the IO coding format is Linear PCM, the PCM data format is required.
  params.clear_io_pcm_data_format();
  EXPECT_TRUE(FidlToScoParameters(params).is_error());

  // PCM_FLOAT is not a supported PCM format.
  params.set_io_pcm_data_format(faudio::SampleFormat::PCM_FLOAT);
  EXPECT_TRUE(FidlToScoParameters(params).is_error());

  // PCM format for non-PCM IO coding formats is kNotApplicable and MSB is 0.
  params.set_io_coding_format(fbredr::CodingFormat::TRANSPARENT);
  ASSERT_TRUE(FidlToScoParameters(params).is_ok());
  out = FidlToScoParameters(params).value();
  EXPECT_EQ(out.input_pcm_data_format, bt::hci::PcmDataFormat::kNotApplicable);
  EXPECT_EQ(out.input_pcm_sample_payload_msb_position, 0u);
}

}  // namespace
}  // namespace bthost::fidl_helpers
