// 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/gap/advertising_data.h"

#include "gtest/gtest.h"
#include "src/connectivity/bluetooth/core/bt-host/common/byte_buffer.h"
#include "src/connectivity/bluetooth/core/bt-host/common/test_helpers.h"

namespace bt {
namespace gap {
namespace {

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

constexpr uint16_t kId1As16 = 0x0212;
constexpr char kId1AsString[] = "00000212-0000-1000-8000-00805f9b34fb";
constexpr uint16_t kId2As16 = 0x1122;

constexpr char kId3AsString[] = "12341234-0000-1000-8000-00805f9b34fb";

constexpr size_t kRandomDataSize = 100;

TEST(GAP_AdvertisingDataTest, ReaderEmptyData) {
  BufferView empty;
  AdvertisingDataReader reader(empty);
  EXPECT_FALSE(reader.is_valid());
  EXPECT_FALSE(reader.HasMoreData());
}

TEST(GAP_AdvertisingDataTest, MakeEmpty) {
  AdvertisingData data;

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

TEST(GAP_AdvertisingDataTest, EncodeKnownURI) {
  AdvertisingData data;
  data.AddURI("https://abc.xyz");

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

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

TEST(GAP_AdvertisingDataTest, EncodeUnknownURI) {
  AdvertisingData data;
  data.AddURI("flubs:xyz");

  auto bytes = CreateStaticByteBuffer(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);
  EXPECT_TRUE(ContainersEqual(bytes, block));
}

TEST(GAP_AdvertisingDataTest, CompressServiceUUIDs) {
  AdvertisingData data;
  data.AddServiceUuid(UUID(kId1As16));
  data.AddServiceUuid(UUID(kId2As16));

  EXPECT_EQ(1 + 1 + (sizeof(uint16_t) * 2), data.CalculateBlockSize());

  auto bytes = CreateStaticByteBuffer(0x05, 0x02, 0x12, 0x02, 0x22, 0x11);

  size_t block_size = data.CalculateBlockSize();
  EXPECT_EQ(bytes.size(), block_size);
  DynamicByteBuffer block(block_size);
  data.WriteBlock(&block);

  EXPECT_TRUE(ContainersEqual(bytes, block));
}

TEST(GAP_AdvertisingDataTest, ParseBlock) {
  auto bytes = CreateStaticByteBuffer(
      // 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 data;

  EXPECT_TRUE(AdvertisingData::FromBytes(bytes, &data));

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

TEST(GAP_AdvertisingDataTest, ParseFIDL) {
  fuchsia::bluetooth::le::AdvertisingData fidl_ad;

  // Confirming UTF-8 codepoints are working as well.
  fidl_ad.name = "Test💖";
  fidl_ad.service_uuids.push_back(kId1AsString);
  fidl_ad.service_uuids.push_back(kId3AsString);

  auto svc_data = fidl::VectorPtr<uint8_t>::New(4);
  for (size_t i = 0; i < svc_data->size(); i++) {
    svc_data->at(i) = static_cast<uint8_t>(i * 3);
  }

  fuchsia::bluetooth::le::ServiceDataEntry service_data_entry;
  service_data_entry.uuid = kId1AsString;
  service_data_entry.data = std::move(svc_data);
  fidl_ad.service_data.push_back(std::move(service_data_entry));

  AdvertisingData data;

  EXPECT_TRUE(AdvertisingData::FromFidl(fidl_ad, &data));

  ASSERT_EQ(2u, data.service_uuids().size());
  EXPECT_EQ("Test💖", *(data.local_name()));

  UUID uuid1(kId1As16);
  EXPECT_EQ(1u, data.service_data_uuids().size());
  EXPECT_EQ(4u, data.service_data(uuid1).size());

  EXPECT_FALSE(data.tx_power());
}

TEST(GAP_AdvertisingDataTest, ParseFIDLFailsWithMalformedUuid) {
  fuchsia::bluetooth::le::AdvertisingData fidl_ad;
  fidl_ad.service_uuids.push_back("12");

  AdvertisingData data;
  EXPECT_FALSE(AdvertisingData::FromFidl(fidl_ad, &data));
}

TEST(GAP_AdvertisingDataTest, ParseFIDLFailsWithMalformedServiceDataUuid) {
  fuchsia::bluetooth::le::AdvertisingData fidl_ad;

  auto svc_data = fidl::VectorPtr<uint8_t>::New(1);

  fuchsia::bluetooth::le::ServiceDataEntry service_data_entry;
  service_data_entry.uuid = "12";
  service_data_entry.data = std::move(svc_data);
  fidl_ad.service_data.push_back(std::move(service_data_entry));

  AdvertisingData data;
  EXPECT_FALSE(AdvertisingData::FromFidl(fidl_ad, &data));
}

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

  AdvertisingData data;

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

  EXPECT_TRUE(AdvertisingData::FromBytes(bytes, &data));

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

TEST(GAP_AdvertisingDataTest, ServiceData) {
  // A typical Eddystone-URL beacon advertisement
  // to "https://fuchsia.cl"
  auto bytes = CreateStaticByteBuffer(
      // 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');

  AdvertisingData data;
  UUID eddystone((uint16_t)0xFEAA);

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

  EXPECT_TRUE(AdvertisingData::FromBytes(bytes, &data));

  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)));
}

TEST(GAP_AdvertisingDataTest, Equality) {
  AdvertisingData one, two;

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

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

  // Even when the bytes are the same but from different places
  auto bytes = CreateStaticByteBuffer(0x01, 0x02, 0x03, 0x04);
  auto same = CreateStaticByteBuffer(0x01, 0x02, 0x03, 0x04);
  two.SetManufacturerData(0x0123, bytes.view());
  EXPECT_NE(two, one);
  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;
  three.AddServiceUuid(eddy);
  three.AddServiceUuid(gatt);
  EXPECT_NE(three, four);

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

TEST(GAP_AdvertisingDataTest, Copy) {
  UUID gatt(kGattUuid);
  UUID eddy(kEddystoneUuid);
  StaticByteBuffer<kRandomDataSize> rand_data;
  rand_data.FillWithRandomBytes();

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

  AdvertisingData dest;
  source.Copy(&dest);

  EXPECT_EQ(source, dest);

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

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

TEST(GAP_AdvertisingDataTest, Move) {
  UUID gatt(kGattUuid);
  UUID eddy(kEddystoneUuid);
  StaticByteBuffer<kRandomDataSize> rand_data;
  rand_data.FillWithRandomBytes();

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

  AdvertisingData dest = std::move(source);

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

  // Dest should have the data we set.
  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());
}

TEST(GAP_AdvertisingDataTest, Uris) {
  auto bytes = CreateStaticByteBuffer(
      // Uri: "https://abc.xyz"
      0x0B, 0x24, 0x17, '/', '/', 'a', 'b', 'c', '.', 'x', 'y', 'z',
      // Uri: "flubs:abc"
      0x0B, 0x24, 0x01, 'f', 'l', 'u', 'b', 's', ':', 'a', 'b', 'c');

  AdvertisingData data;
  EXPECT_TRUE(AdvertisingData::FromBytes(bytes, &data));

  auto uris = data.uris();
  EXPECT_EQ(2u, 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());
}

TEST(GAP_AdvertisingDataTest, ReaderMalformedData) {
  // TLV length exceeds the size of the payload
  auto bytes0 = CreateStaticByteBuffer(0x01);
  AdvertisingDataReader reader(bytes0);
  EXPECT_FALSE(reader.is_valid());
  EXPECT_FALSE(reader.HasMoreData());

  auto bytes = CreateStaticByteBuffer(0x05, 0x00, 0x00, 0x00, 0x00);
  reader = AdvertisingDataReader(bytes);
  EXPECT_FALSE(reader.is_valid());
  EXPECT_FALSE(reader.HasMoreData());

  // TLV length is 0. This is not considered malformed. Data should be valid but
  // should not return more data.
  bytes = CreateStaticByteBuffer(0x00, 0x00, 0x00, 0x00, 0x00);
  reader = AdvertisingDataReader(bytes);
  EXPECT_TRUE(reader.is_valid());
  EXPECT_FALSE(reader.HasMoreData());

  // First field is valid, second field is not.
  DataType type;
  BufferView data;
  bytes = CreateStaticByteBuffer(0x02, 0x00, 0x00, 0x02, 0x00);
  reader = AdvertisingDataReader(bytes);
  EXPECT_FALSE(reader.is_valid());
  EXPECT_FALSE(reader.HasMoreData());
  EXPECT_FALSE(reader.GetNextField(&type, &data));

  // First field is valid, second field has length 0.
  bytes = CreateStaticByteBuffer(0x02, 0x00, 0x00, 0x00, 0x00);
  reader = AdvertisingDataReader(bytes);
  EXPECT_TRUE(reader.is_valid());
  EXPECT_TRUE(reader.HasMoreData());
  EXPECT_TRUE(reader.GetNextField(&type, &data));
  EXPECT_FALSE(reader.HasMoreData());
  EXPECT_FALSE(reader.GetNextField(&type, &data));
}

TEST(GAP_AdvertisingDataTest, ReaderParseFields) {
  auto bytes =
      CreateStaticByteBuffer(0x02, 0x01, 0x00, 0x05, 0x09, 'T', 'e', 's', 't');
  AdvertisingDataReader reader(bytes);
  EXPECT_TRUE(reader.is_valid());
  EXPECT_TRUE(reader.HasMoreData());

  DataType type;
  BufferView data;
  EXPECT_TRUE(reader.GetNextField(&type, &data));
  EXPECT_EQ(DataType::kFlags, type);
  EXPECT_EQ(1u, data.size());
  EXPECT_TRUE(ContainersEqual(CreateStaticByteBuffer(0x00), data));

  EXPECT_TRUE(reader.HasMoreData());
  EXPECT_TRUE(reader.GetNextField(&type, &data));
  EXPECT_EQ(DataType::kCompleteLocalName, type);
  EXPECT_EQ(4u, data.size());
  EXPECT_TRUE(ContainersEqual(std::string("Test"), data));

  EXPECT_FALSE(reader.HasMoreData());
  EXPECT_FALSE(reader.GetNextField(&type, &data));
}

// Helper for computing the size of a string literal at compile time. sizeof()
// would have worked too but that counts the null character.
template <std::size_t N>
constexpr size_t StringSize(char const (&str)[N]) {
  return N - 1;
}

TEST(GAP_AdvertisingDataTest, WriteField) {
  constexpr char kValue0[] = "value zero";
  constexpr char kValue1[] = "value one";
  constexpr char kValue2[] = "value two";
  constexpr char kValue3[] = "value three";

  // Have just enough space for the first three values (+ 6 for 2 extra octets
  // for each TLV field).
  constexpr char kBufferSize =
      StringSize(kValue0) + StringSize(kValue1) + StringSize(kValue2) + 6;
  StaticByteBuffer<kBufferSize> buffer;

  AdvertisingDataWriter writer(&buffer);
  EXPECT_EQ(0u, writer.bytes_written());

  // We write malformed values here for testing purposes.
  EXPECT_TRUE(writer.WriteField(DataType::kFlags, BufferView(kValue0)));
  EXPECT_EQ(StringSize(kValue0) + 2, writer.bytes_written());

  EXPECT_TRUE(
      writer.WriteField(DataType::kShortenedLocalName, BufferView(kValue1)));
  EXPECT_EQ(StringSize(kValue0) + 2 + StringSize(kValue1) + 2,
            writer.bytes_written());

  // Trying to write kValue3 should fail because there isn't enough room left in
  // the buffer.
  EXPECT_FALSE(
      writer.WriteField(DataType::kCompleteLocalName, BufferView(kValue3)));

  // Writing kValue2 should fill up the buffer.
  EXPECT_TRUE(
      writer.WriteField(DataType::kCompleteLocalName, BufferView(kValue2)));
  EXPECT_FALSE(
      writer.WriteField(DataType::kCompleteLocalName, BufferView(kValue3)));
  EXPECT_EQ(buffer.size(), writer.bytes_written());

  // Verify the contents.
  DataType type;
  BufferView value;
  AdvertisingDataReader reader(buffer);
  EXPECT_TRUE(reader.is_valid());

  EXPECT_TRUE(reader.GetNextField(&type, &value));
  EXPECT_EQ(DataType::kFlags, type);
  EXPECT_EQ(kValue0, value.AsString());

  EXPECT_TRUE(reader.GetNextField(&type, &value));
  EXPECT_EQ(DataType::kShortenedLocalName, type);
  EXPECT_EQ(kValue1, value.AsString());

  EXPECT_TRUE(reader.GetNextField(&type, &value));
  EXPECT_EQ(DataType::kCompleteLocalName, type);
  EXPECT_EQ(kValue2, value.AsString());

  EXPECT_FALSE(reader.GetNextField(&type, &value));
}

}  // namespace
}  // namespace gap
}  // namespace bt
