#include "ArcsecJsonParamBase.h"

#include "ArcsecJsonKeys.h"

ArcsecJsonParamBase::ArcsecJsonParamBase(std::string setName) : setName(setName) {}

ReturnValue_t ArcsecJsonParamBase::create(std::string fullname, uint8_t* buffer) {
  ReturnValue_t result = returnvalue::OK;
  result = init(fullname);
  if (result != returnvalue::OK) {
    sif::warning << "ArcsecJsonParamBase::create: Failed to init parameter command for set "
                 << setName << std::endl;
    return result;
  }
  result = createCommand(buffer);
  if (result != returnvalue::OK) {
    sif::warning << "ArcsecJsonParamBase::create: Failed to create parameter command for set "
                 << setName << std::endl;
  }
  return result;
}

ReturnValue_t ArcsecJsonParamBase::getParam(const std::string name, std::string& value) {
  for (json::iterator it = set.begin(); it != set.end(); ++it) {
    if ((*it)[arcseckeys::NAME] == name) {
      value = (*it)[arcseckeys::VALUE];
      convertEmpty(value);
      return returnvalue::OK;
    }
  }
  return PARAM_NOT_EXISTS;
}

void ArcsecJsonParamBase::convertEmpty(std::string& value) {
  if (value == "") {
    value = "0";
  }
}

void ArcsecJsonParamBase::addfloat(const std::string value, uint8_t* buffer) {
  float param = std::stof(value);
  std::memcpy(buffer, &param, sizeof(param));
}

void ArcsecJsonParamBase::adduint8(const std::string value, uint8_t* buffer) {
  uint8_t param = std::stoi(value);
  std::memcpy(buffer, &param, sizeof(param));
}

void ArcsecJsonParamBase::addint16(const std::string value, uint8_t* buffer) {
  int16_t param = std::stoi(value);
  std::memcpy(buffer, &param, sizeof(param));
}

void ArcsecJsonParamBase::adduint16(const std::string value, uint8_t* buffer) {
  uint16_t param = std::stoi(value);
  std::memcpy(buffer, &param, sizeof(param));
}

void ArcsecJsonParamBase::adduint32(const std::string value, uint8_t* buffer) {
  uint32_t param = std::stoi(value);
  std::memcpy(buffer, &param, sizeof(param));
}

void ArcsecJsonParamBase::addSetParamHeader(uint8_t* buffer, uint8_t setId) {
  *buffer = static_cast<uint8_t>(TMTC_SETPARAMREQ);
  *(buffer + 1) = setId;
}

ReturnValue_t ArcsecJsonParamBase::init(const std::string filename) {
  ReturnValue_t result = returnvalue::OK;
  if (not std::filesystem::exists(filename)) {
    sif::warning << "ArcsecJsonParamBase::init: JSON file " << filename << " does not exist"
                 << std::endl;
    return JSON_FILE_NOT_EXISTS;
  }
  createJsonObject(filename);
  result = initSet();
  if (result != returnvalue::OK) {
    return result;
  }
  return returnvalue::OK;
}

void ArcsecJsonParamBase::createJsonObject(const std::string fullname) {
  json j;
  std::ifstream file(fullname);
  file >> j;
  file.close();
  properties = j[arcseckeys::PROPERTIES];
}

ReturnValue_t ArcsecJsonParamBase::initSet() {
  for (json::iterator it = properties.begin(); it != properties.end(); ++it) {
    if ((*it)["name"] == setName) {
      set = (*it)["fields"];
      return returnvalue::OK;
    }
  }
  sif::warning << "ArcsecJsonParamBase::initSet: Set " << setName << "not present in json file"
               << std::endl;
  return SET_NOT_EXISTS;
}