/******************************************************************************
 *
 *  Copyright 2014 Broadcom Corporation
 *
 *  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 <base/bind.h>
#include <stddef.h>
#include <stdio.h>
#include <string.h>
#include <vector>
#include "bt_target.h"

#include "btm_ble_api.h"
#include "btm_int.h"
#include "btu.h"
#include "device/include/controller.h"
#include "stack/btm/btm_int_types.h"
#include "utils/include/bt_utils.h"

extern tBTM_CB btm_cb;

using base::Bind;
using base::Callback;
using hci_cmd_cb = base::Callback<void(uint8_t* /* return_parameters */,
                                       uint16_t /* return_parameters_length*/)>;

tBTM_BLE_BATCH_SCAN_CB ble_batchscan_cb;
tBTM_BLE_ADV_TRACK_CB ble_advtrack_cb;

/* length of each batch scan command */
#define BTM_BLE_BATCH_SCAN_STORAGE_CFG_LEN 4
#define BTM_BLE_BATCH_SCAN_PARAM_CONFIG_LEN 12
#define BTM_BLE_BATCH_SCAN_ENB_DISB_LEN 2
#define BTM_BLE_BATCH_SCAN_READ_RESULTS_LEN 2

namespace {

bool can_do_batch_scan() {
  if (!controller_get_interface()->supports_ble()) return false;

  tBTM_BLE_VSC_CB cmn_ble_vsc_cb;
  BTM_BleGetVendorCapabilities(&cmn_ble_vsc_cb);

  if (cmn_ble_vsc_cb.tot_scan_results_strg == 0) return false;

  return true;
}

/* VSE callback for batch scan, filter, and tracking events */
void btm_ble_batchscan_filter_track_adv_vse_cback(uint8_t len, uint8_t* p) {
  tBTM_BLE_TRACK_ADV_DATA adv_data;

  uint8_t sub_event = 0;
  tBTM_BLE_VSC_CB cmn_ble_vsc_cb;
  if (len == 0) return;
  STREAM_TO_UINT8(sub_event, p);

  BTM_TRACE_EVENT(
      "btm_ble_batchscan_filter_track_adv_vse_cback called with event:%x",
      sub_event);
  if (HCI_VSE_SUBCODE_BLE_THRESHOLD_SUB_EVT == sub_event &&
      NULL != ble_batchscan_cb.p_thres_cback) {
    ble_batchscan_cb.p_thres_cback(ble_batchscan_cb.ref_value);
    return;
  }

  if (HCI_VSE_SUBCODE_BLE_TRACKING_SUB_EVT == sub_event &&
      NULL != ble_advtrack_cb.p_track_cback) {
    if (len < 10) return;

    memset(&adv_data, 0, sizeof(tBTM_BLE_TRACK_ADV_DATA));
    BTM_BleGetVendorCapabilities(&cmn_ble_vsc_cb);
    adv_data.client_if = (uint8_t)ble_advtrack_cb.ref_value;
    if (cmn_ble_vsc_cb.version_supported > BTM_VSC_CHIP_CAPABILITY_L_VERSION) {
      STREAM_TO_UINT8(adv_data.filt_index, p);
      STREAM_TO_UINT8(adv_data.advertiser_state, p);
      STREAM_TO_UINT8(adv_data.advertiser_info_present, p);
      STREAM_TO_BDADDR(adv_data.bd_addr, p);
      STREAM_TO_UINT8(adv_data.addr_type, p);

      /* Extract the adv info details */
      if (ADV_INFO_PRESENT == adv_data.advertiser_info_present) {
        if (len < 15) return;
        STREAM_TO_UINT8(adv_data.tx_power, p);
        STREAM_TO_UINT8(adv_data.rssi_value, p);
        STREAM_TO_UINT16(adv_data.time_stamp, p);

        STREAM_TO_UINT8(adv_data.adv_pkt_len, p);
        if (adv_data.adv_pkt_len > 0) {
          adv_data.p_adv_pkt_data =
              static_cast<uint8_t*>(osi_malloc(adv_data.adv_pkt_len));
          memcpy(adv_data.p_adv_pkt_data, p, adv_data.adv_pkt_len);
          p += adv_data.adv_pkt_len;
        }

        STREAM_TO_UINT8(adv_data.scan_rsp_len, p);
        if (adv_data.scan_rsp_len > 0) {
          adv_data.p_scan_rsp_data =
              static_cast<uint8_t*>(osi_malloc(adv_data.scan_rsp_len));
          memcpy(adv_data.p_scan_rsp_data, p, adv_data.scan_rsp_len);
        }
      }
    } else {
      /* Based on L-release version */
      STREAM_TO_UINT8(adv_data.filt_index, p);
      STREAM_TO_UINT8(adv_data.addr_type, p);
      STREAM_TO_BDADDR(adv_data.bd_addr, p);
      STREAM_TO_UINT8(adv_data.advertiser_state, p);
    }

    BTM_TRACE_EVENT("track_adv_vse_cback called: %d, %d, %d",
                    adv_data.filt_index, adv_data.addr_type,
                    adv_data.advertiser_state);

    // Make sure the device is known
    BTM_SecAddBleDevice(adv_data.bd_addr, BT_DEVICE_TYPE_BLE,
                        adv_data.addr_type);

    ble_advtrack_cb.p_track_cback(&adv_data);
    return;
  }
}

void feat_enable_cb(uint8_t* p, uint16_t len) {
  if (len < 2) {
    BTM_TRACE_ERROR("%s: wrong length", __func__);
    return;
  }

  uint8_t status, subcode;
  STREAM_TO_UINT8(status, p);
  STREAM_TO_UINT8(subcode, p);

  uint8_t expected_opcode = BTM_BLE_BATCH_SCAN_ENB_DISAB_CUST_FEATURE;
  if (subcode != expected_opcode) {
    BTM_TRACE_ERROR("%s: bad subcode, expected: %d got: %d", __func__,
                    expected_opcode, subcode);
    return;
  }

  if (ble_batchscan_cb.cur_state != BTM_BLE_SCAN_ENABLE_CALLED)
    BTM_TRACE_ERROR("%s: state should be ENABLE_CALLED", __func__);

  ble_batchscan_cb.cur_state = BTM_BLE_SCAN_ENABLED_STATE;
}

void storage_config_cb(Callback<void(uint8_t /* status */)> cb, uint8_t* p,
                       uint16_t len) {
  if (len < 2) {
    BTM_TRACE_ERROR("%s: wrong length", __func__);
    return;
  }

  uint8_t status, subcode;
  STREAM_TO_UINT8(status, p);
  STREAM_TO_UINT8(subcode, p);

  uint8_t expected_opcode = BTM_BLE_BATCH_SCAN_SET_STORAGE_PARAM;
  if (subcode != expected_opcode) {
    BTM_TRACE_ERROR("%s: bad subcode, expected: %d got: %d", __func__,
                    expected_opcode, subcode);
    return;
  }

  cb.Run(status);
}

void param_enable_cb(Callback<void(uint8_t /* status */)> cb, uint8_t* p,
                     uint16_t len) {
  if (len < 2) {
    BTM_TRACE_ERROR("%s: wrong length", __func__);
    return;
  }

  uint8_t status, subcode;
  STREAM_TO_UINT8(status, p);
  STREAM_TO_UINT8(subcode, p);

  uint8_t expected_opcode = BTM_BLE_BATCH_SCAN_SET_PARAMS;
  if (subcode != expected_opcode) {
    BTM_TRACE_ERROR("%s: bad subcode: 0x%02x 0x%02x", __func__, expected_opcode,
                    subcode);
    return;
  }

  cb.Run(status);
}

void disable_cb(base::Callback<void(uint8_t /* status */)> cb, uint8_t* p,
                uint16_t len) {
  if (len < 2) {
    BTM_TRACE_ERROR("%s: wrong length", __func__);
    return;
  }

  uint8_t status, subcode;
  STREAM_TO_UINT8(status, p);
  STREAM_TO_UINT8(subcode, p);

  uint8_t expected_opcode = BTM_BLE_BATCH_SCAN_SET_PARAMS;
  if (subcode != expected_opcode) {
    BTM_TRACE_ERROR("%s: bad subcode: 0x%02x 0x%02x", __func__, expected_opcode,
                    subcode);
    return;
  }

  if (ble_batchscan_cb.cur_state != BTM_BLE_SCAN_DISABLE_CALLED) {
    BTM_TRACE_ERROR("%s: state should be DISABLE_CALLED", __func__);
  }

  if (BTM_SUCCESS == status) {
    ble_batchscan_cb.cur_state = BTM_BLE_SCAN_DISABLED_STATE;
  } else {
    BTM_TRACE_ERROR("%s: Invalid state after disabled", __func__);
    ble_batchscan_cb.cur_state = BTM_BLE_SCAN_INVALID_STATE;
  }

  cb.Run(status);
}

/**
 * This function reads the reports from controller. |scan_mode| is the mode for
 * which the reports are to be read
 */
void btm_ble_read_batchscan_reports(tBTM_BLE_BATCH_SCAN_MODE scan_mode,
                                    hci_cmd_cb cb) {
  uint8_t len = BTM_BLE_BATCH_SCAN_READ_RESULTS_LEN;
  uint8_t param[len];
  memset(param, 0, len);

  uint8_t* pp = param;
  UINT8_TO_STREAM(pp, BTM_BLE_BATCH_SCAN_READ_RESULTS);
  UINT8_TO_STREAM(pp, scan_mode);

  btu_hcif_send_cmd_with_cb(FROM_HERE, HCI_BLE_BATCH_SCAN, param, len, cb);
}

/* read reports. data is accumulated in |data_all|, number of records is
 * accumulated in |num_records_all| */
void read_reports_cb(std::vector<uint8_t> data_all, uint8_t num_records_all,
                     tBTM_BLE_SCAN_REP_CBACK cb, uint8_t* p, uint16_t len) {
  if (len < 2) {
    BTM_TRACE_ERROR("%s: wrong length", __func__);
    return;
  }

  uint8_t status, subcode;
  STREAM_TO_UINT8(status, p);
  STREAM_TO_UINT8(subcode, p);

  uint8_t expected_opcode = BTM_BLE_BATCH_SCAN_READ_RESULTS;
  if (subcode != expected_opcode) {
    BTM_TRACE_ERROR("%s: bad subcode, expected: %d got: %d", __func__,
                    expected_opcode, subcode);
    return;
  }

  if (len < 4) {
    BTM_TRACE_ERROR("%s: wrong length", __func__);
    return;
  }

  uint8_t report_format, num_records;
  STREAM_TO_UINT8(report_format, p);
  STREAM_TO_UINT8(num_records, p);

  BTM_TRACE_DEBUG("%s: status=%d,len=%d,rec=%d", __func__, status, len - 4,
                  num_records);

  if (num_records == 0) {
    cb.Run(BTM_SUCCESS, report_format, num_records_all, data_all);
    return;
  }

  if (len > 4) {
    data_all.insert(data_all.end(), p, p + len - 4);
    num_records_all += num_records;

    /* More records could be in the buffer and needs to be pulled out */
    btm_ble_read_batchscan_reports(
        report_format, base::Bind(&read_reports_cb, std::move(data_all),
                                  num_records_all, std::move(cb)));
  }
}

/**
 * This function writes the storage configuration in controller
 *
 * Parameters       batch_scan_full_max - Max storage space (in %) allocated to
 *                                        full scanning
 *                  batch_scan_trunc_max - Max storage space (in %) allocated to
 *                                         truncated scanning
 *                  batch_scan_notify_threshold - Set up notification level
 *                                                based on total space
 *
 **/
void btm_ble_set_storage_config(uint8_t batch_scan_full_max,
                                uint8_t batch_scan_trunc_max,
                                uint8_t batch_scan_notify_threshold,
                                hci_cmd_cb cb) {
  uint8_t len = BTM_BLE_BATCH_SCAN_STORAGE_CFG_LEN;
  uint8_t param[len];
  memset(param, 0, len);

  uint8_t* pp = param;
  UINT8_TO_STREAM(pp, BTM_BLE_BATCH_SCAN_SET_STORAGE_PARAM);
  UINT8_TO_STREAM(pp, batch_scan_full_max);
  UINT8_TO_STREAM(pp, batch_scan_trunc_max);
  UINT8_TO_STREAM(pp, batch_scan_notify_threshold);

  btu_hcif_send_cmd_with_cb(FROM_HERE, HCI_BLE_BATCH_SCAN, param, len, cb);
}

/* This function writes the batch scan params in controller */
void btm_ble_set_batchscan_param(tBTM_BLE_BATCH_SCAN_MODE scan_mode,
                                 uint32_t scan_interval, uint32_t scan_window,
                                 tBLE_ADDR_TYPE addr_type,
                                 tBTM_BLE_DISCARD_RULE discard_rule,
                                 hci_cmd_cb cb) {
  // Override param and decide addr_type based on own addr type
  // TODO: Remove upper layer parameter?
  addr_type = btm_cb.ble_ctr_cb.addr_mgnt_cb.own_addr_type;

  uint8_t len = BTM_BLE_BATCH_SCAN_PARAM_CONFIG_LEN;
  uint8_t param[len];
  memset(param, 0, len);

  uint8_t* p = param;
  UINT8_TO_STREAM(p, BTM_BLE_BATCH_SCAN_SET_PARAMS);
  UINT8_TO_STREAM(p, scan_mode);
  UINT32_TO_STREAM(p, scan_window);
  UINT32_TO_STREAM(p, scan_interval);
  UINT8_TO_STREAM(p, addr_type);
  UINT8_TO_STREAM(p, discard_rule);

  btu_hcif_send_cmd_with_cb(FROM_HERE, HCI_BLE_BATCH_SCAN, param, len, cb);
}

/* This function enables the customer specific feature in controller */
void btm_ble_enable_batchscan(hci_cmd_cb cb) {
  uint8_t len = BTM_BLE_BATCH_SCAN_ENB_DISB_LEN;
  uint8_t param[len];
  memset(param, 0, len);

  uint8_t* p = param;
  UINT8_TO_STREAM(p, BTM_BLE_BATCH_SCAN_ENB_DISAB_CUST_FEATURE);
  UINT8_TO_STREAM(p, 0x01 /* enable */);

  btu_hcif_send_cmd_with_cb(FROM_HERE, HCI_BLE_BATCH_SCAN, param, len, cb);
}

}  // namespace

