#include "NxpUwbChip.h"
#include "phNxpConfig.h"
#include "phNxpUciHal.h"
#include "phNxpUciHal_ext.h"
#include "phUwbStatus.h"
#include "phUwbTypes.h"
#include "phNxpUwbCalib.h"
#include "uci_defs.h"

#define UCI_MSG_UWB_ESE_BINDING_LEN                   11
#define UCI_MSG_UWB_ESE_BINDING_OFFSET_COUNT          5
#define UCI_MSG_UWB_ESE_BINDING_OFFSET_BINDING_STATE  6

extern phNxpUciHal_Control_t nxpucihal_ctrl;
extern int hdll_fw_download();

class NxpUwbChipSr200 final : public NxpUwbChip {
public:
  NxpUwbChipSr200();
  virtual ~NxpUwbChipSr200();

  tHAL_UWB_STATUS chip_init();
  tHAL_UWB_STATUS core_init();
  device_type_t get_device_type(const uint8_t *param, size_t param_len);
  tHAL_UWB_STATUS read_otp(extcal_param_id_t id, uint8_t *data, size_t data_len, size_t *retlen);
  tHAL_UWB_STATUS apply_calibration(extcal_param_id_t id, const uint8_t ch, const uint8_t *data, size_t data_len);
  tHAL_UWB_STATUS get_supported_channels(const uint8_t **cal_channels, uint8_t *nr);
private:
  void on_binding_status_ntf(size_t packet_len, const uint8_t* packet);

  tHAL_UWB_STATUS check_binding_done();

  UciHalRxHandler bindingStatusNtfHandler_;
  UciHalSemaphore bindingStatusNtfWait_;
  uint8_t bindingStatus_;
};

NxpUwbChipSr200::NxpUwbChipSr200() :
  bindingStatus_(UWB_DEVICE_UNKNOWN)
{
}

NxpUwbChipSr200::~NxpUwbChipSr200()
{
}

void NxpUwbChipSr200::on_binding_status_ntf(size_t packet_len, const uint8_t* packet)
{
  if (packet_len >= UCI_RESPONSE_STATUS_OFFSET) {
    bindingStatus_ = packet[UCI_RESPONSE_STATUS_OFFSET];
    NXPLOG_UCIHAL_D("BINDING_STATUS_NTF: 0x%x", bindingStatus_);
    bindingStatusNtfWait_.post(UWBSTATUS_SUCCESS);
  }
}

tHAL_UWB_STATUS NxpUwbChipSr200::check_binding_done()
{
  // Wait for Binding status notification
  if (bindingStatusNtfWait_.getStatus() != UWBSTATUS_SUCCESS) {
    bindingStatusNtfWait_.wait();
  }
  if (bindingStatusNtfWait_.getStatus() != UWBSTATUS_SUCCESS) {
    NXPLOG_UCIHAL_E("Binding status notification timeout");

    // Stop HAL init when it didn't receive the binding notification
    if (nxpucihal_ctrl.fw_boot_mode == USER_FW_BOOT_MODE)
      return UWBSTATUS_FAILED;
    else
      return UWBSTATUS_SUCCESS;
  }

  switch (bindingStatus_) {
  case UWB_DEVICE_NOT_BOUND:
    NXPLOG_UCIHAL_E("Binding status: Unbound.");
    break;
  case UWB_DEVICE_BOUND_UNLOCKED:
    NXPLOG_UCIHAL_E("Binding status: bound & unlocked.");
    break;
  case UWB_DEVICE_BOUND_LOCKED:
    NXPLOG_UCIHAL_D("Binding status: bound & locked.");
    break;
  case UWB_DEVICE_UNKNOWN:
    NXPLOG_UCIHAL_D("Binding status: Unknown.");
    break;
  default:
    NXPLOG_UCIHAL_E("Unknown binding status: 0x%x", bindingStatus_);
    return UWBSTATUS_FAILED;
  }

  return UWBSTATUS_SUCCESS;
}

tHAL_UWB_STATUS NxpUwbChipSr200::chip_init()
{
  tHAL_UWB_STATUS status;

  // system in FW download mode
  // This will be cleared on first Device Status NTF
  nxpucihal_ctrl.fw_dwnld_mode = true;

  NXPLOG_UCIHAL_D("Start SR200 FW download");

  for (int i = 0; i < 5; i++) {
    phTmlUwb_Chip_Reset();

    status = hdll_fw_download();

    if (status == UWBSTATUS_SUCCESS) {
      NXPLOG_UCIHAL_D("Complete SR200 FW download");
      break;
    } else if(status == UWBSTATUS_FILE_NOT_FOUND) {
      NXPLOG_UCIHAL_E("FW file Not found.");
      break;
    } else {
      NXPLOG_UCIHAL_E("FW download failed, status= 0x%x, retry.", status);
    }
  }

  // register binding status ntf handler
  bindingStatusNtfHandler_ = UciHalRxHandler(
      UCI_MT_NTF, UCI_GID_PROPRIETARY, UCI_MSG_BINDING_STATUS_NTF,
      true,
      std::bind(&NxpUwbChipSr200::on_binding_status_ntf, this, std::placeholders::_1, std::placeholders::_2));

  return status;
}

tHAL_UWB_STATUS NxpUwbChipSr200::core_init()
{
  return check_binding_done();
}

device_type_t NxpUwbChipSr200::get_device_type(const uint8_t *param, size_t param_len)
{
  // should be 'SR200..'
  const char marker[] = { 'S', 'R', '2', '0', '0' };
  if (param_len >= sizeof(marker)) {
    if (!memcmp(param, marker, sizeof(marker)))
      return DEVICE_TYPE_SR200;
  }
  return DEVICE_TYPE_UNKNOWN;
}

tHAL_UWB_STATUS
NxpUwbChipSr200::read_otp(extcal_param_id_t id,
                          uint8_t *data, size_t data_len, size_t *retlen)
{
  return UWBSTATUS_NOT_ALLOWED;
}

tHAL_UWB_STATUS
NxpUwbChipSr200::apply_calibration(extcal_param_id_t id, const uint8_t ch,
                                   const uint8_t *data, size_t data_len)
{
  switch (id) {
  case EXTCAL_PARAM_TX_POWER:
  case EXTCAL_PARAM_TX_BASE_BAND_CONTROL:
  case EXTCAL_PARAM_DDFS_TONE_CONFIG:
  case EXTCAL_PARAM_TX_PULSE_SHAPE:
    return sr1xx_apply_calibration(id, ch, data, data_len);
  case EXTCAL_PARAM_CLK_ACCURACY:
  case EXTCAL_PARAM_RX_ANT_DELAY:
    /* break through */
  default:
    NXPLOG_UCIHAL_E("Unsupported parameter: 0x%x", id);
    return UWBSTATUS_FAILED;
  }
}

tHAL_UWB_STATUS
NxpUwbChipSr200::get_supported_channels(const uint8_t **cal_channels, uint8_t *nr)
{
  static const uint8_t sr200_cal_channels[] = {5, 9, 10};
  *cal_channels = sr200_cal_channels;
  *nr = std::size(sr200_cal_channels);
  return UWBSTATUS_SUCCESS;
}

std::unique_ptr<NxpUwbChip> GetUwbChip()
{
  return std::make_unique<NxpUwbChipSr200>();
}
