/******************************************************************************
 *
 *  Copyright (C) 2016 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.
 *
 ******************************************************************************/

#define LOG_TAG "bt_btif_ble_advertiser"

#include <hardware/bluetooth.h>
#include <hardware/bt_gatt.h>

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

#include "ble_advertiser.h"
#include "bta_closure_api.h"
#include "btif_common.h"

using base::Bind;
using base::Owned;
using std::vector;

namespace {

template <typename T>
class OwnedArrayWrapper {
 public:
  explicit OwnedArrayWrapper(T* o) : ptr_(o) {}
  ~OwnedArrayWrapper() { delete[] ptr_; }
  T* get() const { return ptr_; }
  OwnedArrayWrapper(OwnedArrayWrapper&& other) {
    ptr_ = other.ptr_;
    other.ptr_ = NULL;
  }

 private:
  mutable T* ptr_;
};

template <typename T>
T* Unwrap(const OwnedArrayWrapper<T>& o) {
  return o.get();
}

template <typename T>
static inline OwnedArrayWrapper<T> OwnedArray(T* o) {
  return OwnedArrayWrapper<T>(o);
}

void parseParams(tBTM_BLE_ADV_PARAMS* p_params,
                 const AdvertiseParameters& params) {
  p_params->advertising_event_properties = params.advertising_event_properties;
  p_params->adv_int_min = params.min_interval;
  p_params->adv_int_max = params.max_interval;
  p_params->channel_map = params.channel_map;
  p_params->adv_filter_policy = 0;
  p_params->tx_power = params.tx_power;
  p_params->primary_advertising_phy = params.primary_advertising_phy;
  p_params->secondary_advertising_phy = params.secondary_advertising_phy;
  p_params->scan_request_notification_enable =
      params.scan_request_notification_enable;
}

void parsePeriodicParams(tBLE_PERIODIC_ADV_PARAMS* p_periodic_params,
                         PeriodicAdvertisingParameters periodic_params) {
  p_periodic_params->enable = periodic_params.enable;
  p_periodic_params->min_interval = periodic_params.min_interval;
  p_periodic_params->max_interval = periodic_params.max_interval;
  p_periodic_params->periodic_advertising_properties =
      periodic_params.periodic_advertising_properties;
}

class BleAdvertiserInterfaceImpl : public BleAdvertiserInterface {
  ~BleAdvertiserInterfaceImpl(){};

  void RegisterAdvertiserCb(IdStatusCallback cb, uint8_t advertiser_id,
                            uint8_t status) {
    LOG(INFO) << __func__ << " status: " << +status
              << " , adveriser_id: " << +advertiser_id;
    do_in_jni_thread(Bind(cb, advertiser_id, status));
  }

  void RegisterAdvertiser(IdStatusCallback cb) override {
    do_in_bta_thread(
        FROM_HERE, Bind(&BleAdvertisingManager::RegisterAdvertiser,
                        base::Unretained(BleAdvertisingManager::Get()),
                        Bind(&BleAdvertiserInterfaceImpl::RegisterAdvertiserCb,
                             base::Unretained(this), cb)));
  }

  void Unregister(uint8_t advertiser_id) override {
    do_in_bta_thread(
        FROM_HERE,
        Bind(
            [](uint8_t advertiser_id) {
              if (!BleAdvertisingManager::IsInitialized()) {
                LOG(WARNING) << "Stack already shutdown";
                return;
              }
              BleAdvertisingManager::Get()->Unregister(advertiser_id);
            },
            advertiser_id));
  }

  void GetOwnAddress(uint8_t advertiser_id, GetAddressCallback cb) override {
    do_in_bta_thread(FROM_HERE,
                     Bind(&BleAdvertisingManager::GetOwnAddress,
                          base::Unretained(BleAdvertisingManager::Get()),
                          advertiser_id, jni_thread_wrapper(FROM_HERE, cb)));
  }

  void SetParameters(uint8_t advertiser_id, AdvertiseParameters params,
                     ParametersCallback cb) override {
    VLOG(1) << __func__;

    tBTM_BLE_ADV_PARAMS* p_params = new tBTM_BLE_ADV_PARAMS;
    parseParams(p_params, params);

    do_in_bta_thread(
        FROM_HERE,
        Bind(&BleAdvertisingManager::SetParameters,
             base::Unretained(BleAdvertisingManager::Get()), advertiser_id,
             base::Owned(p_params), jni_thread_wrapper(FROM_HERE, cb)));
  }

  void SetData(int advertiser_id, bool set_scan_rsp, vector<uint8_t> data,
               StatusCallback cb) override {
    do_in_bta_thread(
        FROM_HERE,
        Bind(&BleAdvertisingManager::SetData,
             base::Unretained(BleAdvertisingManager::Get()), advertiser_id,
             set_scan_rsp, std::move(data), jni_thread_wrapper(FROM_HERE, cb)));
  }

