/******************************************************************************
 *
 *  Copyright (C) 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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unordered_set>
#include "device/include/controller.h"

#include "btif_common.h"
#include "btif_util.h"

#include <hardware/bt_gatt.h>

#include "advertise_data_parser.h"
#include "bta_api.h"
#include "bta_closure_api.h"
#include "bta_gatt_api.h"
#include "btif_config.h"
#include "btif_dm.h"
#include "btif_gatt.h"
#include "btif_gatt_util.h"
#include "btif_storage.h"
#include "osi/include/log.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_gattc_add_remote_bdaddr(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_gattc_find_bdaddr(const RawAddress& p_bda) {
  return (remote_bdaddr_cache.find(p_bda) != remote_bdaddr_cache.end());
}

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

void btif_gatts_upstreams_evt(uint16_t event, char* p_param) {
  LOG_VERBOSE(LOG_TAG, "%s: Event %d", __func__, event);

  tBTA_GATTC* p_data = (tBTA_GATTC*)p_param;
  switch (event) {
    case BTA_GATTC_DEREG_EVT:
      break;

    case BTA_GATTC_SEARCH_CMPL_EVT: {
      HAL_CBACK(bt_gatt_callbacks, client->search_complete_cb,
                p_data->search_cmpl.conn_id, p_data->search_cmpl.status);
      break;
    }

    default:
      LOG_DEBUG(LOG_TAG, "%s: Unhandled event (%d)", __func__, event);
      break;
  }
}

void bta_gatts_cback(tBTA_GATTC_EVT event, tBTA_GATTC* p_data) {
  bt_status_t status =
      btif_transfer_context(btif_gatts_upstreams_evt, (uint16_t)event,
                            (char*)p_data, sizeof(tBTA_GATTC), NULL);
  ASSERTC(status == BT_STATUS_SUCCESS, "Context transfer failed!", status);
}

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, tBTA_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, uint8_t 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, BTM_EIR_COMPLETE_LOCAL_NAME_TYPE, &remote_name_len);

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

  if ((addr_type != BLE_ADDR_RANDOM) || (p_eir_remote_name)) {
    if (!btif_gattc_find_bdaddr(bd_addr)) {
      btif_gattc_add_remote_bdaddr(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(LOG_TAG,
                   "%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(LOG_TAG, "%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, BTM_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));
}

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

  void RegisterScanner(RegisterCallback cb) override {
    do_in_bta_thread(FROM_HERE,
                     Bind(
                         [](RegisterCallback cb) {
                           BTA_GATTC_AppRegister(
                               bta_gatts_cback,
                               jni_thread_wrapper(FROM_HERE, std::move(cb)));
                         },
                         std::move(cb)));
  }

  void Unregister(int scanner_id) override {
    do_in_bta_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_bta_thread(FROM_HERE,
                             Bind(&BTA_DmBleObserve, false, 0, nullptr));
            return;
          }

          btif_gattc_init_dev_cb();
          do_in_bta_thread(FROM_HERE,
                           Bind(&BTA_DmBleObserve, true, 0,
                                (tBTA_DM_SEARCH_CBACK*)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_bta_thread(
          FROM_HERE, base::Bind(BTM_BleTrackAdvertiser, bta_track_adv_event_cb,
                                client_if));
    }

    do_in_bta_thread(FROM_HERE,
                     base::Bind(&BTM_BleAdvFilterParamSetup, action, filt_index,
                                base::Passed(&filt_param),
                                jni_thread_wrapper(FROM_HERE, std::move(cb))));
  }

  void ScanFilterAddRemove(int action, int filt_type, int filt_index,
                           int company_id, int company_id_mask,
                           const bt_uuid_t* p_uuid,
                           const bt_uuid_t* p_uuid_mask,
                           const RawAddress* bd_addr, char addr_type,
                           vector<uint8_t> data, vector<uint8_t> mask,
                           FilterConfigCallback cb) override {
    BTIF_TRACE_DEBUG("%s, %d, %d", __func__, action, filt_type);

    /* If data is passed, both mask and data have to be the same length */
    if (data.size() != mask.size() && data.size() != 0 && mask.size() != 0)
      return;

    switch (filt_type) {
      case BTM_BLE_PF_ADDR_FILTER: {
        tBLE_BD_ADDR target_addr;
        target_addr.bda = *bd_addr;
        target_addr.type = addr_type;

        do_in_bta_thread(
            FROM_HERE,
            base::Bind(&BTM_LE_PF_addr_filter, action, filt_index,
                       std::move(target_addr),
                       jni_thread_wrapper(FROM_HERE, Bind(cb, filt_type))));
        return;
      }

      case BTM_BLE_PF_SRVC_DATA:
        do_in_bta_thread(FROM_HERE,
                         base::Bind(&BTM_LE_PF_srvc_data, action, filt_index));
        return;

      case BTM_BLE_PF_SRVC_UUID:
      case BTM_BLE_PF_SRVC_SOL_UUID: {
        tBT_UUID bt_uuid;
        btif_to_bta_uuid(&bt_uuid, p_uuid);

        if (p_uuid_mask == NULL) {
          do_in_bta_thread(
              FROM_HERE,
              base::Bind(&BTM_LE_PF_uuid_filter, action, filt_index, filt_type,
                         bt_uuid, BTM_BLE_PF_LOGIC_AND, nullptr,
                         jni_thread_wrapper(FROM_HERE, Bind(cb, filt_type))));
          return;
        }

        tBTM_BLE_PF_COND_MASK* mask = new tBTM_BLE_PF_COND_MASK;
        btif_to_bta_uuid_mask(mask, p_uuid_mask, p_uuid);
        do_in_bta_thread(
            FROM_HERE,
            base::Bind(&BTM_LE_PF_uuid_filter, action, filt_index, filt_type,
                       bt_uuid, BTM_BLE_PF_LOGIC_AND, base::Owned(mask),
                       jni_thread_wrapper(FROM_HERE, Bind(cb, filt_type))));
        return;
      }

      case BTM_BLE_PF_LOCAL_NAME: {
        do_in_bta_thread(
            FROM_HERE,
            base::Bind(&BTM_LE_PF_local_name, action, filt_index,
                       std::move(data),
                       jni_thread_wrapper(FROM_HERE, Bind(cb, filt_type))));
        return;
      }

      case BTM_BLE_PF_MANU_DATA: {
        do_in_bta_thread(
            FROM_HERE,
            base::Bind(&BTM_LE_PF_manu_data, action, filt_index, company_id,
                       company_id_mask, std::move(data), std::move(mask),
                       jni_thread_wrapper(FROM_HERE, Bind(cb, filt_type))));
        return;
      }

      case BTM_BLE_PF_SRVC_DATA_PATTERN: {
        do_in_bta_thread(
            FROM_HERE,
            base::Bind(&BTM_LE_PF_srvc_data_pattern, action, filt_index,
                       std::move(data), std::move(mask),
                       jni_thread_wrapper(FROM_HERE, Bind(cb, filt_type))));
        return;
      }

      default:
        LOG_ERROR(LOG_TAG, "%s: Unknown filter type (%d)!", __func__, action);
        return;
    }
  }

  void ScanFilterClear(int filter_index, FilterConfigCallback cb) override {
    BTIF_TRACE_DEBUG("%s: filter_index: %d", __func__, filter_index);
    do_in_bta_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_bta_thread(FROM_HERE,
                     base::Bind(&BTM_BleEnableDisableFilterFeature, action,
                                jni_thread_wrapper(FROM_HERE, std::move(cb))));
  }

  void SetScanParameters(int scan_interval, int scan_window,
                         Callback cb) override {
    do_in_bta_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_bta_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_bta_thread(
        FROM_HERE, base::Bind(&BTM_BleEnableBatchScan, scan_mode, scan_interval,
                              scan_window, discard_rule, addr_type,
                              jni_thread_wrapper(FROM_HERE, cb)));
  }

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

  void BatchscanReadReports(int client_if, int scan_mode) override {
    do_in_bta_thread(FROM_HERE,
                     base::Bind(&BTM_BleReadScanReports, (uint8_t)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 {}
};

BleScannerInterface* btLeScannerInstance = nullptr;

}  // namespace

BleScannerInterface* get_ble_scanner_instance() {
  if (btLeScannerInstance == nullptr)
    btLeScannerInstance = new BleScannerInterfaceImpl();

  return btLeScannerInstance;
}
