// Copyright 2015 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "content/browser/bluetooth/bluetooth_allowed_devices.h"

#include "base/strings/string_util.h"
#include "content/browser/bluetooth/bluetooth_allowed_devices_map.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/common/bluetooth/web_bluetooth_device_id.h"
#include "url/gurl.h"

using device::BluetoothUUID;

namespace content {
namespace {
const std::string kDeviceAddress1 = "00:00:00";
const std::string kDeviceAddress2 = "11:11:11";

const std::string kDeviceName = "TestName";

const char kGlucoseUUIDString[] = "00001808-0000-1000-8000-00805f9b34fb";
const char kHeartRateUUIDString[] = "0000180d-0000-1000-8000-00805f9b34fb";
const char kBatteryServiceUUIDString[] = "0000180f-0000-1000-8000-00805f9b34fb";
const char kBloodPressureUUIDString[] = "00001813-0000-1000-8000-00805f9b34fb";
const char kCyclingPowerUUIDString[] = "00001818-0000-1000-8000-00805f9b34fb";
const BluetoothUUID kGlucoseUUID(kGlucoseUUIDString);
const BluetoothUUID kHeartRateUUID(kHeartRateUUIDString);
const BluetoothUUID kBatteryServiceUUID(kBatteryServiceUUIDString);
const BluetoothUUID kBloodPressureUUID(kBloodPressureUUIDString);
const BluetoothUUID kCyclingPowerUUID(kCyclingPowerUUIDString);

class BluetoothAllowedDevicesTest : public testing::Test {
 protected:
  BluetoothAllowedDevicesTest() {
    empty_options_ = blink::mojom::WebBluetoothRequestDeviceOptions::New();
  }

  ~BluetoothAllowedDevicesTest() override {}