  void Enable(uint8_t advertiser_id, bool enable, StatusCallback cb,
              uint16_t duration, uint8_t maxExtAdvEvents,
              StatusCallback timeout_cb) override {
    VLOG(1) << __func__ << " advertiser_id: " << +advertiser_id
            << " ,enable: " << enable;

    do_in_bta_thread(
        FROM_HERE,
        Bind(&BleAdvertisingManager::Enable,
             base::Unretained(BleAdvertisingManager::Get()), advertiser_id,
             enable, jni_thread_wrapper(FROM_HERE, cb), duration,
             maxExtAdvEvents, jni_thread_wrapper(FROM_HERE, timeout_cb)));
  }

  void StartAdvertising(uint8_t advertiser_id, StatusCallback cb,
                        AdvertiseParameters params,
                        std::vector<uint8_t> advertise_data,
                        std::vector<uint8_t> scan_response_data, int timeout_s,
                        MultiAdvCb timeout_cb) override {
    VLOG(1) << __func__;

    tBTM_BLE_ADV_PARAMS* p_params = new tBTM_BLE_ADV_PARAMS;
    parseParams(p_params, params);

    do_in_bta_thread(
        FROM_HERE,
        Bind(&BleAdvertisingManager::StartAdvertising,
             base::Unretained(BleAdvertisingManager::Get()), advertiser_id,
             jni_thread_wrapper(FROM_HERE, cb), base::Owned(p_params),
             std::move(advertise_data), std::move(scan_response_data),
             timeout_s * 100, jni_thread_wrapper(FROM_HERE, timeout_cb)));
  }

  void StartAdvertisingSet(IdTxPowerStatusCallback cb,
                           AdvertiseParameters params,
                           std::vector<uint8_t> advertise_data,
                           std::vector<uint8_t> scan_response_data,
                           PeriodicAdvertisingParameters periodic_params,
                           std::vector<uint8_t> periodic_data,
                           uint16_t duration, uint8_t maxExtAdvEvents,
                           IdStatusCallback timeout_cb) override {
    VLOG(1) << __func__;

    tBTM_BLE_ADV_PARAMS* p_params = new tBTM_BLE_ADV_PARAMS;
    parseParams(p_params, params);

    tBLE_PERIODIC_ADV_PARAMS* p_periodic_params = new tBLE_PERIODIC_ADV_PARAMS;
    parsePeriodicParams(p_periodic_params, periodic_params);

    do_in_bta_thread(
        FROM_HERE,
        Bind(&BleAdvertisingManager::StartAdvertisingSet,
             base::Unretained(BleAdvertisingManager::Get()),
             jni_thread_wrapper(FROM_HERE, cb), base::Owned(p_params),
             std::move(advertise_data), std::move(scan_response_data),
             base::Owned(p_periodic_params), std::move(periodic_data), duration,
             maxExtAdvEvents, jni_thread_wrapper(FROM_HERE, timeout_cb)));
  }

  void SetPeriodicAdvertisingParameters(
      int advertiser_id, PeriodicAdvertisingParameters periodic_params,
      StatusCallback cb) override {
    VLOG(1) << __func__ << " advertiser_id: " << +advertiser_id;

    tBLE_PERIODIC_ADV_PARAMS* p_periodic_params = new tBLE_PERIODIC_ADV_PARAMS;
    parsePeriodicParams(p_periodic_params, periodic_params);

    do_in_bta_thread(
        FROM_HERE,
        Bind(&BleAdvertisingManager::SetPeriodicAdvertisingParameters,
             base::Unretained(BleAdvertisingManager::Get()), advertiser_id,
             base::Owned(p_periodic_params),
             jni_thread_wrapper(FROM_HERE, cb)));
  }

  void SetPeriodicAdvertisingData(int advertiser_id, std::vector<uint8_t> data,
                                  StatusCallback cb) override {
    VLOG(1) << __func__ << " advertiser_id: " << +advertiser_id;

    do_in_bta_thread(
        FROM_HERE,
        Bind(&BleAdvertisingManager::SetPeriodicAdvertisingData,
             base::Unretained(BleAdvertisingManager::Get()), advertiser_id,
             std::move(data), jni_thread_wrapper(FROM_HERE, cb)));
  }

  void SetPeriodicAdvertisingEnable(int advertiser_id, bool enable,
                                    StatusCallback cb) override {
    VLOG(1) << __func__ << " advertiser_id: " << +advertiser_id
            << " ,enable: " << enable;

    do_in_bta_thread(
        FROM_HERE,
        Bind(&BleAdvertisingManager::SetPeriodicAdvertisingEnable,
             base::Unretained(BleAdvertisingManager::Get()), advertiser_id,
             enable, jni_thread_wrapper(FROM_HERE, cb)));
  }
};

BleAdvertiserInterface* btLeAdvertiserInstance = nullptr;

}  // namespace

BleAdvertiserInterface* get_ble_advertiser_instance() {
  if (btLeAdvertiserInstance == nullptr)
    btLeAdvertiserInstance = new BleAdvertiserInterfaceImpl();

  return btLeAdvertiserInstance;
}
