// 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 "src/connectivity/bluetooth/core/bt-host/public/pw_bluetooth_sapphire/internal/host/common/advertising_data.h"

#include <limits>
#include <string>
#include <variant>

#include <gtest/gtest.h>

#include "src/connectivity/bluetooth/core/bt-host/public/pw_bluetooth_sapphire/internal/host/common/byte_buffer.h"
#include "src/connectivity/bluetooth/core/bt-host/public/pw_bluetooth_sapphire/internal/host/common/log.h"
#include "src/connectivity/bluetooth/core/bt-host/public/pw_bluetooth_sapphire/internal/host/common/random.h"
#include "src/connectivity/bluetooth/core/bt-host/public/pw_bluetooth_sapphire/internal/host/common/to_string.h"
#include "src/connectivity/bluetooth/core/bt-host/public/pw_bluetooth_sapphire/internal/host/common/uuid.h"
#include "src/connectivity/bluetooth/core/bt-host/public/pw_bluetooth_sapphire/internal/host/testing/test_helpers.h"
#include "src/connectivity/bluetooth/lib/cpp-string/string_printf.h"

namespace bt {
namespace {

constexpr uint16_t kGattUuid = 0x1801;
constexpr uint16_t kEddystoneUuid = 0xFEAA;
constexpr uint16_t kHeartRateServiceUuid = 0x180D;

constexpr uint16_t kId1As16 = 0x0212;
constexpr uint16_t kId2As16 = 0x1122;

constexpr size_t kRandomDataSize = 100;

TEST(AdvertisingDataTest, MakeEmpty) {
  AdvertisingData data;

  EXPECT_EQ(0u, data.CalculateBlockSize());
}

TEST(AdvertisingDataTest, CopyLeavesNoRemnants) {
  AdvertisingData data;
  data.SetFlags(0x4);
  data.SetTxPower(4);
  data.SetAppearance(0x4567);
  EXPECT_TRUE(data.SetLocalName("fuchsia"));
  EXPECT_TRUE(data.AddUri("http://fuchsia.cl"));

  StaticByteBuffer bytes(0x01, 0x02, 0x03);
  EXPECT_TRUE(data.SetManufacturerData(0x0123, bytes.view()));

  auto service_uuid = UUID(kId1As16);
  EXPECT_TRUE(data.AddServiceUuid(service_uuid));

  StaticByteBuffer service_bytes(0x01, 0x02);
  EXPECT_TRUE(data.SetServiceData(service_uuid, service_bytes.view()));

  AdvertisingData new_data;
  new_data.SetTxPower(1);
  new_data.Copy(&data);

  EXPECT_EQ(1, data.tx_power().value());
  EXPECT_FALSE(data.appearance().has_value());
  EXPECT_FALSE(data.local_name().has_value());
  EXPECT_FALSE(data.flags().has_value());
  EXPECT_EQ(0u, data.uris().size());
  EXPECT_EQ(0u, data.manufacturer_data_ids().size());
  EXPECT_EQ(0u, data.service_uuids().size());
  EXPECT_EQ(0u, data.service_data_uuids().size());
}

TEST(AdvertisingDataTest, EncodeKnownURI) {
  AdvertisingData data;
  EXPECT_TRUE(data.AddUri("https://abc.xyz"));

  StaticByteBuffer bytes(
      0x0B, 0x24, 0x17, '/', '/', 'a', 'b', 'c', '.', 'x', 'y', 'z');

  EXPECT_EQ(bytes.size(), data.CalculateBlockSize());
  DynamicByteBuffer block(data.CalculateBlockSize());
  data.WriteBlock(&block, std::nullopt);
  EXPECT_TRUE(ContainersEqual(bytes, block));
}

TEST(AdvertisingDataTest, EncodeUnknownURI) {
  AdvertisingData data;
  EXPECT_TRUE(data.AddUri("flubs:xyz"));

  StaticByteBuffer bytes(
      0x0B, 0x24, 0x01, 'f', 'l', 'u', 'b', 's', ':', 'x', 'y', 'z');

  size_t block_size = data.CalculateBlockSize();
  EXPECT_EQ(bytes.size(), block_size);
  DynamicByteBuffer block(block_size);
  data.WriteBlock(&block, std::nullopt);
  EXPECT_TRUE(ContainersEqual(bytes, block));
}

TEST(AdvertisingDataTest, CompressServiceUUIDs) {
  AdvertisingData data;
  std::unordered_set<UUID> uuids{UUID(kId1As16), UUID(kId2As16)};
  for (auto& uuid : uuids) {
    SCOPED_TRACE(bt_str(uuid));
    EXPECT_TRUE(data.AddServiceUuid(uuid));
  }

  uint8_t expected_block_size = 1                          // length byte
                                + 1                        // type byte
                                + (sizeof(uint16_t) * 2);  // 2 16-bit UUIDs
  EXPECT_EQ(expected_block_size, data.CalculateBlockSize());

  StaticByteBuffer expected_header{expected_block_size - 1,
                                   DataType::kIncomplete16BitServiceUuids};

  DynamicByteBuffer block(expected_block_size);
  data.WriteBlock(&block, std::nullopt);

  EXPECT_TRUE(
      ContainersEqual(expected_header, block.view(/*pos=*/0, /*size=*/2)));
  auto to_uuid = [](const ByteBuffer& b, size_t pos) {
    return UUID(b.view(pos, /*size=*/2).To<uint16_t>());
  };
  EXPECT_TRUE(uuids.find(to_uuid(block, 2)) != uuids.end());
  EXPECT_TRUE(uuids.find(to_uuid(block, 4)) != uuids.end());
}

TEST(AdvertisingDataTest, ParseBlock) {
  StaticByteBuffer bytes(
      // Complete 16-bit UUIDs
      0x05,
      0x03,
      0x12,
      0x02,
      0x22,
      0x11,
      // Incomplete list of 32-bit UUIDs
      0x05,
      0x04,
      0x34,
      0x12,
      0x34,
      0x12,
      // Local name
      0x09,
      0x09,
      'T',
      'e',
      's',
      't',
      0xF0,
      0x9F,
      0x92,
      0x96,
      // TX Power
      0x02,
      0x0A,
      0x8F);

  AdvertisingData::ParseResult data = AdvertisingData::FromBytes(bytes);
  ASSERT_EQ(fit::ok(), data);

  EXPECT_EQ(3u, data->service_uuids().size());
  EXPECT_TRUE(data->local_name());
  EXPECT_EQ("Test💖", data->local_name()->name);
  EXPECT_TRUE(data->tx_power());
  EXPECT_EQ(-113, *(data->tx_power()));
}

TEST(AdvertisingDataTest, ParseBlockUnknownDataType) {
  AdvertisingData expected_ad;
  constexpr uint8_t lower_byte = 0x12, upper_byte = 0x22;
  constexpr uint16_t uuid_value = (upper_byte << 8) + lower_byte;
  // The only field present in the expected AD is one complete 16-bit UUID.
  EXPECT_TRUE(expected_ad.AddServiceUuid(UUID(uuid_value)));

  StaticByteBuffer bytes{// Complete 16-bit UUIDs
                         0x03,
                         0x03,
                         lower_byte,
                         upper_byte,
                         // 0x40, the second octet, is not a recognized DataType
                         // (see common/supplement_data.h).
                         0x05,
                         0x40,
                         0x34,
                         0x12,
                         0x34,
                         0x12};
  AdvertisingData::ParseResult data = AdvertisingData::FromBytes(bytes);
  ASSERT_EQ(fit::ok(), data);

  // The second field of `bytes` was valid (in that its length byte matched its
  // length), but its Data Type was unknown, so it should be ignored (i.e. the
  // only field in the `data` should be the single 16-bit UUID, matching
  // expected AD).
  EXPECT_EQ(expected_ad, *data);
}

TEST(AdvertisingDataTest, ParseBlockNameTooLong) {
  // A block with a name of exactly kMaxNameLength (==248) bytes should be
  // parsed correctly.
  {
    StaticByteBuffer<2> leading_bytes{kMaxNameLength + 1,
                                      DataType::kCompleteLocalName};
    auto bytes = DynamicByteBuffer(kMaxNameLength + 2);
    bytes.Write(leading_bytes);
    DynamicByteBuffer name(kMaxNameLength);
    name.Fill('a');
    bytes.Write(name, /*pos=*/2);
    AdvertisingData::ParseResult result = AdvertisingData::FromBytes(bytes);
    ASSERT_EQ(fit::ok(), result);
    EXPECT_EQ(result->local_name()->name, std::string(kMaxNameLength, 'a'));
  }
  // Repeat previous test with shortened name.
  {
    auto leading_bytes =
        StaticByteBuffer<2>{kMaxNameLength + 1, DataType::kShortenedLocalName};
    auto bytes = DynamicByteBuffer(kMaxNameLength + 2);
    bytes.Write(leading_bytes);
    DynamicByteBuffer name(kMaxNameLength);
    name.Fill('a');
    bytes.Write(name, /*pos=*/2);
    AdvertisingData::ParseResult result = AdvertisingData::FromBytes(bytes);
    ASSERT_EQ(fit::ok(), result);
    EXPECT_EQ(result->local_name()->name, std::string(kMaxNameLength, 'a'));
  }
  // A block with a name of kMaxNameLength+1 (==249) bytes should be rejected.
  {
    StaticByteBuffer<2> leading_bytes{kMaxNameLength + 2,
                                      DataType::kCompleteLocalName};
    auto bytes = DynamicByteBuffer(kMaxNameLength + 3);
    bytes.Write(leading_bytes);
    DynamicByteBuffer name(kMaxNameLength + 1);
    name.Fill('a');
    bytes.Write(name, /*pos=*/2);
    AdvertisingData::ParseResult result = AdvertisingData::FromBytes(bytes);
    ASSERT_TRUE(result.is_error());
    EXPECT_EQ(AdvertisingData::ParseError::kLocalNameTooLong,
              result.error_value());
  }
  // Repeat previous test with shortened name.
  {
    auto leading_bytes =
        StaticByteBuffer<2>{kMaxNameLength + 2, DataType::kShortenedLocalName};
    auto bytes = DynamicByteBuffer(kMaxNameLength + 3);
    bytes.Write(leading_bytes);
    DynamicByteBuffer name(kMaxNameLength + 1);
    name.Fill('a');
    bytes.Write(name, /*pos=*/2);
    AdvertisingData::ParseResult result = AdvertisingData::FromBytes(bytes);
    ASSERT_TRUE(result.is_error());
    EXPECT_EQ(AdvertisingData::ParseError::kLocalNameTooLong,
              result.error_value());
  }
}

TEST(AdvertisingDataTest, ManufacturerZeroLength) {
  StaticByteBuffer bytes(
      // Complete 16-bit UUIDs
      0x05,
      0x03,
      0x12,
      0x02,
      0x22,
      0x11,
      // Manufacturer Data with no data
      0x03,
      0xFF,
      0x34,
      0x12);

  EXPECT_EQ(0u, AdvertisingData().manufacturer_data_ids().size());

  AdvertisingData::ParseResult data = AdvertisingData::FromBytes(bytes);
  ASSERT_EQ(fit::ok(), data);

  EXPECT_EQ(1u, data->manufacturer_data_ids().count(0x1234));
  EXPECT_EQ(0u, data->manufacturer_data(0x1234).size());
}

TEST(AdvertisingDataTest, ServiceData) {
  // A typical Eddystone-URL beacon advertisement
  // to "https://fuchsia.cl"
  StaticByteBuffer bytes(
      // Complete 16-bit UUIDs, 0xFEAA
      0x03,
      0x03,
      0xAA,
      0xFE,
      // Eddystone Service (0xFEAA) Data:
      0x10,
      0x16,
      0xAA,
      0xFE,
      0x10,  // Eddystone-Uri type
      0xEE,  // TX Power level -18dBm
      0x03,  // "https://"
      'f',
      'u',
      'c',
      'h',
      's',
      'i',
      'a',
      '.',
      'c',
      'l');

  EXPECT_EQ(0u, AdvertisingData().service_data_uuids().size());

  AdvertisingData::ParseResult data = AdvertisingData::FromBytes(bytes);
  ASSERT_EQ(fit::ok(), data);

  UUID eddystone(uint16_t{0xFEAA});

  EXPECT_EQ(1u, data->service_data_uuids().size());
  EXPECT_EQ(13u, data->service_data(eddystone).size());

  EXPECT_TRUE(ContainersEqual(bytes.view(8), data->service_data(eddystone)));
}

// Per CSS v9 Part A 1.1.1, "A packet or data block shall not contain more than
// one instance for each Service UUID data size". We enforce this by failing to
// parse AdvertisingData with UUIDs of a particular size which exceed the amount
// that can fit in one TLV field.
TEST(AdvertisingDataTest, TooManyUuidsOfSizeRejected) {
  // Space for the maximum # of 16 bit UUIDs + length + type fields.
  const uint64_t kMaxAllowed16BitUuidsSize =
      (2 + kMax16BitUuids * UUIDElemSize::k16Bit);
  // Space for one more UUID + type and length fields
  const uint64_t kExpectedBuffSize =
      kMaxAllowed16BitUuidsSize + (2 + UUIDElemSize::k16Bit);

  DynamicByteBuffer bytes(kExpectedBuffSize);
  uint64_t offset = 0;
  // Write first TLV field with maximum # of UUIDs
  bytes.Write(StaticByteBuffer{
      kMax16BitUuids * UUIDElemSize::k16Bit + 1,                  // Size byte
      static_cast<uint8_t>(DataType::kComplete16BitServiceUuids)  // Type byte
  });
  offset += 2;
  for (uint16_t i = 0; i < kMax16BitUuids; ++i) {
    UUID uuid(static_cast<uint16_t>(i + 'a'));
    bytes.Write(uuid.CompactView(), offset);
    offset += uuid.CompactSize();
  }
  // Verify that we successfully parse an AD with the maximum amount of 16 bit
  // UUIDs
  AdvertisingData::ParseResult adv_result = AdvertisingData::FromBytes(
      bytes.view(/*pos=*/0, /*size=*/kMaxAllowed16BitUuidsSize));
  ASSERT_EQ(fit::ok(), adv_result);
  EXPECT_EQ(kMax16BitUuids, adv_result->service_uuids().size());
  // Write second Complete 16 bit Service UUIDs TLV field with one more UUID
  bytes.Write(
      StaticByteBuffer{
          UUIDElemSize::k16Bit + 1,  // Size byte
          static_cast<uint8_t>(
              DataType::kComplete16BitServiceUuids)  // Type byte
      },
      offset);
  offset += 2;
  UUID uuid(static_cast<uint16_t>(kMax16BitUuids + 'a'));
  bytes.Write(uuid.CompactView(), offset);

  adv_result = AdvertisingData::FromBytes(bytes);
  ASSERT_TRUE(adv_result.is_error());
  EXPECT_EQ(AdvertisingData::ParseError::kUuidsMalformed,
            adv_result.error_value());
}

TEST(AdvertisingDataTest, Missing) {
  AdvertisingData::ParseResult result =
      AdvertisingData::FromBytes(DynamicByteBuffer());
  ASSERT_TRUE(result.is_error());
  EXPECT_EQ(AdvertisingData::ParseError::kMissing, result.error_value());
}

TEST(AdvertisingDataTest, InvalidTlvFormat) {
  AdvertisingData::ParseResult result =
      AdvertisingData::FromBytes(StaticByteBuffer(0x03));
  ASSERT_TRUE(result.is_error());
  EXPECT_EQ(AdvertisingData::ParseError::kInvalidTlvFormat,
            result.error_value());
}

TEST(AdvertisingDataTest, TxPowerLevelMalformed) {
  StaticByteBuffer service_data{/*length=*/0x01,
                                static_cast<uint8_t>(DataType::kTxPowerLevel)};
  AdvertisingData::ParseResult result =
      AdvertisingData::FromBytes(service_data);
  ASSERT_TRUE(result.is_error());
  EXPECT_EQ(AdvertisingData::ParseError::kTxPowerLevelMalformed,
            result.error_value());
}

TEST(AdvertisingDataTest, UuidsMalformed) {
  StaticByteBuffer service_data{
      0x02,  // Length
      static_cast<uint8_t>(DataType::kComplete16BitServiceUuids),
      0x12  // The length of a valid 16-bit UUID byte array be a multiple of 2
            // (and 1 % 2 == 1).
  };
  AdvertisingData::ParseResult result =
      AdvertisingData::FromBytes(service_data);
  ASSERT_TRUE(result.is_error());
  EXPECT_EQ(AdvertisingData::ParseError::kUuidsMalformed, result.error_value());
}

TEST(AdvertisingDataTest, ManufacturerSpecificDataTooSmall) {
  StaticByteBuffer service_data{
      0x02,  // Length
      static_cast<uint8_t>(DataType::kManufacturerSpecificData),
      0x12  // Manufacturer-specific data must be at least 2 bytes
  };
  AdvertisingData::ParseResult result =
      AdvertisingData::FromBytes(service_data);
  ASSERT_TRUE(result.is_error());
  EXPECT_EQ(AdvertisingData::ParseError::kManufacturerSpecificDataTooSmall,
            result.error_value());
}

TEST(AdvertisingDataTest, DecodeServiceDataWithIncompleteUuid) {
  StaticByteBuffer service_data(
      0x02,                                               // Length
      static_cast<uint8_t>(DataType::kServiceData16Bit),  // Data type
      0xAA  // First byte of incomplete UUID
  );

  AdvertisingData::ParseResult result =
      AdvertisingData::FromBytes(service_data);
  ASSERT_TRUE(result.is_error());
  EXPECT_EQ(AdvertisingData::ParseError::kServiceDataTooSmall,
            result.error_value());
}

TEST(AdvertisingDataTest, AppearanceMalformed) {
  StaticByteBuffer service_data{
      0x02,  // Length
      static_cast<uint8_t>(DataType::kAppearance),
      0x12  // Appearance is supposed to be 2 bytes
  };
  AdvertisingData::ParseResult result =
      AdvertisingData::FromBytes(service_data);
  ASSERT_TRUE(result.is_error());
  EXPECT_EQ(AdvertisingData::ParseError::kAppearanceMalformed,
            result.error_value());
}
TEST(AdvertisingDataTest, Equality) {
  AdvertisingData one, two;

  UUID gatt(kGattUuid);
  UUID eddy(kEddystoneUuid);

  // Service UUIDs
  EXPECT_EQ(two, one);
  EXPECT_TRUE(one.AddServiceUuid(gatt));
  EXPECT_NE(two, one);
  EXPECT_TRUE(two.AddServiceUuid(gatt));
  EXPECT_EQ(two, one);

  // Even when the bytes are the same but from different places
  StaticByteBuffer bytes(0x01, 0x02, 0x03, 0x04);
  StaticByteBuffer same(0x01, 0x02, 0x03, 0x04);
  EXPECT_TRUE(two.SetManufacturerData(0x0123, bytes.view()));
  EXPECT_NE(two, one);
  EXPECT_TRUE(one.SetManufacturerData(0x0123, same.view()));
  EXPECT_EQ(two, one);

  // When TX Power is different
  two.SetTxPower(-34);
  EXPECT_NE(two, one);
  one.SetTxPower(-30);
  EXPECT_NE(two, one);
  one.SetTxPower(-34);
  EXPECT_EQ(two, one);

  // Even if the fields were added in different orders
  AdvertisingData three, four;
  EXPECT_TRUE(three.AddServiceUuid(eddy));
  EXPECT_TRUE(three.AddServiceUuid(gatt));
  EXPECT_NE(three, four);

  EXPECT_TRUE(four.AddServiceUuid(gatt));
  EXPECT_TRUE(four.AddServiceUuid(eddy));
  EXPECT_EQ(three, four);
}

TEST(AdvertisingDataTest, ToString) {
  AdvertisingData data;

  AdvFlags flags = kLEGeneralDiscoverableMode | kBREDRNotSupported;
  data.SetFlags(flags);
  data.SetTxPower(-18);
  data.SetAppearance(0x4567);
  EXPECT_TRUE(data.SetLocalName("fuchsia"));
  EXPECT_TRUE(data.AddUri("http://fuchsia.cl"));

  uint32_t service_uuid_32 = 0x12345678;
  UUID service_uuid_32bit = UUID(service_uuid_32);
  UUID service_uuid_16bit = UUID(kId1As16);
  EXPECT_TRUE(data.AddServiceUuid(service_uuid_32bit));
  EXPECT_TRUE(data.AddServiceUuid(service_uuid_16bit));

  StaticByteBuffer service_bytes(0x01, 0x02);
  EXPECT_TRUE(data.SetServiceData(service_uuid_16bit, service_bytes.view()));

  StaticByteBuffer bytes(0x01, 0x02, 0x03);
  EXPECT_TRUE(data.SetManufacturerData(0x0123, bytes.view()));

  EXPECT_EQ(
      "Advertising Data { Complete Name: fuchsia, TX Power: -18, Appearance: 0x4567, URIs: { http://fuchsia.cl, }, Flags: { LE General Discoverable Mode, BR/EDR Not Supported, }, Service UUIDs: { 00000212-0000-1000-8000-00805f9b34fb, 12345678-0000-1000-8000-00805f9b34fb, }, Service Data: { { UUID:00000212-0000-1000-8000-00805f9b34fb, Data: {01 02} }, }, Manufacturer Data: { { Company ID: 0x0123, Data: {01 02 03} }, } }",
      data.ToString());
}

TEST(AdvertisingDataTest, ToStringHasEmptyFields) {
  AdvertisingData data;

  EXPECT_EQ("Advertising Data { }", data.ToString());
}

TEST(AdvertisingDataTest, Copy) {
  UUID gatt(kGattUuid);
  UUID eddy(kEddystoneUuid);
  StaticByteBuffer<kRandomDataSize> rand_data;
  random_generator()->Get(rand_data.mutable_subspan());

  AdvertisingData source;
  EXPECT_TRUE(source.AddUri("http://fuchsia.cl"));
  EXPECT_TRUE(source.AddUri("https://ru.st"));
  EXPECT_TRUE(source.SetManufacturerData(0x0123, rand_data.view()));
  EXPECT_TRUE(source.AddServiceUuid(gatt));
  EXPECT_TRUE(source.AddServiceUuid(eddy));

  AdvertisingData dest;
  source.Copy(&dest);

  EXPECT_EQ(source, dest);

  // Modifying the source shouldn't mess with the copy
  EXPECT_TRUE(source.SetLocalName("fuchsia"));
  EXPECT_FALSE(dest.local_name());

  StaticByteBuffer bytes(0x01, 0x02, 0x03);
  EXPECT_TRUE(source.SetManufacturerData(0x0123, bytes.view()));
  EXPECT_TRUE(ContainersEqual(rand_data, dest.manufacturer_data(0x0123)));
}

TEST(AdvertisingDataTest, Move) {
  UUID gatt(kGattUuid);
  UUID eddy(kEddystoneUuid);
  StaticByteBuffer<kRandomDataSize> rand_data;
  random_generator()->Get(rand_data.mutable_subspan());

  UUID heart_rate_uuid(kHeartRateServiceUuid);
  int8_t tx_power = 18;          // arbitrary TX power
  uint16_t appearance = 0x4567;  // arbitrary appearance value
  uint8_t flags = 0x48;          // arbitrary flags value
  AdvertisingData source;
  EXPECT_TRUE(source.SetLocalName("test"));
  source.SetFlags(flags);
  source.SetTxPower(tx_power);
  source.SetAppearance(appearance);
  EXPECT_TRUE(source.AddUri("http://fuchsia.cl"));
  EXPECT_TRUE(source.AddUri("https://ru.st"));
  EXPECT_TRUE(source.SetManufacturerData(0x0123, rand_data.view()));
  EXPECT_TRUE(source.AddServiceUuid(gatt));
  EXPECT_TRUE(source.AddServiceUuid(eddy));
  EXPECT_TRUE(source.SetServiceData(heart_rate_uuid, rand_data.view()));

  auto verify_advertising_data = [&](const AdvertisingData& dest,
                                     const char* type) {
    SCOPED_TRACE(type);
    // Dest should have the data we set.
    EXPECT_EQ("test", dest.local_name()->name);
    EXPECT_EQ(tx_power, dest.tx_power().value());
    EXPECT_EQ(appearance, dest.appearance().value());
    EXPECT_EQ(
        std::unordered_set<std::string>({"http://fuchsia.cl", "https://ru.st"}),
        dest.uris());
    EXPECT_TRUE(ContainersEqual(rand_data, dest.manufacturer_data(0x0123)));
    EXPECT_EQ(std::unordered_set<UUID>({gatt, eddy}), dest.service_uuids());
    EXPECT_TRUE(ContainersEqual(rand_data, dest.service_data(heart_rate_uuid)));
    EXPECT_EQ(flags, dest.flags().value());
  };

  AdvertisingData move_constructed(std::move(source));

  // source should be empty.
  EXPECT_EQ(AdvertisingData(), source);
  verify_advertising_data(move_constructed, "move_constructed");

  AdvertisingData move_assigned{};
  move_assigned = std::move(move_constructed);
  EXPECT_EQ(AdvertisingData(), move_constructed);
  verify_advertising_data(move_assigned, "move_assigned");
}

TEST(AdvertisingDataTest, Flags) {
  // A zero-byte flags is allowed, and sets the flags field to zeroes.
  StaticByteBuffer flags_empty(0x01, DataType::kFlags);
  // Extra bytes are accepted but ignored.
  StaticByteBuffer flags_extra(0x04, DataType::kFlags, 0x03, 0x42, 0x49);

  AdvertisingData::ParseResult data = AdvertisingData::FromBytes(flags_empty);
  ASSERT_EQ(fit::ok(), data);
  ASSERT_TRUE(data->flags().has_value());
  ASSERT_EQ(0x00, data->flags().value());

  data = AdvertisingData::FromBytes(flags_extra);
  ASSERT_EQ(fit::ok(), data);
  ASSERT_TRUE(data->flags().has_value());
  ASSERT_EQ(0x03, data->flags().value());
}

TEST(AdvertisingDataTest, Uris) {
  // The encoding scheme is represented by the first UTF-8 code-point in the URI
  // string. Per
  // https://www.bluetooth.com/specifications/assigned-numbers/uri-scheme-name-string-mapping/,
  // 0xBA is the highest code point corresponding to an encoding scheme.
  // However, 0xBA > 0x7F, so representing too-large encoding schemes (i.e.
  // code-points > 0xBA) in UTF-8 requires two bytes.
  const uint8_t kLargestKnownSchemeByte1 = 0xC2,
                kLargestKnownSchemeByte2 = 0xBA;
  // These bytes represent the (valid) UTF-8 code point for the (unknown
  // encoding scheme) U+00BB.
  const uint8_t kUnknownSchemeByte1 = 0xC2, kUnknownSchemeByte2 = 0xBB;
  StaticByteBuffer bytes(
      // Uri: "https://abc.xyz"
      0x0B,
      DataType::kURI,
      0x17,
      '/',
      '/',
      'a',
      'b',
      'c',
      '.',
      'x',
      'y',
      'z',
      // Empty URI should be ignored:
      0x01,
      DataType::kURI,
      // Uri: "flubs:abc"
      0x0B,
      DataType::kURI,
      0x01,
      'f',
      'l',
      'u',
      'b',
      's',
      ':',
      'a',
      'b',
      'c',
      // Uri: "ms-settings-cloudstorage:flub"
      0x07,
      DataType::kURI,
      kLargestKnownSchemeByte1,
      kLargestKnownSchemeByte2,
      'f',
      'l',
      'u',
      'b',
      // Invalid URI should be ignored - UTF-8 U+00BB doesn't correspond to an
      // encoding scheme.
      0x07,
      DataType::kURI,
      kUnknownSchemeByte1,
      kUnknownSchemeByte2,
      'f',
      'l',
      'u',
      'b',
      // Invalid URI should be ignored - UTF-8 U+0000 doesn't correspond to an
      // encoding scheme.
      0x03,
      DataType::kURI,
      0x00,
      0x00);

  AdvertisingData::ParseResult data = AdvertisingData::FromBytes(bytes);
  ASSERT_EQ(fit::ok(), data);

  auto uris = data->uris();
  EXPECT_EQ(3u, uris.size());

  EXPECT_TRUE(std::find(uris.begin(), uris.end(), "https://abc.xyz") !=
              uris.end());
  EXPECT_TRUE(std::find(uris.begin(), uris.end(), "flubs:abc") != uris.end());
  EXPECT_TRUE(std::find(uris.begin(),
                        uris.end(),
                        "ms-settings-cloudstorage:flub") != uris.end());
}

// Tests writing a fully populated |AdvertisingData| to
// an output buffer succeeds.
TEST(AdvertisingDataTest, WriteBlockSuccess) {
  AdvertisingData data;

  data.SetTxPower(4);
  data.SetAppearance(0x4567);
  EXPECT_TRUE(data.SetLocalName("fuchsia"));

  StaticByteBuffer bytes(0x01, 0x02, 0x03);
  EXPECT_TRUE(data.SetManufacturerData(0x0123, bytes.view()));

  auto service_uuid = UUID(kId1As16);
  StaticByteBuffer service_bytes(0x01, 0x02);
  EXPECT_TRUE(data.AddServiceUuid(service_uuid));
  EXPECT_TRUE(data.SetServiceData(service_uuid, service_bytes.view()));

  EXPECT_TRUE(data.AddUri("http://fuchsia.cl"));

  DynamicByteBuffer write_buf(data.CalculateBlockSize());
  EXPECT_TRUE(data.WriteBlock(&write_buf, std::nullopt));

  StaticByteBuffer expected_buf(0x02,
                                0x0a,
                                0x04,  // tx_power_level_: 4
                                0x03,
                                0x19,
                                0x67,
                                0x45,  // appearance_: 0x4567
                                0x08,
                                0x09,
                                0x66,
                                0x75,
                                0x63,
                                0x68,
                                0x73,
                                0x69,
                                0x61,  // local_name_: "fuchsia"
                                0x06,
                                0xff,
                                0x23,
                                0x01,
                                0x01,
                                0x02,
                                0x03,  // manufacturer_data_
                                0x05,
                                0x16,
                                0x12,
                                0x02,
                                0x01,
                                0x02,  // service_data_
                                0x0e,
                                0x24,
                                0x16,
                                0x2f,
                                0x2f,
                                0x66,
                                0x75,
                                0x63,
                                0x68,
                                0x73,
                                0x69,
                                0x61,
                                0x2e,
                                0x63,
                                0x6c,
                                0x03,
                                0x02,
                                0x12,
                                0x02);  // uris_
  EXPECT_TRUE(ContainersEqual(expected_buf, write_buf));
}

// Tests writing |AdvertisingData| to an output buffer that
// is too small fails gracefully and returns early.
TEST(AdvertisingDataTest, WriteBlockSmallBufError) {
  AdvertisingData data;

  data.SetTxPower(4);
  data.SetAppearance(0x4567);
  EXPECT_TRUE(data.SetLocalName("fuchsia"));

  DynamicByteBuffer write_buf(data.CalculateBlockSize() - 1);
  // The buffer is too small. No write should occur, and should return false.
  EXPECT_FALSE(data.WriteBlock(&write_buf, std::nullopt));
}

// Tests writing a fully populated |AdvertisingData| with provided flags to
// an output buffer succeeds.
TEST(AdvertisingDataTest, WriteBlockWithFlagsSuccess) {
  AdvertisingData data;

  data.SetTxPower(4);
  data.SetAppearance(0x4567);
  EXPECT_TRUE(data.SetLocalName("fuchsia"));

  StaticByteBuffer bytes(0x01, 0x02, 0x03);
  EXPECT_TRUE(data.SetManufacturerData(0x0123, bytes.view()));

  auto service_uuid = UUID(kId1As16);
  StaticByteBuffer service_bytes(0x01, 0x02);
  EXPECT_TRUE(data.AddServiceUuid(service_uuid));
  EXPECT_TRUE(data.SetServiceData(service_uuid, service_bytes.view()));

  EXPECT_TRUE(data.AddUri("http://fuchsia.cl"));

  DynamicByteBuffer write_buf(data.CalculateBlockSize(/*include_flags=*/true));
  EXPECT_TRUE(data.WriteBlock(&write_buf, AdvFlag::kLEGeneralDiscoverableMode));

  StaticByteBuffer expected_buf(0x02,
                                0x01,
                                0x02,  // flags: 2
                                0x02,
                                0x0a,
                                0x04,  // tx_power_level_: 4
                                0x03,
                                0x19,
                                0x67,
                                0x45,  // appearance_: 0x4567
                                0x08,
                                0x09,
                                0x66,
                                0x75,
                                0x63,
                                0x68,
                                0x73,
                                0x69,
                                0x61,  // local_name_: "fuchsia"
                                0x06,
                                0xff,
                                0x23,
                                0x01,
                                0x01,
                                0x02,
                                0x03,  // manufacturer_data_
                                0x05,
                                0x16,
                                0x12,
                                0x02,
                                0x01,
                                0x02,  // service_data_
                                0x0e,
                                0x24,
                                0x16,
                                0x2f,
                                0x2f,
                                0x66,
                                0x75,
                                0x63,
                                0x68,
                                0x73,
                                0x69,
                                0x61,
                                0x2e,
                                0x63,
                                0x6c,
                                0x03,
                                0x02,
                                0x12,
                                0x02);  // uris_
  EXPECT_TRUE(ContainersEqual(expected_buf, write_buf));
}

TEST(AdvertisingDataTest, WriteBlockWithFlagsBufError) {
  AdvertisingData data;

  data.SetTxPower(6);
  EXPECT_TRUE(data.SetLocalName("Fuchsia"));
  data.SetAppearance(0x1234);

  DynamicByteBuffer write_buf(data.CalculateBlockSize(/*include_flags=*/true) -
                              1);
  EXPECT_FALSE(
      data.WriteBlock(&write_buf, AdvFlag::kLEGeneralDiscoverableMode));
}

// Adds `n_(consecutively_increasing)_uuids` to `input` and returns the "next"
// UUID in the sequence. UUIDs may wrap around - this is OK, as we only care
// that they are all distinct.
UUID AddNDistinctUuids(AdvertisingData& input,
                       std::variant<uint16_t, uint32_t, UInt128> starting_uuid,
                       uint8_t n_uuids) {
  UUID next;
  for (uint8_t i = 0; true; ++i) {
    std::visit(
        [&](auto arg) {
          using T = std::decay_t<decltype(arg)>;
          if constexpr (std::is_same_v<T, UInt128>) {
            arg[0] += i;
            next = UUID(arg);
          } else {
            next = UUID(static_cast<T>(arg + i));
          }
        },
        starting_uuid);
    SCOPED_TRACE(
        bt_lib_cpp_string::StringPrintf("i: %du UUID: %s", i, bt_str(next)));
    if (i >= n_uuids) {
      return next;
    }
    EXPECT_TRUE(input.AddServiceUuid(next));
  }
}

TEST(AdvertisingDataTest, SetFieldsWithTooLongParameters) {
  AdvertisingData data;
  {
    // Use the https URI encoding scheme. This prefix will be compressed to one
    // byte when encoded.
    std::string uri = "https:";
    uri += std::string(kMaxEncodedUriLength - 1, '.');
    EXPECT_TRUE(data.AddUri(uri));
    uri += '.';
    EXPECT_FALSE(data.AddUri(uri));
  }
  // Attempt to set slightly too long service data.
  {
    UUID two_byte_uuid{kHeartRateServiceUuid};
    DynamicByteBuffer long_data(kMaxEncodedServiceDataLength - 1);
    long_data.Fill(0xAB);
    EXPECT_FALSE(data.SetServiceData(two_byte_uuid, long_data));
    // An empty DynamicByteBuffer represents unset service data per the header.
    EXPECT_TRUE(
        ContainersEqual(DynamicByteBuffer(), data.service_data(two_byte_uuid)));
    // Now use a view that is just small enough to fit when encoded
    BufferView view = long_data.view(/*pos=*/0, /*size=*/long_data.size() - 1);
    EXPECT_TRUE(data.SetServiceData(two_byte_uuid, view));
    EXPECT_TRUE(ContainersEqual(view, data.service_data(two_byte_uuid)));
  }
  // Attempt to set slightly too long manufacturer data.
  {
    uint16_t manufacturer_id{0xABBA};
    DynamicByteBuffer long_data(kMaxManufacturerDataLength + 1);
    long_data.Fill(0xAB);
    EXPECT_FALSE(data.SetManufacturerData(manufacturer_id, long_data.view()));
    // An empty DynamicByteBuffer represents unset service data per the header.
    EXPECT_TRUE(ContainersEqual(DynamicByteBuffer(),
                                data.manufacturer_data(manufacturer_id)));
    // Now use a view that is just small enough to fit when encoded
    BufferView view = long_data.view(/*pos=*/0, /*size=*/long_data.size() - 1);
    EXPECT_TRUE(data.SetManufacturerData(manufacturer_id, view));
    EXPECT_TRUE(ContainersEqual(view, data.manufacturer_data(manufacturer_id)));
  }
  // Ensure that service UUIDs are truncated when they do not fit.
  {
    uint16_t starting_16bit_uuid = 0x0001;
    UUID should_fail = AddNDistinctUuids(
        data,
        std::variant<uint16_t, uint32_t, UInt128>{starting_16bit_uuid},
        kMax16BitUuids);
    EXPECT_FALSE(data.AddServiceUuid(should_fail));
    EXPECT_TRUE(data.service_uuids().find(should_fail) ==
                data.service_uuids().end());

    // This value must not fit in a 16 bit number in order to count as a "32
    // bit" UUID
    uint32_t starting_32bit_uuid = std::numeric_limits<uint16_t>::max() + 1;
    should_fail = AddNDistinctUuids(
        data,
        std::variant<uint16_t, uint32_t, UInt128>{starting_32bit_uuid},
        kMax32BitUuids);
    EXPECT_FALSE(data.AddServiceUuid(should_fail));
    EXPECT_TRUE(data.service_uuids().find(should_fail) ==
                data.service_uuids().end());

    UInt128 starting_128bit_uuid = {0xAB,
                                    0xAB,
                                    0xAB,
                                    0xAB,
                                    0xAB,
                                    0xAB,
                                    0xAB,
                                    0xAB,
                                    0xAB,
                                    0xAB,
                                    0xAB,
                                    0xAB,
                                    0xAB,
                                    0xAB,
                                    0xAB,
                                    0xAB};
    should_fail = AddNDistinctUuids(
        data,
        std::variant<uint16_t, uint32_t, UInt128>{starting_128bit_uuid},
        kMax128BitUuids);
    EXPECT_FALSE(data.AddServiceUuid(should_fail));
    EXPECT_TRUE(data.service_uuids().find(should_fail) ==
                data.service_uuids().end());
  }
  // Ensures names exceeding kMaxNameLength are rejected.
  {
    std::string name_that_fits(kMaxNameLength, 'a');
    std::string too_long_name(kMaxNameLength + 1, 'b');
    EXPECT_TRUE(data.SetLocalName(name_that_fits));
    EXPECT_EQ(name_that_fits, data.local_name()->name);
    EXPECT_FALSE(data.SetLocalName(too_long_name));
    EXPECT_EQ(name_that_fits, data.local_name()->name);
  }
  // Write the data out to ensure no assertions are triggered
  DynamicByteBuffer block(data.CalculateBlockSize());
  EXPECT_TRUE(data.WriteBlock(&block, std::nullopt));
}

// Tests that setting a complete local name overwrites an existing shortened
// local name and that setting a shortened local name has no effect if a
// complete local name is currently stored.
TEST(AdvertisingDataTest, CompleteLocalNameFavored) {
  AdvertisingData data;
  std::string short_name = "short";
  std::string complete_name = "complete";

  EXPECT_TRUE(data.SetLocalName(short_name, /*is_complete=*/false));
  EXPECT_EQ(short_name, data.local_name()->name);
  EXPECT_TRUE(data.SetLocalName(complete_name, /*is_complete=*/true));
  EXPECT_EQ(complete_name, data.local_name()->name);

  EXPECT_FALSE(data.SetLocalName(short_name, /*is_complete=*/false));
  EXPECT_EQ(complete_name, data.local_name()->name);
}

// Tests that even when the maximum number of distinct UUIDs for a certain size
// have been added to an AD, we do not reject additional UUIDs that are
// duplicates of already-added UUIDs.
TEST(AdvertisingDataTest, AddDuplicateServiceUuidsWhenFullSucceeds) {
  AdvertisingData data;
  uint16_t starting_16bit_uuid = 0x0001;
  UUID should_fail = AddNDistinctUuids(
      data,
      std::variant<uint16_t, uint32_t, UInt128>{starting_16bit_uuid},
      kMax16BitUuids);
  // Verify that adding another distinct UUID fails - i.e. we are at the limit.
  EXPECT_FALSE(data.AddServiceUuid(should_fail));
  EXPECT_TRUE(data.service_uuids().find(should_fail) ==
              data.service_uuids().end());
  // Verify that we are notified of success when adding an existing UUID
  EXPECT_TRUE(data.AddServiceUuid(UUID(starting_16bit_uuid)));
}
}  // namespace
}  // namespace bt
