//
//  Copyright (C) 2015 Google, Inc.
//
//  Licensed under the Apache License, Version 2.0 (the "License");
//  you may not use this file except in compliance with the License.
//  You may obtain a copy of the License at:
//
//  http://www.apache.org/licenses/LICENSE-2.0
//
//  Unless required by applicable law or agreed to in writing, software
//  distributed under the License is distributed on an "AS IS" BASIS,
//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//  See the License for the specific language governing permissions and
//  limitations under the License.
//

#include "service/low_energy_advertiser.h"

#include <base/bind.h>
#include <base/logging.h>

#include "service/adapter.h"
#include "service/common/bluetooth/util/address_helper.h"
#include "service/logging_helpers.h"
#include "stack/include/bt_types.h"
#include "stack/include/hcidefs.h"

using std::lock_guard;
using std::mutex;

namespace bluetooth {

namespace {

BLEStatus GetBLEStatus(int status) {
  if (status == BT_STATUS_FAIL) return BLE_STATUS_FAILURE;

  return static_cast<BLEStatus>(status);
}

// The Bluetooth Core Specification defines time interval (e.g. Page Scan
// Interval, Advertising Interval, etc) units as 0.625 milliseconds (or 1
// Baseband slot). The HAL advertising functions expect the interval in this
// unit. This function maps an AdvertiseSettings::Mode value to the
// corresponding time unit.
int GetAdvertisingIntervalUnit(AdvertiseSettings::Mode mode) {
  int ms;

  switch (mode) {
    case AdvertiseSettings::MODE_BALANCED:
      ms = kAdvertisingIntervalMediumMs;
      break;
    case AdvertiseSettings::MODE_LOW_LATENCY:
      ms = kAdvertisingIntervalLowMs;
      break;
    case AdvertiseSettings::MODE_LOW_POWER:
    // Fall through
    default:
      ms = kAdvertisingIntervalHighMs;
      break;
  }

  // Convert milliseconds to Bluetooth units.
  return (ms * 1000) / 625;
}

int8_t GetAdvertisingTxPower(AdvertiseSettings::TxPowerLevel tx_power) {
  int8_t power;

  switch (tx_power) {
    case AdvertiseSettings::TX_POWER_LEVEL_ULTRA_LOW:
      power = -21;
      break;
    case AdvertiseSettings::TX_POWER_LEVEL_LOW:
      power = -15;
      break;
    case AdvertiseSettings::TX_POWER_LEVEL_MEDIUM:
      power = -7;
      break;
    case AdvertiseSettings::TX_POWER_LEVEL_HIGH:
    // Fall through
    default:
      power = 1;
      break;
  }

  return power;
}

void GetAdvertiseParams(const AdvertiseSettings& settings, bool has_scan_rsp,
                        AdvertiseParameters* out_params) {
  CHECK(out_params);

  out_params->min_interval = GetAdvertisingIntervalUnit(settings.mode());
  out_params->max_interval =
      out_params->min_interval + kAdvertisingIntervalDeltaUnit;

  if (settings.connectable())
    out_params->advertising_event_properties =
        kAdvertisingEventTypeLegacyConnectable;
  else if (has_scan_rsp)
    out_params->advertising_event_properties =
        kAdvertisingEventTypeLegacyScannable;
  else
    out_params->advertising_event_properties =
        kAdvertisingEventTypeLegacyNonConnectable;

  out_params->channel_map = kAdvertisingChannelAll;
  out_params->tx_power = GetAdvertisingTxPower(settings.tx_power_level());

  // TODO: expose those new setting through AdvertiseSettings
  out_params->primary_advertising_phy = 0x01;
  out_params->secondary_advertising_phy = 0x01;
  out_params->scan_request_notification_enable = 0;
}

void DoNothing(uint8_t status) {}

}  // namespace

// LowEnergyAdvertiser implementation
// ========================================================

LowEnergyAdvertiser::LowEnergyAdvertiser(const UUID& uuid, int advertiser_id)
    : app_identifier_(uuid),
      advertiser_id_(advertiser_id),
      adv_started_(false),
      adv_start_callback_(nullptr),
      adv_stop_callback_(nullptr) {}

LowEnergyAdvertiser::~LowEnergyAdvertiser() {
  // Automatically unregister the advertiser.
  VLOG(1) << "LowEnergyAdvertiser unregistering advertiser: " << advertiser_id_;

  // Stop advertising and ignore the result.
  hal::BluetoothGattInterface::Get()->GetAdvertiserHALInterface()->Enable(
      advertiser_id_, false, base::Bind(&DoNothing), 0, 0,
      base::Bind(&DoNothing));
  hal::BluetoothGattInterface::Get()->GetAdvertiserHALInterface()->Unregister(
      advertiser_id_);
}

bool LowEnergyAdvertiser::StartAdvertising(const AdvertiseSettings& settings,
                                           const AdvertiseData& advertise_data,
                                           const AdvertiseData& scan_response,
                                           const StatusCallback& callback) {
  VLOG(2) << __func__;
  lock_guard<mutex> lock(adv_fields_lock_);

  if (IsAdvertisingStarted()) {
    LOG(WARNING) << "Already advertising";
    return false;
  }

  if (IsStartingAdvertising()) {
    LOG(WARNING) << "StartAdvertising already pending";
    return false;
  }

  if (!advertise_data.IsValid()) {
    LOG(ERROR) << "Invalid advertising data";
    return false;
  }

  if (!scan_response.IsValid()) {
    LOG(ERROR) << "Invalid scan response data";
    return false;
  }

  advertise_settings_ = settings;

  AdvertiseParameters params;
  GetAdvertiseParams(settings, !scan_response.data().empty(), &params);

  hal::BluetoothGattInterface::Get()
      ->GetAdvertiserHALInterface()
      ->StartAdvertising(
          advertiser_id_,
          base::Bind(&LowEnergyAdvertiser::EnableCallback,
                     base::Unretained(this), true, advertiser_id_),
          params, advertise_data.data(), scan_response.data(),
          settings.timeout().InSeconds(),
          base::Bind(&LowEnergyAdvertiser::EnableCallback,
                     base::Unretained(this), false, advertiser_id_));
  ;

  adv_start_callback_.reset(new StatusCallback(callback));
  return true;
}

bool LowEnergyAdvertiser::StopAdvertising(const StatusCallback& callback) {
  VLOG(2) << __func__;
  lock_guard<mutex> lock(adv_fields_lock_);

  if (!IsAdvertisingStarted()) {
    LOG(ERROR) << "Not advertising";
    return false;
  }

  if (IsStoppingAdvertising()) {
    LOG(ERROR) << "StopAdvertising already pending";
    return false;
  }

  hal::BluetoothGattInterface::Get()->GetAdvertiserHALInterface()->Enable(
      advertiser_id_, false,
      base::Bind(&LowEnergyAdvertiser::EnableCallback, base::Unretained(this),
                 false, advertiser_id_),
      0, 0, base::Bind(&LowEnergyAdvertiser::EnableCallback,
                       base::Unretained(this), false, advertiser_id_));

  // OK to set this at the end since we're still holding |adv_fields_lock_|.
  adv_stop_callback_.reset(new StatusCallback(callback));

  return true;
}

bool LowEnergyAdvertiser::IsAdvertisingStarted() const {
  return adv_started_.load();
}

bool LowEnergyAdvertiser::IsStartingAdvertising() const {
  return !IsAdvertisingStarted() && adv_start_callback_;
}

bool LowEnergyAdvertiser::IsStoppingAdvertising() const {
  return IsAdvertisingStarted() && adv_stop_callback_;
}

const UUID& LowEnergyAdvertiser::GetAppIdentifier() const {
  return app_identifier_;
}

int LowEnergyAdvertiser::GetInstanceId() const { return advertiser_id_; }

void LowEnergyAdvertiser::EnableCallback(bool enable, uint8_t advertiser_id,
                                         uint8_t status) {
  if (advertiser_id != advertiser_id_) return;

  lock_guard<mutex> lock(adv_fields_lock_);

  VLOG(1) << __func__ << "advertiser_id: " << advertiser_id
          << " status: " << status << " enable: " << enable;

  if (enable) {
    CHECK(adv_start_callback_);
    CHECK(!adv_stop_callback_);

    // Terminate operation in case of error.
    if (status != BT_STATUS_SUCCESS) {
      LOG(ERROR) << "Failed to enable multi-advertising";
      InvokeAndClearStartCallback(GetBLEStatus(status));
      return;
    }

    // All pending tasks are complete. Report success.
    adv_started_ = true;
    InvokeAndClearStartCallback(BLE_STATUS_SUCCESS);

  } else {
    CHECK(!adv_start_callback_);
    CHECK(adv_stop_callback_);

    if (status == BT_STATUS_SUCCESS) {
      VLOG(1) << "Multi-advertising stopped for advertiser_id: "
              << advertiser_id;
      adv_started_ = false;
    } else {
      LOG(ERROR) << "Failed to stop multi-advertising";
    }

    InvokeAndClearStopCallback(GetBLEStatus(status));
  }
}

void LowEnergyAdvertiser::InvokeAndClearStartCallback(BLEStatus status) {
  // We allow NULL callbacks.
  if (*adv_start_callback_) (*adv_start_callback_)(status);

  adv_start_callback_ = nullptr;
}

void LowEnergyAdvertiser::InvokeAndClearStopCallback(BLEStatus status) {
  // We allow NULL callbacks.
  if (*adv_stop_callback_) (*adv_stop_callback_)(status);

  adv_stop_callback_ = nullptr;
}

// LowEnergyAdvertiserFactory implementation
// ========================================================

LowEnergyAdvertiserFactory::LowEnergyAdvertiserFactory() {}

LowEnergyAdvertiserFactory::~LowEnergyAdvertiserFactory() {}

bool LowEnergyAdvertiserFactory::RegisterInstance(
    const UUID& app_uuid, const RegisterCallback& callback) {
  VLOG(1) << __func__;
  lock_guard<mutex> lock(pending_calls_lock_);

  if (pending_calls_.find(app_uuid) != pending_calls_.end()) {
    LOG(ERROR) << "Low-Energy advertiser with given UUID already registered - "
               << "UUID: " << app_uuid.ToString();
    return false;
  }

  BleAdvertiserInterface* hal_iface =
      hal::BluetoothGattInterface::Get()->GetAdvertiserHALInterface();

  VLOG(1) << __func__ << " calling register!";
  hal_iface->RegisterAdvertiser(
      base::Bind(&LowEnergyAdvertiserFactory::RegisterAdvertiserCallback,
                 base::Unretained(this), callback, app_uuid));
  VLOG(1) << __func__ << " call finished!";

  pending_calls_.insert(app_uuid);

  return true;
}

void LowEnergyAdvertiserFactory::RegisterAdvertiserCallback(
    const RegisterCallback& callback, const UUID& app_uuid,
    uint8_t advertiser_id, uint8_t status) {
  VLOG(1) << __func__;
  lock_guard<mutex> lock(pending_calls_lock_);

  auto iter = pending_calls_.find(app_uuid);
  if (iter == pending_calls_.end()) {
    VLOG(1) << "Ignoring callback for unknown app_id: " << app_uuid.ToString();
    return;
  }

  // No need to construct a advertiser if the call wasn't successful.
  std::unique_ptr<LowEnergyAdvertiser> advertiser;
  BLEStatus result = BLE_STATUS_FAILURE;
  if (status == BT_STATUS_SUCCESS) {
    advertiser.reset(new LowEnergyAdvertiser(app_uuid, advertiser_id));

    result = BLE_STATUS_SUCCESS;
  }

  // Notify the result via the result callback.
  callback(result, app_uuid, std::move(advertiser));

  pending_calls_.erase(iter);
}

}  // namespace bluetooth
