// Copyright 2015 The Chromium 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 "device/bluetooth/bluez/bluetooth_adapter_profile_bluez.h"

#include <memory>
#include <string>
#include <utility>

#include "base/bind.h"
#include "base/logging.h"
#include "base/strings/string_util.h"
#include "dbus/bus.h"
#include "dbus/object_path.h"
#include "device/bluetooth/bluetooth_uuid.h"
#include "device/bluetooth/bluez/bluetooth_adapter_bluez.h"
#include "device/bluetooth/dbus/bluetooth_profile_service_provider.h"
#include "device/bluetooth/dbus/bluez_dbus_manager.h"

namespace bluez {

// static
void BluetoothAdapterProfileBlueZ::Register(
    const device::BluetoothUUID& uuid,
    const bluez::BluetoothProfileManagerClient::Options& options,
    const ProfileRegisteredCallback& success_callback,
    const bluez::BluetoothProfileManagerClient::ErrorCallback& error_callback) {
  std::unique_ptr<BluetoothAdapterProfileBlueZ> profile(
      new BluetoothAdapterProfileBlueZ(uuid));

  VLOG(1) << "Registering profile: " << profile->object_path().value();
  const dbus::ObjectPath& object_path = profile->object_path();
  bluez::BluezDBusManager::Get()
      ->GetBluetoothProfileManagerClient()
      ->RegisterProfile(object_path, uuid.canonical_value(), options,
                        base::Bind(success_callback, base::Passed(&profile)),
                        error_callback);
}

BluetoothAdapterProfileBlueZ::BluetoothAdapterProfileBlueZ(
    const device::BluetoothUUID& uuid)
    : uuid_(uuid), weak_ptr_factory_(this) {
  std::string uuid_path;
  base::ReplaceChars(uuid.canonical_value(), ":-", "_", &uuid_path);
  object_path_ =
      dbus::ObjectPath("/org/chromium/bluetooth_profile/" + uuid_path);

  dbus::Bus* system_bus = bluez::BluezDBusManager::Get()->GetSystemBus();
  profile_.reset(bluez::BluetoothProfileServiceProvider::Create(
      system_bus, object_path_, this));
  DCHECK(profile_.get());
}

BluetoothAdapterProfileBlueZ::~BluetoothAdapterProfileBlueZ() {}

bool BluetoothAdapterProfileBlueZ::SetDelegate(
    const dbus::ObjectPath& device_path,
    bluez::BluetoothProfileServiceProvider::Delegate* delegate) {
  DCHECK(delegate);
  VLOG(1) << "SetDelegate: " << object_path_.value() << " dev "
          << device_path.value();

  if (delegates_.find(device_path.value()) != delegates_.end()) {
    return false;
  }

  delegates_[device_path.value()] = delegate;
  return true;
}

void BluetoothAdapterProfileBlueZ::RemoveDelegate(
    const dbus::ObjectPath& device_path,
    const base::Closure& unregistered_callback) {
  VLOG(1) << object_path_.value() << " dev " << device_path.value()
          << ": RemoveDelegate";

  if (delegates_.find(device_path.value()) == delegates_.end())
    return;

  delegates_.erase(device_path.value());

  if (delegates_.size() != 0)
    return;

  VLOG(1) << device_path.value() << " No delegates left, unregistering.";

  // No users left, release the profile.
  bluez::BluezDBusManager::Get()
      ->GetBluetoothProfileManagerClient()
      ->UnregisterProfile(
          object_path_, unregistered_callback,
          base::Bind(&BluetoothAdapterProfileBlueZ::OnUnregisterProfileError,
                     weak_ptr_factory_.GetWeakPtr(), unregistered_callback));
}

void BluetoothAdapterProfileBlueZ::OnUnregisterProfileError(
    const base::Closure& unregistered_callback,
    const std::string& error_name,
    const std::string& error_message) {
  LOG(WARNING) << this->object_path().value()
               << ": Failed to unregister profile: " << error_name << ": "
               << error_message;

  unregistered_callback.Run();
}

// bluez::BluetoothProfileServiceProvider::Delegate:
void BluetoothAdapterProfileBlueZ::Released() {
  VLOG(1) << object_path_.value() << ": Release";
}

void BluetoothAdapterProfileBlueZ::NewConnection(
    const dbus::ObjectPath& device_path,
    base::ScopedFD fd,
    const bluez::BluetoothProfileServiceProvider::Delegate::Options& options,
    const ConfirmationCallback& callback) {
  dbus::ObjectPath delegate_path = device_path;

  if (delegates_.find(device_path.value()) == delegates_.end())
    delegate_path = dbus::ObjectPath("");

  if (delegates_.find(delegate_path.value()) == delegates_.end()) {
    VLOG(1) << object_path_.value() << ": New connection for device "
            << device_path.value() << " which has no delegates!";
    callback.Run(REJECTED);
    return;
  }

  delegates_[delegate_path.value()]->NewConnection(device_path, std::move(fd),
                                                   options, callback);
}

void BluetoothAdapterProfileBlueZ::RequestDisconnection(
    const dbus::ObjectPath& device_path,
    const ConfirmationCallback& callback) {
  dbus::ObjectPath delegate_path = device_path;

  if (delegates_.find(device_path.value()) == delegates_.end())
    delegate_path = dbus::ObjectPath("");

  if (delegates_.find(delegate_path.value()) == delegates_.end()) {
    VLOG(1) << object_path_.value() << ": RequestDisconnection for device "
            << device_path.value() << " which has no delegates!";
    return;
  }

  delegates_[delegate_path.value()]->RequestDisconnection(device_path,
                                                          callback);
}

void BluetoothAdapterProfileBlueZ::Cancel() {
  // Cancel() should only go to a delegate accepting connections.
  if (delegates_.find("") == delegates_.end()) {
    VLOG(1) << object_path_.value() << ": Cancel with no delegate!";
    return;
  }

  delegates_[""]->Cancel();
}

}  // namespace bluez
