// 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/hci/advertising_report_parser.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"
#include "src/connectivity/bluetooth/core/bt-host/hci/control_packets.h"

namespace bt {
namespace hci {
namespace test {
namespace {

TEST(HCI_AdvertisingReportParserTest, EmptyReport) {
  auto bytes = CreateStaticByteBuffer(0x3E, 0x02, 0x02, 0x00);

  auto event = EventPacket::New(bytes.size() - sizeof(EventHeader));
  event->mutable_view()->mutable_data().Write(bytes);
  event->InitializeFromBuffer();

  AdvertisingReportParser parser(*event);
  EXPECT_FALSE(parser.HasMoreReports());

  const LEAdvertisingReportData* data;
  int8_t rssi;
  EXPECT_FALSE(parser.GetNextReport(&data, &rssi));
}

TEST(HCI_AdvertisingReportParserTest, SingleReportMalformed) {
  // clang-format off

  auto bytes = CreateStaticByteBuffer(
      0x3E, 0x0B, 0x02, 0x01,  // HCI event header and LE Meta Event params
      0x03, 0x02,              // event_type, address_type
      0x01, 0x02, 0x03, 0x04, 0x05, 0x06,  // address
      0x00                                 // |length_data|. RSSI is missing
      );

  // clang-format on

  auto event = EventPacket::New(bytes.size() - sizeof(EventHeader));
  event->mutable_view()->mutable_data().Write(bytes);
  event->InitializeFromBuffer();

  AdvertisingReportParser parser(*event);
  EXPECT_TRUE(parser.HasMoreReports());
  EXPECT_FALSE(parser.encountered_error());

  const LEAdvertisingReportData* data;
  int8_t rssi;
  EXPECT_FALSE(parser.GetNextReport(&data, &rssi));
  EXPECT_TRUE(parser.encountered_error());
}

TEST(HCI_AdvertisingReportParserTest, SingleReportNoData) {
  // clang-format off

  auto bytes = CreateStaticByteBuffer(
      0x3E, 0x0C, 0x02, 0x01,  // HCI event header and LE Meta Event params
      0x03, 0x02,              // event_type, address_type
      0x01, 0x02, 0x03, 0x04, 0x05, 0x06,  // address
      0x00, 0x7F                           // |length_data|, RSSI
      );

  // clang-format on

  auto event = EventPacket::New(bytes.size() - sizeof(EventHeader));
  event->mutable_view()->mutable_data().Write(bytes);
  event->InitializeFromBuffer();

  AdvertisingReportParser parser(*event);
  EXPECT_TRUE(parser.HasMoreReports());

  const LEAdvertisingReportData* data;
  int8_t rssi;
  EXPECT_TRUE(parser.GetNextReport(&data, &rssi));
  EXPECT_EQ(LEAdvertisingEventType::kAdvNonConnInd, data->event_type);
  EXPECT_EQ(LEAddressType::kPublicIdentity, data->address_type);
  EXPECT_EQ("06:05:04:03:02:01", data->address.ToString());
  EXPECT_EQ(0u, data->length_data);
  EXPECT_EQ(kRSSIInvalid, rssi);

  // No other reports
  EXPECT_FALSE(parser.HasMoreReports());
  EXPECT_FALSE(parser.GetNextReport(&data, &rssi));

  EXPECT_FALSE(parser.encountered_error());
}

TEST(HCI_AdvertisingReportParserTest, ReportsValidInvalid) {
  // clang-format off

  auto bytes = CreateStaticByteBuffer(
      0x3E, 0x16, 0x02, 0x02,  // HCI event header and LE Meta Event params
      0x03, 0x02,              // event_type, address_type
      0x01, 0x02, 0x03, 0x04, 0x05, 0x06,  // address
      0x00, 0x7F,                          // |length_data|, RSSI
      0x03, 0x02,                          // event_type, address_type
      0x01, 0x02, 0x03, 0x04, 0x05, 0x06,  // address
      0x0A, 0x7F                           // malformed |length_data|, RSSI
      );

  // clang-format on

  auto event = EventPacket::New(bytes.size() - sizeof(EventHeader));
  event->mutable_view()->mutable_data().Write(bytes);
  event->InitializeFromBuffer();

  AdvertisingReportParser parser(*event);
  EXPECT_TRUE(parser.HasMoreReports());
  EXPECT_FALSE(parser.encountered_error());

  const LEAdvertisingReportData* data;
  int8_t rssi;
  EXPECT_TRUE(parser.GetNextReport(&data, &rssi));
  EXPECT_EQ(LEAdvertisingEventType::kAdvNonConnInd, data->event_type);
  EXPECT_EQ(LEAddressType::kPublicIdentity, data->address_type);
  EXPECT_EQ("06:05:04:03:02:01", data->address.ToString());
  EXPECT_EQ(0u, data->length_data);
  EXPECT_EQ(kRSSIInvalid, rssi);

  // There are more reports...
  EXPECT_TRUE(parser.HasMoreReports());
  EXPECT_FALSE(parser.encountered_error());

  // ...but the report is malformed.
  EXPECT_FALSE(parser.GetNextReport(&data, &rssi));
  EXPECT_TRUE(parser.encountered_error());
}

TEST(HCI_AdvertisingReportParserTest, ReportsAllValid) {
  // clang-format off

  auto bytes = CreateStaticByteBuffer(
      0x3E, 0x28, 0x02, 0x03,              // HCI event header and LE Meta Event params
      0x03, 0x02,                          // event_type, address_type
      0x01, 0x02, 0x03, 0x04, 0x05, 0x06,  // address
      0x00, 0x7F,                          // |length_data|, RSSI

      0x00, 0x01,                          // event_type, address_type
      0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C,  // address
      0x03, 0x01, 0x02, 0x03, 0x0F,        // |length_data|, data, RSSI

      0x01, 0x00,                          // event_type, address_type
      0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12,  // address
      0x05, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,  // |length_data|, data
      0x01                                 // RSSI
      );

  // clang-format on

  auto event = EventPacket::New(bytes.size() - sizeof(EventHeader));
  event->mutable_view()->mutable_data().Write(bytes);
  event->InitializeFromBuffer();

  AdvertisingReportParser parser(*event);
  EXPECT_TRUE(parser.HasMoreReports());

  const LEAdvertisingReportData* data;
  int8_t rssi;
  EXPECT_TRUE(parser.GetNextReport(&data, &rssi));
  EXPECT_EQ(LEAdvertisingEventType::kAdvNonConnInd, data->event_type);
  EXPECT_EQ(LEAddressType::kPublicIdentity, data->address_type);
  EXPECT_EQ("06:05:04:03:02:01", data->address.ToString());
  EXPECT_EQ(0u, data->length_data);
  EXPECT_EQ(kRSSIInvalid, rssi);

  // There are more reports
  EXPECT_TRUE(parser.HasMoreReports());
  EXPECT_TRUE(parser.GetNextReport(&data, &rssi));
  EXPECT_EQ(LEAdvertisingEventType::kAdvInd, data->event_type);
  EXPECT_EQ(LEAddressType::kRandom, data->address_type);
  EXPECT_EQ("0C:0B:0A:09:08:07", data->address.ToString());
  EXPECT_EQ(3, data->length_data);
  EXPECT_TRUE(ContainersEqual(std::array<uint8_t, 3>{{0x01, 0x02, 0x03}},
                              data->data, data->length_data));
  EXPECT_EQ(15, rssi);

  // There are more reports
  EXPECT_TRUE(parser.HasMoreReports());
  EXPECT_TRUE(parser.GetNextReport(&data, &rssi));
  EXPECT_EQ(LEAdvertisingEventType::kAdvDirectInd, data->event_type);
  EXPECT_EQ(LEAddressType::kPublic, data->address_type);
  EXPECT_EQ("12:11:10:0F:0E:0D", data->address.ToString());
  EXPECT_EQ(5, data->length_data);
  EXPECT_TRUE(
      ContainersEqual(std::array<uint8_t, 5>{{0xFF, 0xFF, 0xFF, 0xFF, 0xFF}},
                      data->data, data->length_data));
  EXPECT_EQ(1, rssi);

  // No more reports.
  EXPECT_FALSE(parser.HasMoreReports());
  EXPECT_FALSE(parser.GetNextReport(&data, &rssi));

  EXPECT_FALSE(parser.encountered_error());
}

TEST(HCI_AdvertisingReportParserTest, ReportCountLessThanPayloadSize) {
  // clang-format off

  auto bytes = CreateStaticByteBuffer(
      0x3E, 0x28, 0x02,  // HCI event header and LE Meta Event param
      0x01,              // Event count is 1, even though packet contains 3
      0x03, 0x02,        // event_type, address_type
      0x01, 0x02, 0x03, 0x04, 0x05, 0x06,  // address
      0x00, 0x7F,                          // |length_data|, RSSI

      0x00, 0x01,                          // event_type, address_type
      0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C,  // address
      0x03, 0x01, 0x02, 0x03, 0x0F,        // |length_data|, data, RSSI

      0x01, 0x00,                          // event_type, address_type
      0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12,  // address
      0x05, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,  // |length_data|, data
      0x01                                 // RSSI
      );

  // clang-format on

  auto event = EventPacket::New(bytes.size() - sizeof(EventHeader));
  event->mutable_view()->mutable_data().Write(bytes);
  event->InitializeFromBuffer();

  AdvertisingReportParser parser(*event);
  EXPECT_TRUE(parser.HasMoreReports());
  EXPECT_FALSE(parser.encountered_error());

  const LEAdvertisingReportData* data;
  int8_t rssi;
  EXPECT_TRUE(parser.GetNextReport(&data, &rssi));
  EXPECT_EQ(LEAdvertisingEventType::kAdvNonConnInd, data->event_type);
  EXPECT_EQ(LEAddressType::kPublicIdentity, data->address_type);
  EXPECT_EQ("06:05:04:03:02:01", data->address.ToString());
  EXPECT_EQ(0u, data->length_data);
  EXPECT_EQ(kRSSIInvalid, rssi);

  // Since the packet is malformed (the event payload contains 3 reports while
  // the header states there is only 1) this should return false.
  EXPECT_FALSE(parser.encountered_error());
  EXPECT_FALSE(parser.HasMoreReports());
  EXPECT_TRUE(parser.encountered_error());

  EXPECT_FALSE(parser.GetNextReport(&data, &rssi));
  EXPECT_TRUE(parser.encountered_error());
}

TEST(HCI_AdvertisingReportParserTest, ReportCountGreaterThanPayloadSize) {
  // clang-format off

  auto bytes = CreateStaticByteBuffer(
      0x3E, 0x0C, 0x02,  // HCI event header and LE Meta Event param
      0x02,              // Event count is 2, even though packet contains 1
      0x03, 0x02,        // event_type, address_type
      0x01, 0x02, 0x03, 0x04, 0x05, 0x06,  // address
      0x00, 0x7F                           // |length_data|, RSSI
      );

  // clang-format on

  auto event = EventPacket::New(bytes.size() - sizeof(EventHeader));
  event->mutable_view()->mutable_data().Write(bytes);
  event->InitializeFromBuffer();

  AdvertisingReportParser parser(*event);
  EXPECT_TRUE(parser.HasMoreReports());

  const LEAdvertisingReportData* data;
  int8_t rssi;
  EXPECT_TRUE(parser.GetNextReport(&data, &rssi));
  EXPECT_EQ(LEAdvertisingEventType::kAdvNonConnInd, data->event_type);
  EXPECT_EQ(LEAddressType::kPublicIdentity, data->address_type);
  EXPECT_EQ("06:05:04:03:02:01", data->address.ToString());
  EXPECT_EQ(0u, data->length_data);
  EXPECT_EQ(kRSSIInvalid, rssi);

  EXPECT_FALSE(parser.encountered_error());

  // Since the packet is malformed (the event payload contains 1 report while
  // the header states there are 2) this should return false.
  EXPECT_FALSE(parser.HasMoreReports());
  EXPECT_FALSE(parser.GetNextReport(&data, &rssi));

  EXPECT_TRUE(parser.encountered_error());
}

}  // namespace
}  // namespace test
}  // namespace hci
}  // namespace bt