  blink::mojom::WebBluetoothRequestDeviceOptionsPtr empty_options_;
};

}  // namespace

TEST_F(BluetoothAllowedDevicesTest, UniqueOriginNotSupported) {
  auto allowed_devices_map = std::make_unique<BluetoothAllowedDevicesMap>();
  EXPECT_DEATH_IF_SUPPORTED(
      allowed_devices_map->GetOrCreateAllowedDevices(url::Origin()), "");
}

TEST_F(BluetoothAllowedDevicesTest, AddDevice) {
  BluetoothAllowedDevices allowed_devices;

  const blink::WebBluetoothDeviceId& device_id =
      allowed_devices.AddDevice(kDeviceAddress1, empty_options_);

  // Test that we can retrieve the device address/id.
  EXPECT_EQ(device_id, *allowed_devices.GetDeviceId(kDeviceAddress1));
  EXPECT_EQ(kDeviceAddress1, allowed_devices.GetDeviceAddress(device_id));
}

TEST_F(BluetoothAllowedDevicesTest, AddDeviceTwice) {
  BluetoothAllowedDevices allowed_devices;
  const blink::WebBluetoothDeviceId& device_id1 =
      allowed_devices.AddDevice(kDeviceAddress1, empty_options_);
  const blink::WebBluetoothDeviceId& device_id2 =
      allowed_devices.AddDevice(kDeviceAddress1, empty_options_);

  EXPECT_EQ(device_id1, device_id2);

  // Test that we can retrieve the device address/id.
  EXPECT_EQ(device_id1, *allowed_devices.GetDeviceId(kDeviceAddress1));
  EXPECT_EQ(kDeviceAddress1, allowed_devices.GetDeviceAddress(device_id1));
}

TEST_F(BluetoothAllowedDevicesTest, AddTwoDevices) {
  BluetoothAllowedDevices allowed_devices;
  const blink::WebBluetoothDeviceId& device_id1 =
      allowed_devices.AddDevice(kDeviceAddress1, empty_options_);
  const blink::WebBluetoothDeviceId& device_id2 =
      allowed_devices.AddDevice(kDeviceAddress2, empty_options_);

  EXPECT_NE(device_id1, device_id2);

  // Test that we can retrieve the device address/id.
  EXPECT_EQ(device_id1, *allowed_devices.GetDeviceId(kDeviceAddress1));
  EXPECT_EQ(device_id2, *allowed_devices.GetDeviceId(kDeviceAddress2));

  EXPECT_EQ(kDeviceAddress1, allowed_devices.GetDeviceAddress(device_id1));
  EXPECT_EQ(kDeviceAddress2, allowed_devices.GetDeviceAddress(device_id2));
}

TEST_F(BluetoothAllowedDevicesTest, AddTwoDevicesFromTwoOriginsToMap) {
  auto allowed_devices_map = std::make_unique<BluetoothAllowedDevicesMap>();
  content::BluetoothAllowedDevices& allowed_devices1 =
      allowed_devices_map->GetOrCreateAllowedDevices(
          url::Origin::Create(GURL("https://www.example1.com")));
  content::BluetoothAllowedDevices& allowed_devices2 =
      allowed_devices_map->GetOrCreateAllowedDevices(
          url::Origin::Create(GURL("https://www.example2.com")));

  const blink::WebBluetoothDeviceId& device_id1 =
      allowed_devices1.AddDevice(kDeviceAddress1, empty_options_);
  const blink::WebBluetoothDeviceId& device_id2 =
      allowed_devices2.AddDevice(kDeviceAddress2, empty_options_);

  EXPECT_NE(device_id1, device_id2);

  // Test that the wrong origin doesn't have access to the device.
  EXPECT_EQ(nullptr, allowed_devices1.GetDeviceId(kDeviceAddress2));
  EXPECT_EQ(nullptr, allowed_devices2.GetDeviceId(kDeviceAddress1));

  EXPECT_EQ(std::string(), allowed_devices1.GetDeviceAddress(device_id2));
  EXPECT_EQ(std::string(), allowed_devices2.GetDeviceAddress(device_id1));

  // Test that we can retrieve the device address/id.
  EXPECT_EQ(device_id1, *(allowed_devices1.GetDeviceId(kDeviceAddress1)));
  EXPECT_EQ(device_id2, *(allowed_devices2.GetDeviceId(kDeviceAddress2)));

  EXPECT_EQ(kDeviceAddress1, allowed_devices1.GetDeviceAddress(device_id1));
  EXPECT_EQ(kDeviceAddress2, allowed_devices2.GetDeviceAddress(device_id2));
}

TEST_F(BluetoothAllowedDevicesTest, AddDeviceFromTwoOriginsToMap) {
  auto allowed_devices_map = std::make_unique<BluetoothAllowedDevicesMap>();
  content::BluetoothAllowedDevices& allowed_devices1 =
      allowed_devices_map->GetOrCreateAllowedDevices(
          url::Origin::Create(GURL("https://www.example1.com")));
  content::BluetoothAllowedDevices& allowed_devices2 =
      allowed_devices_map->GetOrCreateAllowedDevices(
          url::Origin::Create(GURL("https://www.example2.com")));

  const blink::WebBluetoothDeviceId& device_id1 =
      allowed_devices1.AddDevice(kDeviceAddress1, empty_options_);
  const blink::WebBluetoothDeviceId& device_id2 =
      allowed_devices2.AddDevice(kDeviceAddress1, empty_options_);

  EXPECT_NE(device_id1, device_id2);

  // Test that the wrong origin doesn't have access to the device.
  EXPECT_EQ(std::string(), allowed_devices1.GetDeviceAddress(device_id2));
  EXPECT_EQ(std::string(), allowed_devices2.GetDeviceAddress(device_id1));
}

TEST_F(BluetoothAllowedDevicesTest, AddRemoveAddDevice) {
  BluetoothAllowedDevices allowed_devices;
  const blink::WebBluetoothDeviceId device_id_first_time =
      allowed_devices.AddDevice(kDeviceAddress1, empty_options_);

  allowed_devices.RemoveDevice(kDeviceAddress1);

  const blink::WebBluetoothDeviceId device_id_second_time =
      allowed_devices.AddDevice(kDeviceAddress1, empty_options_);

  EXPECT_NE(device_id_first_time, device_id_second_time);
}

TEST_F(BluetoothAllowedDevicesTest, RemoveDevice) {
  BluetoothAllowedDevices allowed_devices;

  const blink::WebBluetoothDeviceId device_id =
      allowed_devices.AddDevice(kDeviceAddress1, empty_options_);

  allowed_devices.RemoveDevice(kDeviceAddress1);

  EXPECT_EQ(nullptr, allowed_devices.GetDeviceId(kDeviceAddress1));
  EXPECT_EQ(std::string(), allowed_devices.GetDeviceAddress(device_id));
}

TEST_F(BluetoothAllowedDevicesTest, NoPermissionForAnyService) {
  BluetoothAllowedDevices allowed_devices;

  // Setup device.
  blink::mojom::WebBluetoothRequestDeviceOptionsPtr options =
      blink::mojom::WebBluetoothRequestDeviceOptions::New();
  blink::mojom::WebBluetoothLeScanFilterPtr scan_filter =
      blink::mojom::WebBluetoothLeScanFilter::New();

  scan_filter->name = kDeviceName;
  options->filters.emplace();
  options->filters->push_back({scan_filter.Clone()});

  // Add to map.
  const blink::WebBluetoothDeviceId device_id =
      allowed_devices.AddDevice(kDeviceAddress1, options);

  // Try to access at least one service.
  EXPECT_FALSE(allowed_devices.IsAllowedToAccessAtLeastOneService(device_id));
  EXPECT_FALSE(
      allowed_devices.IsAllowedToAccessService(device_id, kGlucoseUUID));
}

TEST_F(BluetoothAllowedDevicesTest, AllowedServices_OneDevice) {
  BluetoothAllowedDevices allowed_devices;

  // Setup device.
  blink::mojom::WebBluetoothRequestDeviceOptionsPtr options =
      blink::mojom::WebBluetoothRequestDeviceOptions::New();
  blink::mojom::WebBluetoothLeScanFilterPtr scan_filter1 =
      blink::mojom::WebBluetoothLeScanFilter::New();
  blink::mojom::WebBluetoothLeScanFilterPtr scan_filter2 =
      blink::mojom::WebBluetoothLeScanFilter::New();

  scan_filter1->services.emplace();
  scan_filter1->services->push_back(kGlucoseUUID);
  options->filters.emplace();
  options->filters->push_back(scan_filter1.Clone());

  scan_filter2->services.emplace();
  scan_filter2->services->push_back(kHeartRateUUID);
  options->filters->push_back(scan_filter2.Clone());

  options->optional_services.push_back(kBatteryServiceUUID);
  options->optional_services.push_back(kHeartRateUUID);

  // Add to map.
  const blink::WebBluetoothDeviceId device_id1 =
      allowed_devices.AddDevice(kDeviceAddress1, options);

  // Access allowed services.
  EXPECT_TRUE(allowed_devices.IsAllowedToAccessAtLeastOneService(device_id1));
  EXPECT_TRUE(
      allowed_devices.IsAllowedToAccessService(device_id1, kGlucoseUUID));
  EXPECT_TRUE(
      allowed_devices.IsAllowedToAccessService(device_id1, kHeartRateUUID));
  EXPECT_TRUE(allowed_devices.IsAllowedToAccessService(device_id1,
                                                       kBatteryServiceUUID));

  // Try to access a non-allowed service.
  EXPECT_FALSE(
      allowed_devices.IsAllowedToAccessService(device_id1, kBloodPressureUUID));

  // Try to access allowed services after removing device.
  allowed_devices.RemoveDevice(kDeviceAddress1);

  EXPECT_FALSE(allowed_devices.IsAllowedToAccessAtLeastOneService(device_id1));
  EXPECT_FALSE(
      allowed_devices.IsAllowedToAccessService(device_id1, kGlucoseUUID));
  EXPECT_FALSE(
      allowed_devices.IsAllowedToAccessService(device_id1, kHeartRateUUID));
  EXPECT_FALSE(allowed_devices.IsAllowedToAccessService(device_id1,
                                                        kBatteryServiceUUID));

  // Add device back.
  blink::mojom::WebBluetoothRequestDeviceOptionsPtr options2 =
      blink::mojom::WebBluetoothRequestDeviceOptions::New();

  options2->filters.emplace();
  options2->filters->push_back(scan_filter1.Clone());
  options2->filters->push_back(scan_filter2.Clone());

  const blink::WebBluetoothDeviceId device_id2 =
      allowed_devices.AddDevice(kDeviceAddress1, options2);

  // Access allowed services.
  EXPECT_TRUE(allowed_devices.IsAllowedToAccessAtLeastOneService(device_id2));
  EXPECT_TRUE(
      allowed_devices.IsAllowedToAccessService(device_id2, kGlucoseUUID));
  EXPECT_TRUE(
      allowed_devices.IsAllowedToAccessService(device_id2, kHeartRateUUID));

  // Try to access a non-allowed service.
  EXPECT_FALSE(allowed_devices.IsAllowedToAccessService(device_id2,
                                                        kBatteryServiceUUID));

  // Try to access services from old device.
  EXPECT_FALSE(
      allowed_devices.IsAllowedToAccessService(device_id1, kGlucoseUUID));
  EXPECT_FALSE(
      allowed_devices.IsAllowedToAccessService(device_id1, kHeartRateUUID));
  EXPECT_FALSE(allowed_devices.IsAllowedToAccessService(device_id1,
                                                        kBatteryServiceUUID));
}

TEST_F(BluetoothAllowedDevicesTest, AllowedServices_TwoDevices) {
  BluetoothAllowedDevices allowed_devices;

  // Setup request for device #1.
  blink::mojom::WebBluetoothRequestDeviceOptionsPtr options1 =
      blink::mojom::WebBluetoothRequestDeviceOptions::New();
  blink::mojom::WebBluetoothLeScanFilterPtr scan_filter1 =
      blink::mojom::WebBluetoothLeScanFilter::New();

  scan_filter1->services.emplace();
  scan_filter1->services->push_back(kGlucoseUUID);
  options1->filters.emplace();
  options1->filters->push_back(std::move(scan_filter1));

  options1->optional_services.push_back(kHeartRateUUID);

  // Setup request for device #2.
  blink::mojom::WebBluetoothRequestDeviceOptionsPtr options2 =
      blink::mojom::WebBluetoothRequestDeviceOptions::New();
  blink::mojom::WebBluetoothLeScanFilterPtr scan_filter2 =
      blink::mojom::WebBluetoothLeScanFilter::New();

  scan_filter2->services.emplace();
  scan_filter2->services->push_back(kBatteryServiceUUID);
  options2->filters.emplace();
  options2->filters->push_back(std::move(scan_filter2));

  options2->optional_services.push_back(kBloodPressureUUID);

  // Add devices to map.
  const blink::WebBluetoothDeviceId& device_id1 =
      allowed_devices.AddDevice(kDeviceAddress1, options1);
  const blink::WebBluetoothDeviceId& device_id2 =
      allowed_devices.AddDevice(kDeviceAddress2, options2);

  // Access allowed services.
  EXPECT_TRUE(allowed_devices.IsAllowedToAccessAtLeastOneService(device_id1));
  EXPECT_TRUE(
      allowed_devices.IsAllowedToAccessService(device_id1, kGlucoseUUID));
  EXPECT_TRUE(
      allowed_devices.IsAllowedToAccessService(device_id1, kHeartRateUUID));

  EXPECT_TRUE(allowed_devices.IsAllowedToAccessAtLeastOneService(device_id2));
  EXPECT_TRUE(allowed_devices.IsAllowedToAccessService(device_id2,
                                                       kBatteryServiceUUID));
  EXPECT_TRUE(
      allowed_devices.IsAllowedToAccessService(device_id2, kBloodPressureUUID));

  // Try to access non-allowed services.
  EXPECT_FALSE(allowed_devices.IsAllowedToAccessService(device_id1,
                                                        kBatteryServiceUUID));
  EXPECT_FALSE(
      allowed_devices.IsAllowedToAccessService(device_id1, kBloodPressureUUID));
  EXPECT_FALSE(
      allowed_devices.IsAllowedToAccessService(device_id1, kCyclingPowerUUID));

  EXPECT_FALSE(
      allowed_devices.IsAllowedToAccessService(device_id2, kGlucoseUUID));
  EXPECT_FALSE(
      allowed_devices.IsAllowedToAccessService(device_id2, kHeartRateUUID));
  EXPECT_FALSE(
      allowed_devices.IsAllowedToAccessService(device_id2, kCyclingPowerUUID));
}

TEST_F(BluetoothAllowedDevicesTest, AllowedServices_TwoOriginsOneDevice) {
  auto allowed_devices_map = std::make_unique<BluetoothAllowedDevicesMap>();
  content::BluetoothAllowedDevices& allowed_devices1 =
      allowed_devices_map->GetOrCreateAllowedDevices(
          url::Origin::Create(GURL("https://www.example1.com")));
  content::BluetoothAllowedDevices& allowed_devices2 =
      allowed_devices_map->GetOrCreateAllowedDevices(
          url::Origin::Create(GURL("https://www.example2.com")));
  // Setup request #1 for device.
  blink::mojom::WebBluetoothRequestDeviceOptionsPtr options1 =
      blink::mojom::WebBluetoothRequestDeviceOptions::New();
  blink::mojom::WebBluetoothLeScanFilterPtr scan_filter1 =
      blink::mojom::WebBluetoothLeScanFilter::New();

  scan_filter1->services.emplace();
  scan_filter1->services->push_back(kGlucoseUUID);
  options1->filters.emplace();
  options1->filters->push_back(std::move(scan_filter1));

  options1->optional_services.push_back(kHeartRateUUID);

  // Setup request #2 for device.
  blink::mojom::WebBluetoothRequestDeviceOptionsPtr options2 =
      blink::mojom::WebBluetoothRequestDeviceOptions::New();
  blink::mojom::WebBluetoothLeScanFilterPtr scan_filter2 =
      blink::mojom::WebBluetoothLeScanFilter::New();

  scan_filter2->services.emplace();
  scan_filter2->services->push_back(kBatteryServiceUUID);
  options2->filters.emplace();
  options2->filters->push_back(std::move(scan_filter2));

  options2->optional_services.push_back(kBloodPressureUUID);

  // Add devices to map.
  const blink::WebBluetoothDeviceId& device_id1 =
      allowed_devices1.AddDevice(kDeviceAddress1, options1);
  const blink::WebBluetoothDeviceId& device_id2 =
      allowed_devices2.AddDevice(kDeviceAddress1, options2);

  // Access allowed services.
  EXPECT_TRUE(allowed_devices1.IsAllowedToAccessAtLeastOneService(device_id1));
  EXPECT_TRUE(
      allowed_devices1.IsAllowedToAccessService(device_id1, kGlucoseUUID));
  EXPECT_TRUE(
      allowed_devices1.IsAllowedToAccessService(device_id1, kHeartRateUUID));

  EXPECT_TRUE(allowed_devices2.IsAllowedToAccessAtLeastOneService(device_id2));
  EXPECT_TRUE(allowed_devices2.IsAllowedToAccessService(device_id2,
                                                        kBatteryServiceUUID));
  EXPECT_TRUE(allowed_devices2.IsAllowedToAccessService(device_id2,
                                                        kBloodPressureUUID));

  // Try to access non-allowed services.
  EXPECT_FALSE(allowed_devices1.IsAllowedToAccessService(device_id1,
                                                         kBatteryServiceUUID));
  EXPECT_FALSE(allowed_devices1.IsAllowedToAccessService(device_id1,
                                                         kBloodPressureUUID));

  EXPECT_FALSE(allowed_devices1.IsAllowedToAccessAtLeastOneService(device_id2));
  EXPECT_FALSE(
      allowed_devices1.IsAllowedToAccessService(device_id2, kGlucoseUUID));
  EXPECT_FALSE(
      allowed_devices1.IsAllowedToAccessService(device_id2, kHeartRateUUID));
  EXPECT_FALSE(allowed_devices1.IsAllowedToAccessService(device_id2,
                                                         kBatteryServiceUUID));
  EXPECT_FALSE(allowed_devices1.IsAllowedToAccessService(device_id2,
                                                         kBloodPressureUUID));

  EXPECT_FALSE(
      allowed_devices2.IsAllowedToAccessService(device_id2, kGlucoseUUID));
  EXPECT_FALSE(
      allowed_devices2.IsAllowedToAccessService(device_id2, kHeartRateUUID));

  EXPECT_FALSE(allowed_devices2.IsAllowedToAccessAtLeastOneService(device_id1));
  EXPECT_FALSE(
      allowed_devices2.IsAllowedToAccessService(device_id1, kGlucoseUUID));
  EXPECT_FALSE(
      allowed_devices2.IsAllowedToAccessService(device_id1, kHeartRateUUID));
  EXPECT_FALSE(allowed_devices2.IsAllowedToAccessService(device_id1,
                                                         kBatteryServiceUUID));
  EXPECT_FALSE(allowed_devices2.IsAllowedToAccessService(device_id1,
                                                         kBloodPressureUUID));
}

TEST_F(BluetoothAllowedDevicesTest, MergeServices) {
  BluetoothAllowedDevices allowed_devices;

  // Setup first request.
  blink::mojom::WebBluetoothRequestDeviceOptionsPtr options1 =
      blink::mojom::WebBluetoothRequestDeviceOptions::New();
  blink::mojom::WebBluetoothLeScanFilterPtr scan_filter1 =
      blink::mojom::WebBluetoothLeScanFilter::New();

  scan_filter1->services.emplace();
  scan_filter1->services->push_back(kGlucoseUUID);
  options1->filters.emplace();
  options1->filters->push_back(std::move(scan_filter1));

  options1->optional_services.push_back(kBatteryServiceUUID);

  // Add to map.
  const blink::WebBluetoothDeviceId device_id1 =
      allowed_devices.AddDevice(kDeviceAddress1, options1);

  // Setup second request.
  blink::mojom::WebBluetoothRequestDeviceOptionsPtr options2 =
      blink::mojom::WebBluetoothRequestDeviceOptions::New();
  blink::mojom::WebBluetoothLeScanFilterPtr scan_filter2 =
      blink::mojom::WebBluetoothLeScanFilter::New();

  scan_filter2->services.emplace();
  scan_filter2->services->push_back(kHeartRateUUID);
  options2->filters.emplace();
  options2->filters->push_back(std::move(scan_filter2));

  options2->optional_services.push_back(kBloodPressureUUID);

  // Add to map again.
  const blink::WebBluetoothDeviceId device_id2 =
      allowed_devices.AddDevice(kDeviceAddress1, options2);

  EXPECT_EQ(device_id1, device_id2);

  EXPECT_TRUE(allowed_devices.IsAllowedToAccessAtLeastOneService(device_id1));
  EXPECT_TRUE(
      allowed_devices.IsAllowedToAccessService(device_id1, kGlucoseUUID));
  EXPECT_TRUE(allowed_devices.IsAllowedToAccessService(device_id1,
                                                       kBatteryServiceUUID));
  EXPECT_TRUE(
      allowed_devices.IsAllowedToAccessService(device_id1, kHeartRateUUID));
  EXPECT_TRUE(
      allowed_devices.IsAllowedToAccessService(device_id1, kBloodPressureUUID));
}

TEST_F(BluetoothAllowedDevicesTest, CorrectIdFormat) {
  BluetoothAllowedDevices allowed_devices;

  const blink::WebBluetoothDeviceId& device_id =
      allowed_devices.AddDevice(kDeviceAddress1, empty_options_);

  EXPECT_TRUE(blink::WebBluetoothDeviceId::IsValid(device_id.str()));
}

TEST_F(BluetoothAllowedDevicesTest, NoFilterServices) {
  BluetoothAllowedDevices allowed_devices;

  // Setup request.
  blink::mojom::WebBluetoothRequestDeviceOptionsPtr options =
      blink::mojom::WebBluetoothRequestDeviceOptions::New();
  blink::mojom::WebBluetoothLeScanFilterPtr scan_filter =
      blink::mojom::WebBluetoothLeScanFilter::New();

  options->filters.emplace();
  options->filters->push_back(std::move(scan_filter));

  // Add to map.
  const blink::WebBluetoothDeviceId device_id =
      allowed_devices.AddDevice(kDeviceAddress1, options);

  EXPECT_FALSE(allowed_devices.IsAllowedToAccessAtLeastOneService(device_id));
}

}  // namespace content