/*******************************************************************************
 *
 * Description      This function is called to write storage config params.
 *
 * Parameters:      batch_scan_full_max - Max storage space (in %) allocated to
 *                                        full style
 *                  batch_scan_trunc_max - Max storage space (in %) allocated to
 *                                         trunc style
 *                  batch_scan_notify_threshold - Setup notification level based
 *                                                on total space
 *                  cb - Setup callback pointer
 *                  p_thres_cback - Threshold callback pointer
 *                  ref_value - Reference value
 *
 ******************************************************************************/
void BTM_BleSetStorageConfig(uint8_t batch_scan_full_max,
                             uint8_t batch_scan_trunc_max,
                             uint8_t batch_scan_notify_threshold,
                             Callback<void(uint8_t /* status */)> cb,
                             tBTM_BLE_SCAN_THRESHOLD_CBACK* p_thres_cback,
                             tBTM_BLE_REF_VALUE ref_value) {
  if (!can_do_batch_scan()) {
    cb.Run(BTM_ERR_PROCESSING);
    return;
  }

  BTM_TRACE_EVENT("%s: %d, %d, %d, %d, %d", __func__,
                  ble_batchscan_cb.cur_state, ref_value, batch_scan_full_max,
                  batch_scan_trunc_max, batch_scan_notify_threshold);

  ble_batchscan_cb.p_thres_cback = p_thres_cback;
  ble_batchscan_cb.ref_value = ref_value;

  if (batch_scan_full_max > BTM_BLE_ADV_SCAN_FULL_MAX ||
      batch_scan_trunc_max > BTM_BLE_ADV_SCAN_TRUNC_MAX ||
      batch_scan_notify_threshold > BTM_BLE_ADV_SCAN_THR_MAX) {
    BTM_TRACE_ERROR("Illegal set storage config params");
    cb.Run(BTM_ILLEGAL_VALUE);
    return;
  }

  if (BTM_BLE_SCAN_INVALID_STATE == ble_batchscan_cb.cur_state ||
      BTM_BLE_SCAN_DISABLED_STATE == ble_batchscan_cb.cur_state ||
      BTM_BLE_SCAN_DISABLE_CALLED == ble_batchscan_cb.cur_state) {
    btm_ble_enable_batchscan(Bind(&feat_enable_cb));
    ble_batchscan_cb.cur_state = BTM_BLE_SCAN_ENABLE_CALLED;
  }

  btm_ble_set_storage_config(batch_scan_full_max, batch_scan_trunc_max,
                             batch_scan_notify_threshold,
                             Bind(&storage_config_cb, cb));
  return;
}

