// 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/bluetooth_advertisement_bluez.h"

#include <string>

#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/guid.h"
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
#include "base/strings/string_util.h"
#include "dbus/bus.h"
#include "dbus/object_path.h"
#include "device/bluetooth/bluetooth_adapter_bluez.h"
#include "device/bluetooth/dbus/bluetooth_le_advertising_manager_client.h"
#include "device/bluetooth/dbus/bluez_dbus_manager.h"
#include "third_party/cros_system_api/dbus/service_constants.h"

namespace {

void UnregisterFailure(device::BluetoothAdvertisement::ErrorCode error) {
  LOG(ERROR)
      << "BluetoothAdvertisementBlueZ::Unregister failed with error code = "
      << error;
}

device::BluetoothAdvertisement::ErrorCode GetErrorCodeFromErrorStrings(
    const std::string& error_name,
    const std::string& error_message) {
  if (error_name == bluetooth_advertising_manager::kErrorFailed ||
      error_name == bluetooth_advertising_manager::kErrorAlreadyExists) {
    return device::BluetoothAdvertisement::ErrorCode::
        ERROR_ADVERTISEMENT_ALREADY_EXISTS;
  } else if (error_name ==
             bluetooth_advertising_manager::kErrorInvalidArguments) {
    return device::BluetoothAdvertisement::ErrorCode::
        ERROR_ADVERTISEMENT_INVALID_LENGTH;
  } else if (error_name == bluetooth_advertising_manager::kErrorDoesNotExist) {
    return device::BluetoothAdvertisement::ErrorCode::
        ERROR_ADVERTISEMENT_DOES_NOT_EXIST;
  }
  return device::BluetoothAdvertisement::ErrorCode::
      INVALID_ADVERTISEMENT_ERROR_CODE;
}

void RegisterErrorCallbackConnector(
    const device::BluetoothAdapter::CreateAdvertisementErrorCallback&
        error_callback,
    const std::string& error_name,
    const std::string& error_message) {
  LOG(ERROR) << "Error while registering advertisement. error_name = "
             << error_name << ", error_message = " << error_message;
  error_callback.Run(GetErrorCodeFromErrorStrings(error_name, error_message));
}

void UnregisterErrorCallbackConnector(
    const device::BluetoothAdapter::CreateAdvertisementErrorCallback&
        error_callback,
    const std::string& error_name,
    const std::string& error_message) {
  LOG(WARNING) << "Error while unregistering advertisement. error_name = "
               << error_name << ", error_message = " << error_message;
  error_callback.Run(GetErrorCodeFromErrorStrings(error_name, error_message));
}

}  // namespace

namespace bluez {

BluetoothAdvertisementBlueZ::BluetoothAdvertisementBlueZ(
    scoped_ptr<device::BluetoothAdvertisement::Data> data,
    scoped_refptr<BluetoothAdapterBlueZ> adapter)
    : adapter_(adapter) {
  // Generate a new object path - make sure that we strip any -'s from the
  // generated GUID string since object paths can only contain alphanumeric
  // characters and _ characters.
  std::string GuidString = base::GenerateGUID();
  base::RemoveChars(GuidString, "-", &GuidString);
  dbus::ObjectPath advertisement_object_path =
      dbus::ObjectPath("/org/chromium/bluetooth_advertisement/" + GuidString);

  DCHECK(bluez::BluezDBusManager::Get());
  provider_ = bluez::BluetoothLEAdvertisementServiceProvider::Create(
      bluez::BluezDBusManager::Get()->GetSystemBus(), advertisement_object_path,
      this,
      static_cast<
          bluez::BluetoothLEAdvertisementServiceProvider::AdvertisementType>(
          data->type()),
      data->service_uuids(), data->manufacturer_data(), data->solicit_uuids(),
      data->service_data());
}

void BluetoothAdvertisementBlueZ::Register(
    const base::Closure& success_callback,
    const device::BluetoothAdapter::CreateAdvertisementErrorCallback&
        error_callback) {
  DCHECK(bluez::BluezDBusManager::Get());
  bluez::BluezDBusManager::Get()
      ->GetBluetoothLEAdvertisingManagerClient()
      ->RegisterAdvertisement(
          adapter_->object_path(), provider_->object_path(), success_callback,
          base::Bind(&RegisterErrorCallbackConnector, error_callback));
}

BluetoothAdvertisementBlueZ::~BluetoothAdvertisementBlueZ() {
  Unregister(base::Bind(&base::DoNothing), base::Bind(&UnregisterFailure));
}

void BluetoothAdvertisementBlueZ::Unregister(
    const SuccessCallback& success_callback,
    const ErrorCallback& error_callback) {
  // If we don't have a provider, that means we have already been unregistered,
  // return an error.
  if (!provider_) {
    error_callback.Run(device::BluetoothAdvertisement::ErrorCode::
                           ERROR_ADVERTISEMENT_DOES_NOT_EXIST);
    return;
  }

  DCHECK(bluez::BluezDBusManager::Get());
  bluez::BluezDBusManager::Get()
      ->GetBluetoothLEAdvertisingManagerClient()
      ->UnregisterAdvertisement(
          adapter_->object_path(), provider_->object_path(), success_callback,
          base::Bind(&UnregisterErrorCallbackConnector, error_callback));
  provider_.reset();
}

void BluetoothAdvertisementBlueZ::Released() {
  LOG(WARNING) << "Advertisement released.";
  provider_.reset();
  FOR_EACH_OBSERVER(BluetoothAdvertisement::Observer, observers_,
                    AdvertisementReleased(this));
}

}  // namespace bluez
