// 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 <string>
#include <vector>

#include "base/containers/contains.h"
#include "base/logging.h"
#include "base/strings/string_util.h"
#include "content/browser/bluetooth/bluetooth_blocklist.h"
#include "third_party/abseil-cpp/absl/types/optional.h"

using device::BluetoothUUID;

namespace content {

BluetoothAllowedDevices::BluetoothAllowedDevices() {}
BluetoothAllowedDevices::BluetoothAllowedDevices(
    const BluetoothAllowedDevices& other) = default;
BluetoothAllowedDevices::~BluetoothAllowedDevices() {}

const blink::WebBluetoothDeviceId& BluetoothAllowedDevices::AddDevice(
    const std::string& device_address,
    const blink::mojom::WebBluetoothRequestDeviceOptionsPtr& options) {
  auto& device_id = AddDevice(device_address);
  AddUnionOfServicesTo(options, &device_id_to_services_map_[device_id]);
  AddManufacturerDataTo(options, &device_id_to_manufacturers_map_[device_id]);

  // Currently, devices that are added with WebBluetoothRequestDeviceOptionsPtr
  // |options| come from RequestDevice() and therefore have the ablity to be
  // connected to.
  device_id_to_connectable_map_[device_id] = true;

  return device_id;
}

const blink::WebBluetoothDeviceId& BluetoothAllowedDevices::AddDevice(
    const std::string& device_address) {
  DVLOG(1) << "Adding a device to Map of Allowed Devices.";

  auto id_iter = device_address_to_id_map_.find(device_address);
  if (id_iter != device_address_to_id_map_.end()) {
    DVLOG(1) << "Device already in map of allowed devices.";
    return device_address_to_id_map_[device_address];
  }
  const blink::WebBluetoothDeviceId device_id = GenerateUniqueDeviceId();
  DVLOG(1) << "Id generated for device: " << device_id;

  device_address_to_id_map_[device_address] = device_id;
  device_id_to_address_map_[device_id] = device_address;

  CHECK(device_id_set_.insert(device_id).second);

  return device_address_to_id_map_[device_address];
}

void BluetoothAllowedDevices::RemoveDevice(const std::string& device_address) {
  const blink::WebBluetoothDeviceId* device_id_ptr =
      GetDeviceId(device_address);
  DCHECK(device_id_ptr != nullptr);

  // We make a copy because we are going to remove the original value from its
  // map.
  blink::WebBluetoothDeviceId device_id = *device_id_ptr;

  // 1. Remove from all three maps.
  CHECK(device_address_to_id_map_.erase(device_address));
  CHECK(device_id_to_address_map_.erase(device_id));
  CHECK(device_id_to_services_map_.erase(device_id));

  // Not all devices are connectable.
  device_id_to_connectable_map_.erase(device_id);

  // 2. Remove from set of ids.
  CHECK(device_id_set_.erase(device_id));
}

const blink::WebBluetoothDeviceId* BluetoothAllowedDevices::GetDeviceId(
    const std::string& device_address) {
  auto id_iter = device_address_to_id_map_.find(device_address);
  if (id_iter == device_address_to_id_map_.end()) {
    return nullptr;
  }
  return &(id_iter->second);
}

const std::string& BluetoothAllowedDevices::GetDeviceAddress(
    const blink::WebBluetoothDeviceId& device_id) {
  auto id_iter = device_id_to_address_map_.find(device_id);
  return id_iter == device_id_to_address_map_.end() ? base::EmptyString()
                                                    : id_iter->second;
}

bool BluetoothAllowedDevices::IsAllowedToAccessAtLeastOneService(
    const blink::WebBluetoothDeviceId& device_id) const {
  auto id_iter = device_id_to_services_map_.find(device_id);
  return id_iter == device_id_to_services_map_.end() ? false
                                                     : !id_iter->second.empty();
}

bool BluetoothAllowedDevices::IsAllowedToAccessService(
    const blink::WebBluetoothDeviceId& device_id,
    const BluetoothUUID& service_uuid) const {
  if (BluetoothBlocklist::Get().IsExcluded(service_uuid))
    return false;

  auto id_iter = device_id_to_services_map_.find(device_id);
  return id_iter == device_id_to_services_map_.end()
             ? false
             : base::Contains(id_iter->second, service_uuid);
}

bool BluetoothAllowedDevices::IsAllowedToGATTConnect(
    const blink::WebBluetoothDeviceId& device_id) const {
  auto id_iter = device_id_to_connectable_map_.find(device_id);
  if (id_iter == device_id_to_connectable_map_.end())
    return false;
  return id_iter->second;
}

bool BluetoothAllowedDevices::IsAllowedToAccessManufacturerData(
    const blink::WebBluetoothDeviceId& device_id,
    const uint16_t manufacturer_code) const {
  auto id_iter = device_id_to_manufacturers_map_.find(device_id);
  return id_iter == device_id_to_manufacturers_map_.end()
             ? false
             : base::Contains(id_iter->second, manufacturer_code);
}

blink::WebBluetoothDeviceId BluetoothAllowedDevices::GenerateUniqueDeviceId() {
  blink::WebBluetoothDeviceId device_id = blink::WebBluetoothDeviceId::Create();
  while (base::Contains(device_id_set_, device_id)) {
    LOG(WARNING) << "Generated repeated id.";
    device_id = blink::WebBluetoothDeviceId::Create();
  }
  return device_id;
}

void BluetoothAllowedDevices::AddUnionOfServicesTo(
    const blink::mojom::WebBluetoothRequestDeviceOptionsPtr& options,
    std::unordered_set<BluetoothUUID, device::BluetoothUUIDHash>*
        unionOfServices) {
  if (options->filters) {
    for (const auto& filter : options->filters.value()) {
      if (!filter->services)
        continue;

      for (const BluetoothUUID& uuid : filter->services.value())
        unionOfServices->insert(uuid);
    }
  }

  for (const BluetoothUUID& uuid : options->optional_services)
    unionOfServices->insert(uuid);
}

void BluetoothAllowedDevices::AddManufacturerDataTo(
    const blink::mojom::WebBluetoothRequestDeviceOptionsPtr& options,
    base::flat_set<uint16_t>* manufacturer_codes) {
  for (const uint16_t manufacturer_code : options->optional_manufacturer_data)
    manufacturer_codes->insert(manufacturer_code);
}

}  // namespace content