/* This function is called to configure and enable batch scanning */
void BTM_BleEnableBatchScan(tBTM_BLE_BATCH_SCAN_MODE scan_mode,
                            uint32_t scan_interval, uint32_t scan_window,
                            tBLE_ADDR_TYPE addr_type,
                            tBTM_BLE_DISCARD_RULE discard_rule,
                            Callback<void(uint8_t /* status */)> cb) {
  BTM_TRACE_EVENT("%s: %d, %d, %d, %d, %d, %d", __func__, scan_mode,
                  scan_interval, scan_window, addr_type, discard_rule);

  if (!can_do_batch_scan()) {
    cb.Run(BTM_ERR_PROCESSING);
    return;
  }

  BTM_TRACE_DEBUG("%s: %d, %x, %x, %d, %d", __func__, scan_mode, scan_interval,
                  scan_window, discard_rule, ble_batchscan_cb.cur_state);

  /* Only 16 bits will be used for scan interval and scan window as per
   * agreement with Google */
  /* So the standard LE range would suffice for scan interval and scan window */
  if ((BTM_BLE_ISVALID_PARAM(scan_interval, BTM_BLE_SCAN_INT_MIN,
                             BTM_BLE_SCAN_INT_MAX) ||
       BTM_BLE_ISVALID_PARAM(scan_window, BTM_BLE_SCAN_WIN_MIN,
                             BTM_BLE_SCAN_WIN_MAX)) &&
      (BTM_BLE_BATCH_SCAN_MODE_PASS == scan_mode ||
       BTM_BLE_BATCH_SCAN_MODE_ACTI == scan_mode ||
       BTM_BLE_BATCH_SCAN_MODE_PASS_ACTI == scan_mode) &&
      (BTM_BLE_DISCARD_OLD_ITEMS == discard_rule ||
       BTM_BLE_DISCARD_LOWER_RSSI_ITEMS == discard_rule)) {
  } else {
    BTM_TRACE_ERROR("%s: Illegal enable scan params", __func__);
    cb.Run(BTM_ILLEGAL_VALUE);
    return;
  }

  if (BTM_BLE_SCAN_INVALID_STATE == ble_batchscan_cb.cur_state ||
      BTM_BLE_SCAN_DISABLED_STATE == ble_batchscan_cb.cur_state ||
      BTM_BLE_SCAN_DISABLE_CALLED == ble_batchscan_cb.cur_state) {
    btm_ble_enable_batchscan(Bind(&feat_enable_cb));
    ble_batchscan_cb.cur_state = BTM_BLE_SCAN_ENABLE_CALLED;
  }

  ble_batchscan_cb.scan_mode = scan_mode;
  ble_batchscan_cb.scan_interval = scan_interval;
  ble_batchscan_cb.scan_window = scan_window;
  ble_batchscan_cb.addr_type = addr_type;
  ble_batchscan_cb.discard_rule = discard_rule;
  /* This command starts batch scanning, if enabled */
  btm_ble_set_batchscan_param(scan_mode, scan_interval, scan_window, addr_type,
                              discard_rule, Bind(&param_enable_cb, cb));
}

