/******************************************************************************
 *
 *  Copyright 2016 The Android Open Source Project
 *
 *  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_scanner"

#include <base/bind.h>
#include <base/threading/thread.h>
#include <errno.h>
#include <hardware/bluetooth.h>
#include <hardware/bt_gatt.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <unordered_set>

#include "advertise_data_parser.h"
#include "bta_api.h"
#include "bta_gatt_api.h"
#include "btif_common.h"
#include "btif_config.h"
#include "btif_dm.h"
#include "btif_gatt.h"
#include "btif_gatt_util.h"
#include "btif_storage.h"
#include "btif_util.h"
#include "device/include/controller.h"
#include "main/shim/le_scanning_manager.h"
#include "main/shim/shim.h"
#include "osi/include/log.h"
#include "stack/include/btu.h"
#include "types/bluetooth/uuid.h"
#include "types/raw_address.h"
#include "vendor_api.h"

using base::Bind;
using base::Owned;
using std::vector;
using RegisterCallback = BleScannerInterface::RegisterCallback;

extern const btgatt_callbacks_t* bt_gatt_callbacks;

#define SCAN_CBACK_IN_JNI(P_CBACK, ...)                              \
  do {                                                               \
    if (bt_gatt_callbacks && bt_gatt_callbacks->scanner->P_CBACK) {  \
      BTIF_TRACE_API("HAL bt_gatt_callbacks->client->%s", #P_CBACK); \
      do_in_jni_thread(                                              \
          Bind(bt_gatt_callbacks->scanner->P_CBACK, __VA_ARGS__));   \
    } else {                                                         \
      ASSERTC(0, "Callback is NULL", 0);                             \
    }                                                                \
  } while (0)

namespace {

// all access to this variable should be done on the jni thread
std::set<RawAddress> remote_bdaddr_cache;
std::queue<RawAddress> remote_bdaddr_cache_ordered;
const size_t remote_bdaddr_cache_max_size = 1024;

void btif_address_cache_add(const RawAddress& p_bda, uint8_t addr_type) {
  // Remove the oldest entries
  while (remote_bdaddr_cache.size() >= remote_bdaddr_cache_max_size) {
    const RawAddress& raw_address = remote_bdaddr_cache_ordered.front();
    remote_bdaddr_cache.erase(raw_address);
    remote_bdaddr_cache_ordered.pop();
  }
  remote_bdaddr_cache.insert(p_bda);
  remote_bdaddr_cache_ordered.push(p_bda);
}

bool btif_address_cache_find(const RawAddress& p_bda) {
  return (remote_bdaddr_cache.find(p_bda) != remote_bdaddr_cache.end());
}

void btif_address_cache_init(void) {
  remote_bdaddr_cache.clear();
  remote_bdaddr_cache_ordered = {};
}

void bta_batch_scan_threshold_cb(tBTM_BLE_REF_VALUE ref_value) {
  SCAN_CBACK_IN_JNI(batchscan_threshold_cb, ref_value);
}

void bta_batch_scan_reports_cb(int client_id, tBTM_STATUS status,
                               uint8_t report_format, uint8_t num_records,
                               std::vector<uint8_t> data) {
  SCAN_CBACK_IN_JNI(batchscan_reports_cb, client_id, status, report_format,
                    num_records, std::move(data));
}

void bta_scan_results_cb_impl(RawAddress bd_addr, tBT_DEVICE_TYPE device_type,
                              int8_t rssi, tBLE_ADDR_TYPE addr_type,
                              uint16_t ble_evt_type, uint8_t ble_primary_phy,
                              uint8_t ble_secondary_phy,
                              uint8_t ble_advertising_sid, int8_t ble_tx_power,
                              uint16_t ble_periodic_adv_int,
                              vector<uint8_t> value) {
  uint8_t remote_name_len;
  bt_device_type_t dev_type;
  bt_property_t properties;

  const uint8_t* p_eir_remote_name = AdvertiseDataParser::GetFieldByType(
      value, HCI_EIR_COMPLETE_LOCAL_NAME_TYPE, &remote_name_len);

  if (p_eir_remote_name == NULL) {
    p_eir_remote_name = AdvertiseDataParser::GetFieldByType(
        value, HCI_EIR_SHORTENED_LOCAL_NAME_TYPE, &remote_name_len);
  }

  if ((addr_type != BLE_ADDR_RANDOM) || (p_eir_remote_name)) {
    if (!btif_address_cache_find(bd_addr)) {
      btif_address_cache_add(bd_addr, addr_type);

      if (p_eir_remote_name) {
        if (remote_name_len > BD_NAME_LEN + 1 ||
            (remote_name_len == BD_NAME_LEN + 1 &&
             p_eir_remote_name[BD_NAME_LEN] != '\0')) {
          LOG_INFO("%s dropping invalid packet - device name too long: %d",
                   __func__, remote_name_len);
          return;
        }

        bt_bdname_t bdname;
        memcpy(bdname.name, p_eir_remote_name, remote_name_len);
        if (remote_name_len < BD_NAME_LEN + 1)
          bdname.name[remote_name_len] = '\0';

        LOG_VERBOSE("%s BLE device name=%s len=%d dev_type=%d", __func__,
                    bdname.name, remote_name_len, device_type);
        btif_dm_update_ble_remote_properties(bd_addr, bdname.name, device_type);
      }
    }
  }

  dev_type = (bt_device_type_t)device_type;
  BTIF_STORAGE_FILL_PROPERTY(&properties, BT_PROPERTY_TYPE_OF_DEVICE,
                             sizeof(dev_type), &dev_type);
  btif_storage_set_remote_device_property(&(bd_addr), &properties);

  btif_storage_set_remote_addr_type(&bd_addr, addr_type);
  HAL_CBACK(bt_gatt_callbacks, scanner->scan_result_cb, ble_evt_type, addr_type,
            &bd_addr, ble_primary_phy, ble_secondary_phy, ble_advertising_sid,
            ble_tx_power, rssi, ble_periodic_adv_int, std::move(value));
}

void bta_scan_results_cb(tBTA_DM_SEARCH_EVT event, tBTA_DM_SEARCH* p_data) {
  uint8_t len;

  if (event == BTA_DM_INQ_CMPL_EVT) {
    BTIF_TRACE_DEBUG("%s  BLE observe complete. Num Resp %d", __func__,
                     p_data->inq_cmpl.num_resps);
    return;
  }

  if (event != BTA_DM_INQ_RES_EVT) {
    BTIF_TRACE_WARNING("%s : Unknown event 0x%x", __func__, event);
    return;
  }

  vector<uint8_t> value;
  if (p_data->inq_res.p_eir) {
    value.insert(value.begin(), p_data->inq_res.p_eir,
                 p_data->inq_res.p_eir + p_data->inq_res.eir_len);

    if (AdvertiseDataParser::GetFieldByType(
            value, HCI_EIR_COMPLETE_LOCAL_NAME_TYPE, &len)) {
      p_data->inq_res.remt_name_not_required = true;
    }
  }

  tBTA_DM_INQ_RES* r = &p_data->inq_res;
  do_in_jni_thread(Bind(bta_scan_results_cb_impl, r->bd_addr, r->device_type,
                        r->rssi, r->ble_addr_type, r->ble_evt_type,
                        r->ble_primary_phy, r->ble_secondary_phy,
                        r->ble_advertising_sid, r->ble_tx_power,
                        r->ble_periodic_adv_int, std::move(value)));
}

void bta_track_adv_event_cb(tBTM_BLE_TRACK_ADV_DATA* p_track_adv_data) {
  btgatt_track_adv_info_t* btif_scan_track_cb = new btgatt_track_adv_info_t;

  BTIF_TRACE_DEBUG("%s", __func__);
  btif_gatt_move_track_adv_data(btif_scan_track_cb,
                                (btgatt_track_adv_info_t*)p_track_adv_data);

  SCAN_CBACK_IN_JNI(track_adv_event_cb, Owned(btif_scan_track_cb));
}

void bta_cback(tBTA_GATTC_EVT, tBTA_GATTC*) {}

class BleScannerInterfaceImpl : public BleScannerInterface {
  ~BleScannerInterfaceImpl() override{};

  void RegisterScanner(const bluetooth::Uuid& app_uuid,
                       RegisterCallback cb) override {
    do_in_main_thread(FROM_HERE,
                      Bind(
                          [](RegisterCallback cb) {
                            BTA_GATTC_AppRegister(
                                bta_cback,
                                jni_thread_wrapper(FROM_HERE, std::move(cb)),
                                false);
                          },
                          std::move(cb)));
  }

  void Unregister(int scanner_id) override {
    do_in_main_thread(FROM_HERE, Bind(&BTA_GATTC_AppDeregister, scanner_id));
  }

  void Scan(bool start) override {
    do_in_jni_thread(Bind(
        [](bool start) {
          if (!start) {
            do_in_main_thread(FROM_HERE,
                              Bind(&BTA_DmBleObserve, false, 0, nullptr));
            return;
          }

          btif_address_cache_init();
          do_in_main_thread(
              FROM_HERE, Bind(&BTA_DmBleObserve, true, 0, bta_scan_results_cb));
        },
        start));
  }

  void ScanFilterParamSetup(
      uint8_t client_if, uint8_t action, uint8_t filt_index,
      std::unique_ptr<btgatt_filt_param_setup_t> filt_param,
      FilterParamSetupCallback cb) override {
    BTIF_TRACE_DEBUG("%s", __func__);

    if (filt_param && filt_param->dely_mode == 1) {
      do_in_main_thread(
          FROM_HERE, base::Bind(BTM_BleTrackAdvertiser, bta_track_adv_event_cb,
                                client_if));
    }

    do_in_main_thread(FROM_HERE,
                      base::Bind(&BTM_BleAdvFilterParamSetup,
                                 static_cast<tBTM_BLE_SCAN_COND_OP>(action),
                                 filt_index, base::Passed(&filt_param),
                                 jni_thread_wrapper(FROM_HERE, std::move(cb))));
  }

  void ScanFilterAdd(int filter_index, std::vector<ApcfCommand> filters,
                     FilterConfigCallback cb) override {
    BTIF_TRACE_DEBUG("%s: %d", __func__, filter_index);

    do_in_main_thread(
        FROM_HERE,
        base::Bind(
            &BTM_LE_PF_set, filter_index, std::move(filters),
            jni_thread_wrapper(
                FROM_HERE,
                Bind(std::move(cb),
                     0 /*TODO: this used to be filter type, unused ?*/))));
  }

  void ScanFilterClear(int filter_index, FilterConfigCallback cb) override {
    BTIF_TRACE_DEBUG("%s: filter_index: %d", __func__, filter_index);
    do_in_main_thread(
        FROM_HERE, base::Bind(&BTM_LE_PF_clear, filter_index,
                              jni_thread_wrapper(
                                  FROM_HERE, Bind(cb, BTM_BLE_PF_TYPE_ALL))));
  }

  void ScanFilterEnable(bool enable, EnableCallback cb) override {
    BTIF_TRACE_DEBUG("%s: enable: %d", __func__, enable);

    uint8_t action = enable ? 1 : 0;
    do_in_main_thread(FROM_HERE,
                      base::Bind(&BTM_BleEnableDisableFilterFeature, action,
                                 jni_thread_wrapper(FROM_HERE, std::move(cb))));
  }

  void SetScanParameters(int scanner_id, int scan_interval, int scan_window,
                         Callback cb) override {
    do_in_main_thread(
        FROM_HERE, base::Bind(&BTM_BleSetScanParams, scan_interval, scan_window,
                              BTM_BLE_SCAN_MODE_ACTI,
                              jni_thread_wrapper(FROM_HERE, std::move(cb))));
  }

  void BatchscanConfigStorage(int client_if, int batch_scan_full_max,
                              int batch_scan_trunc_max,
                              int batch_scan_notify_threshold,
                              Callback cb) override {
    do_in_main_thread(
        FROM_HERE,
        base::Bind(&BTM_BleSetStorageConfig, (uint8_t)batch_scan_full_max,
                   (uint8_t)batch_scan_trunc_max,
                   (uint8_t)batch_scan_notify_threshold,
                   jni_thread_wrapper(FROM_HERE, cb),
                   bta_batch_scan_threshold_cb, (tBTM_BLE_REF_VALUE)client_if));
  }

  void BatchscanEnable(int scan_mode, int scan_interval, int scan_window,
                       int addr_type, int discard_rule, Callback cb) override {
    do_in_main_thread(
        FROM_HERE, base::Bind(&BTM_BleEnableBatchScan, scan_mode, scan_interval,
                              scan_window, discard_rule,
                              static_cast<tBLE_ADDR_TYPE>(addr_type),
                              jni_thread_wrapper(FROM_HERE, cb)));
  }

  void BatchscanDisable(Callback cb) override {
    do_in_main_thread(FROM_HERE, base::Bind(&BTM_BleDisableBatchScan,
                                            jni_thread_wrapper(FROM_HERE, cb)));
  }

  void BatchscanReadReports(int client_if, int scan_mode) override {
    do_in_main_thread(
        FROM_HERE,
        base::Bind(&BTM_BleReadScanReports, (tBLE_SCAN_MODE)scan_mode,
                   Bind(bta_batch_scan_reports_cb, client_if)));
  }

  void StartSync(uint8_t sid, RawAddress address, uint16_t skip,
                 uint16_t timeout, StartSyncCb start_cb, SyncReportCb report_cb,
                 SyncLostCb lost_cb) override {}

  void StopSync(uint16_t handle) override {}

  void RegisterCallbacks(ScanningCallbacks* callbacks) {
    // For GD only
  }
};

BleScannerInterface* btLeScannerInstance = nullptr;

}  // namespace

BleScannerInterface* get_ble_scanner_instance() {
  if (bluetooth::shim::is_gd_scanning_enabled()) {
    LOG_INFO("Use gd le scanner");
    return bluetooth::shim::get_ble_scanner_instance();
  } else if (btLeScannerInstance == nullptr) {
    btLeScannerInstance = new BleScannerInterfaceImpl();
  }
  return btLeScannerInstance;
}
