/*!
 * \file      Params.cc
 * \brief     Source file for the parameter dictionary.
 * \author    ETSI STF525
 * \copyright ETSI Copyright Notification
 *            No part may be reproduced except as authorized by written permission.
 *            The copyright and the foregoing restriction extend to reproduction in all media.
 *            All rights reserved.
 * \version   0.1
 */
#include <stdexcept>
#include <regex>

#include "Params.hh"
#include "loggers.hh"

const std::string& Params::debug = std::string("debug");

const std::string& Params::loopback = std::string("loopback");

const std::string& Params::mac_src = std::string("mac_src");
const std::string& Params::mac_dst = std::string("mac_dst");
const std::string& Params::mac_bc = std::string("mac_bc");
const std::string& Params::eth_type = std::string("eth_type");
const std::string& Params::beaconing = std::string("beaconing");
const std::string& Params::station_type = std::string("station_type");
const std::string& Params::country = std::string("country");
const std::string& Params::type_of_address = std::string("type_of_address");
const std::string& Params::its_aid = std::string("its_aid");
const std::string& Params::ssp = std::string("ssp");
const std::string& Params::gn_payload = std::string("gn_payload");
const std::string& Params::gn_next_header = std::string("gnNextHeader");
const std::string& Params::gn_header_type = std::string("gnHeaderType");
const std::string& Params::gn_header_sub_type = std::string("gnHeaderSubtype");
const std::string& Params::gn_lifetime = std::string("gnLifetime");
const std::string& Params::gn_traffic_class = std::string("gnTrafficClass");
const std::string& Params::btp_type = std::string("btp_type");
const std::string& Params::btp_payload = std::string("btp_payload");
const std::string& Params::btp_destination_port = std::string("btpDestinationPort");
const std::string& Params::btp_info = std::string("btpInfo");

const std::string& Params::nic = std::string("nic");
const std::string& Params::latitude = std::string("latitude");
const std::string& Params::longitude = std::string("longitude");
const std::string& Params::ll_address = std::string("ll_address");
const std::string& Params::expiry = std::string("expiry");

const std::string& Params::device_mode = std::string("device_mode");
const std::string& Params::secured_mode = std::string("secured_mode");
const std::string& Params::encrypted_mode = std::string("encrypted_mode");
const std::string& Params::enable_security_checks = std::string("enable_security_checks");
const std::string& Params::certificate = std::string("certificate");
const std::string& Params::sec_db_path = std::string("sec_db_path");
const std::string& Params::hash = std::string("hash");
const std::string& Params::signature = std::string("signature");
const std::string& Params::cypher = std::string("cypher");
const std::string& Params::distanceA = std::string("distanceA");
const std::string& Params::distanceB = std::string("distanceB");
const std::string& Params::angle = std::string("angle");

const std::string& Params::payload_type = std::string("payload_type");

const std::string& Params::next_header = std::string("next_header");
const std::string& Params::header_type = std::string("header_type");
const std::string& Params::header_sub_type = std::string("header_sub_type");

const std::string& Params::interface_id = std::string("interface_id");

const std::string& Params::server = std::string("server");
const std::string& Params::port = std::string("port");
const std::string& Params::use_ssl = std::string("use_ssl");

void Params::convert(Params& p_param, const std::string p_parameters) {
  // Sanity checks
  if (p_parameters.length() == 0) {
    return;
  }
  loggers::get_instance().log(">>> Params::convert: %s", p_parameters.c_str());
  // Extract parameters
  try {
    std::regex rgx ("(\\w+)=(.*?)(,|$)");
    std::sregex_iterator begin(p_parameters.cbegin(), p_parameters.cend(), rgx);
    std::sregex_iterator end = std::sregex_iterator();
    for (std::sregex_iterator it = begin; it != end; ++it) {
      std::smatch m = *it;
      loggers::get_instance().log("Params::convert: %d - %s - %s - %s - %s", m.size(), m[0].str().c_str(), m[1].str().c_str(), m[2].str().c_str(), m[3].str().c_str());
      p_param.insert(std::pair<std::string, std::string>(m[1].str(), m[2].str()));
    } // End of 'for' statement
  }
  catch(const std::logic_error& e){
    p_param.clear();
  }
  loggers::get_instance().log("<<< Params::convert");
}

void Params::log() const {
  loggers::get_instance().log("Params::log");
  if (size() == 0) {
    loggers::get_instance().log("\tEmpty");
  } else {
    for (const_iterator it = cbegin(); it != cend(); ++it) {
      loggers::get_instance().log("\t(%s, %s)", it->first.c_str(), it->second.c_str());
    } // End of 'for' statement
  }
}

void Params::log() {
  loggers::get_instance().log("Params::log");
  if (size() == 0) {
    loggers::get_instance().log("\tEmpty");
  } else {
    for (const_iterator it = cbegin(); it != cend(); ++it) {
      loggers::get_instance().log("\t(%s, %s)", it->first.c_str(), it->second.c_str());
    } // End of 'for' statement
  }
}

void Params::reset() { 
  loggers::get_instance().log("Params::reset");
  for (iterator it = begin(); it != end(); ++it) {
    it->second.clear();
  } // End of 'for' statement
}
