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

#include "components/permissions/bluetooth_delegate_impl.h"

#include "base/observer_list.h"
#include "base/strings/utf_string_conversions.h"
#include "components/permissions/contexts/bluetooth_chooser_context.h"
#include "content/public/browser/render_frame_host.h"
#include "device/bluetooth/bluetooth_device.h"
#include "device/bluetooth/public/cpp/bluetooth_uuid.h"
#include "third_party/blink/public/common/bluetooth/web_bluetooth_device_id.h"
#include "third_party/blink/public/mojom/bluetooth/web_bluetooth.mojom.h"

using blink::WebBluetoothDeviceId;
using content::RenderFrameHost;
using device::BluetoothUUID;

namespace permissions {

BluetoothDelegateImpl::BluetoothDelegateImpl(std::unique_ptr<Client> client)
    : client_(std::move(client)) {}

BluetoothDelegateImpl::~BluetoothDelegateImpl() = default;

std::unique_ptr<content::BluetoothChooser>
BluetoothDelegateImpl::RunBluetoothChooser(
    content::RenderFrameHost* frame,
    const content::BluetoothChooser::EventHandler& event_handler) {
  return client_->RunBluetoothChooser(frame, event_handler);
}

std::unique_ptr<content::BluetoothScanningPrompt>
BluetoothDelegateImpl::ShowBluetoothScanningPrompt(
    content::RenderFrameHost* frame,
    const content::BluetoothScanningPrompt::EventHandler& event_handler) {
  return client_->ShowBluetoothScanningPrompt(frame, event_handler);
}

void BluetoothDelegateImpl::ShowDevicePairPrompt(
    RenderFrameHost* frame,
    const std::u16string& device_identifier,
    PairPromptCallback callback,
    PairingKind pairing_kind,
    const absl::optional<std::u16string>& pin) {
  client_->ShowBluetoothDevicePairDialog(
      frame, device_identifier, std::move(callback), pairing_kind, pin);
}

WebBluetoothDeviceId BluetoothDelegateImpl::GetWebBluetoothDeviceId(
    RenderFrameHost* frame,
    const std::string& device_address) {
  return client_->GetBluetoothChooserContext(frame)->GetWebBluetoothDeviceId(
      frame->GetMainFrame()->GetLastCommittedOrigin(), device_address);
}

std::string BluetoothDelegateImpl::GetDeviceAddress(
    RenderFrameHost* frame,
    const WebBluetoothDeviceId& device_id) {
  return client_->GetBluetoothChooserContext(frame)->GetDeviceAddress(
      frame->GetMainFrame()->GetLastCommittedOrigin(), device_id);
}

WebBluetoothDeviceId BluetoothDelegateImpl::AddScannedDevice(
    RenderFrameHost* frame,
    const std::string& device_address) {
  return client_->GetBluetoothChooserContext(frame)->AddScannedDevice(
      frame->GetMainFrame()->GetLastCommittedOrigin(), device_address);
}

WebBluetoothDeviceId BluetoothDelegateImpl::GrantServiceAccessPermission(
    RenderFrameHost* frame,
    const device::BluetoothDevice* device,
    const blink::mojom::WebBluetoothRequestDeviceOptions* options) {
  return client_->GetBluetoothChooserContext(frame)
      ->GrantServiceAccessPermission(
          frame->GetMainFrame()->GetLastCommittedOrigin(), device, options);
}

bool BluetoothDelegateImpl::HasDevicePermission(
    RenderFrameHost* frame,
    const WebBluetoothDeviceId& device_id) {
  return client_->GetBluetoothChooserContext(frame)->HasDevicePermission(
      frame->GetMainFrame()->GetLastCommittedOrigin(), device_id);
}

void BluetoothDelegateImpl::RevokeDevicePermissionWebInitiated(
    RenderFrameHost* frame,
    const WebBluetoothDeviceId& device_id) {
  client_->GetBluetoothChooserContext(frame)
      ->RevokeDevicePermissionWebInitiated(
          frame->GetMainFrame()->GetLastCommittedOrigin(), device_id);
}

bool BluetoothDelegateImpl::IsAllowedToAccessService(
    RenderFrameHost* frame,
    const WebBluetoothDeviceId& device_id,
    const BluetoothUUID& service) {
  return client_->GetBluetoothChooserContext(frame)->IsAllowedToAccessService(
      frame->GetMainFrame()->GetLastCommittedOrigin(), device_id, service);
}

bool BluetoothDelegateImpl::IsAllowedToAccessAtLeastOneService(
    RenderFrameHost* frame,
    const WebBluetoothDeviceId& device_id) {
  return client_->GetBluetoothChooserContext(frame)
      ->IsAllowedToAccessAtLeastOneService(
          frame->GetMainFrame()->GetLastCommittedOrigin(), device_id);
}

bool BluetoothDelegateImpl::IsAllowedToAccessManufacturerData(
    RenderFrameHost* frame,
    const WebBluetoothDeviceId& device_id,
    uint16_t manufacturer_code) {
  return client_->GetBluetoothChooserContext(frame)
      ->IsAllowedToAccessManufacturerData(
          frame->GetMainFrame()->GetLastCommittedOrigin(), device_id,
          manufacturer_code);
}

void BluetoothDelegateImpl::AddFramePermissionObserver(
    FramePermissionObserver* observer) {
  std::unique_ptr<ChooserContextPermissionObserver>& chooser_observer =
      chooser_observers_[observer->GetRenderFrameHost()];
  if (!chooser_observer) {
    chooser_observer = std::make_unique<ChooserContextPermissionObserver>(
        this,
        client_->GetBluetoothChooserContext(observer->GetRenderFrameHost()));
  }

  chooser_observer->AddFramePermissionObserver(observer);
}

void BluetoothDelegateImpl::RemoveFramePermissionObserver(
    FramePermissionObserver* observer) {
  auto it = chooser_observers_.find(observer->GetRenderFrameHost());
  if (it == chooser_observers_.end())
    return;
  it->second->RemoveFramePermissionObserver(observer);
}

std::vector<blink::mojom::WebBluetoothDevicePtr>
BluetoothDelegateImpl::GetPermittedDevices(content::RenderFrameHost* frame) {
  auto* context = client_->GetBluetoothChooserContext(frame);
  std::vector<std::unique_ptr<ObjectPermissionContextBase::Object>> objects =
      context->GetGrantedObjects(
          frame->GetMainFrame()->GetLastCommittedOrigin());
  std::vector<blink::mojom::WebBluetoothDevicePtr> permitted_devices;

  for (const auto& object : objects) {
    auto permitted_device = blink::mojom::WebBluetoothDevice::New();
    permitted_device->id =
        BluetoothChooserContext::GetObjectDeviceId(object->value);
    permitted_device->name =
        base::UTF16ToUTF8(context->GetObjectDisplayName(object->value));
    permitted_devices.push_back(std::move(permitted_device));
  }

  return permitted_devices;
}

BluetoothDelegateImpl::ChooserContextPermissionObserver::
    ChooserContextPermissionObserver(BluetoothDelegateImpl* owning_delegate,
                                     ObjectPermissionContextBase* context)
    : owning_delegate_(owning_delegate) {
  observer_.Observe(context);
}

BluetoothDelegateImpl::ChooserContextPermissionObserver::
    ~ChooserContextPermissionObserver() = default;

void BluetoothDelegateImpl::ChooserContextPermissionObserver::
    OnPermissionRevoked(const url::Origin& origin) {
  observers_pending_removal_.clear();
  is_traversing_observers_ = true;

  for (auto& observer : observer_list_)
    observer.OnPermissionRevoked(origin);

  is_traversing_observers_ = false;
  for (FramePermissionObserver* observer : observers_pending_removal_)
    RemoveFramePermissionObserver(observer);
}

void BluetoothDelegateImpl::ChooserContextPermissionObserver::
    AddFramePermissionObserver(FramePermissionObserver* observer) {
  observer_list_.AddObserver(observer);
}

void BluetoothDelegateImpl::ChooserContextPermissionObserver::
    RemoveFramePermissionObserver(FramePermissionObserver* observer) {
  if (is_traversing_observers_) {
    observers_pending_removal_.emplace_back(observer);
    return;
  }

  observer_list_.RemoveObserver(observer);
  if (observer_list_.empty())
    owning_delegate_->chooser_observers_.erase(observer->GetRenderFrameHost());
  // Previous call destructed this instance. Don't add code after this.
}

}  // namespace permissions