/* This function is called to disable batch scanning */
void BTM_BleDisableBatchScan(base::Callback<void(uint8_t /* status */)> cb) {
  BTM_TRACE_EVENT(" BTM_BleDisableBatchScan");

  if (!can_do_batch_scan()) {
    cb.Run(BTM_ERR_PROCESSING);
    return;
  }

  btm_ble_set_batchscan_param(
      BTM_BLE_BATCH_SCAN_MODE_DISABLE, ble_batchscan_cb.scan_interval,
      ble_batchscan_cb.scan_window, ble_batchscan_cb.addr_type,
      ble_batchscan_cb.discard_rule, Bind(&disable_cb, cb));
  ble_batchscan_cb.cur_state = BTM_BLE_SCAN_DISABLE_CALLED;
}

/* This function is called to start reading batch scan reports */
void BTM_BleReadScanReports(tBTM_BLE_BATCH_SCAN_MODE scan_mode,
                            tBTM_BLE_SCAN_REP_CBACK cb) {
  uint8_t read_scan_mode = 0;

  BTM_TRACE_EVENT("%s; %d", __func__, scan_mode);

  if (!can_do_batch_scan()) {
    BTM_TRACE_ERROR("Controller does not support batch scan");
    cb.Run(BTM_ERR_PROCESSING, 0, 0, {});
    return;
  }

  /*  Check if the requested scan mode has already been setup by the user */
  read_scan_mode = ble_batchscan_cb.scan_mode & BTM_BLE_BATCH_SCAN_MODE_ACTI;
  if (0 == read_scan_mode)
    read_scan_mode = ble_batchscan_cb.scan_mode & BTM_BLE_BATCH_SCAN_MODE_PASS;

  /* Check only for modes, as scan reports can be called after disabling batch
   * scan */
  if (scan_mode != BTM_BLE_BATCH_SCAN_MODE_PASS &&
      scan_mode != BTM_BLE_BATCH_SCAN_MODE_ACTI) {
    BTM_TRACE_ERROR("Illegal read scan params: %d, %d, %d", read_scan_mode,
                    scan_mode, ble_batchscan_cb.cur_state);
    cb.Run(BTM_ILLEGAL_VALUE, 0, 0, {});
    return;
  }

  btm_ble_read_batchscan_reports(
      scan_mode, base::Bind(&read_reports_cb, std::vector<uint8_t>(), 0, cb));
  return;
}

