// 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 "garnet/drivers/bluetooth/lib/gap/advertising_data.h"

#include "gtest/gtest.h"

#include "garnet/drivers/bluetooth/lib/common/byte_buffer.h"
#include "garnet/drivers/bluetooth/lib/common/test_helpers.h"

namespace btlib {
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) {
  common::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 = common::CreateStaticByteBuffer(0x0B, 0x24, 0x17, '/', '/', 'a',
                                              'b', 'c', '.', 'x', 'y', 'z');

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

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

  auto bytes = common::CreateStaticByteBuffer(0x0B, 0x24, 0x01, 'f', 'l', 'u',
                                              'b', 's', ':', 'x', 'y', 'z');

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

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

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

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

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

  EXPECT_TRUE(ContainersEqual(bytes, block));
}

TEST(GAP_AdvertisingDataTest, ParseBlock) {
  auto bytes = common::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()));

  common::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 = common::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 = common::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;
  common::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;

  common::UUID gatt(kGattUuid);
  common::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 = common::CreateStaticByteBuffer(0x01, 0x02, 0x03, 0x04);
  auto same = common::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) {
  common::UUID gatt(kGattUuid);
  common::UUID eddy(kEddystoneUuid);
  common::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 = common::CreateStaticByteBuffer(0x01, 0x02, 0x03);
  source.SetManufacturerData(0x0123, bytes.view());
  EXPECT_TRUE(
      common::ContainersEqual(rand_data, dest.manufacturer_data(0x0123)));
}

TEST(GAP_AdvertisingDataTest, Move) {
  common::UUID gatt(kGattUuid);
  common::UUID eddy(kEddystoneUuid);
  common::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<common::UUID>({gatt, eddy}),
            dest.service_uuids());
}

TEST(GAP_AdvertisingDataTest, Uris) {
  auto bytes = common::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 = common::CreateStaticByteBuffer(0x01);
  AdvertisingDataReader reader(bytes0);
  EXPECT_FALSE(reader.is_valid());
  EXPECT_FALSE(reader.HasMoreData());

  auto bytes = common::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 = common::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;
  common::BufferView data;
  bytes = common::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 = common::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 = common::CreateStaticByteBuffer(0x02, 0x01, 0x00, 0x05, 0x09, 'T',
                                              'e', 's', 't');
  AdvertisingDataReader reader(bytes);
  EXPECT_TRUE(reader.is_valid());
  EXPECT_TRUE(reader.HasMoreData());

  DataType type;
  common::BufferView data;
  EXPECT_TRUE(reader.GetNextField(&type, &data));
  EXPECT_EQ(DataType::kFlags, type);
  EXPECT_EQ(1u, data.size());
  EXPECT_TRUE(
      common::ContainersEqual(common::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(common::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;
  common::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, common::BufferView(kValue0)));
  EXPECT_EQ(StringSize(kValue0) + 2, writer.bytes_written());

  EXPECT_TRUE(writer.WriteField(DataType::kShortenedLocalName,
                                common::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,
                                 common::BufferView(kValue3)));

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

  // Verify the contents.
  DataType type;
  common::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 btlib