/* This function is called to setup the callback for tracking */
void BTM_BleTrackAdvertiser(tBTM_BLE_TRACK_ADV_CBACK* p_track_cback,
                            tBTM_BLE_REF_VALUE ref_value) {
  BTM_TRACE_EVENT("%s:", __func__);

  if (!can_do_batch_scan()) {
    BTM_TRACE_ERROR("Controller does not support batch scan");

    tBTM_BLE_TRACK_ADV_DATA track_adv_data;
    memset(&track_adv_data, 0, sizeof(tBTM_BLE_TRACK_ADV_DATA));
    track_adv_data.advertiser_info_present =
        NO_ADV_INFO_PRESENT; /* Indicates failure */
    track_adv_data.client_if = (uint8_t)ref_value;
    p_track_cback(&track_adv_data);
    return;
  }

  ble_advtrack_cb.p_track_cback = p_track_cback;
  ble_advtrack_cb.ref_value = ref_value;
  return;
}

/**
 * This function initialize the batch scan control block.
 **/
void btm_ble_batchscan_init(void) {
  BTM_TRACE_EVENT(" btm_ble_batchscan_init");
  memset(&ble_batchscan_cb, 0, sizeof(tBTM_BLE_BATCH_SCAN_CB));
  memset(&ble_advtrack_cb, 0, sizeof(tBTM_BLE_ADV_TRACK_CB));
  BTM_RegisterForVSEvents(btm_ble_batchscan_filter_track_adv_vse_cback, true);
}
