#include "LibItsHttp_TypesAndValues.hh"

#include "http_layer_factory.hh"
#include "codec_stack_builder.hh"

#include "loggers.hh"

#include "converter.hh"

using namespace std; // Required for isnan()
#include "LibItsHttp_TypesAndValues.hh"
#include "LibItsHttp_TestSystem.hh"

http_layer::http_layer(const std::string & p_type, const std::string & param) : t_layer<LibItsHttp__TestSystem::HttpPort>(p_type), _params()//, _device_mode{false}
{
  loggers::get_instance().log(">>> http_layer::http_layer: %s, %s", to_string().c_str(), param.c_str());
  // Setup parameters
  params::convert(_params, param);

  params::const_iterator it = _params.find(params::codecs);
  if (it != _params.cend()) {
    _codec.set_payload_codecs(it->second);
  }
}

void http_layer::sendMsg(const LibItsHttp__TypesAndValues::HttpMessage& p_http_message, params& p_param) {
  loggers::get_instance().log_msg(">>> http_layer::sendMsg: ", p_http_message);

  // Encode HttpMessage
  OCTETSTRING data;
  _codec.encode(p_http_message, data);
  send_data(data, _params);
}

void http_layer::send_data(OCTETSTRING& data, params& params) {
  loggers::get_instance().log_msg(">>> http_layer::send_data: ", data);

  send_to_all_layers(data, params);
}

void http_layer::receive_data(OCTETSTRING& data, params& params)
{
  loggers::get_instance().log_msg(">>> http_layer::receive_data: ", data);

  // Decode HTTP message
  LibItsHttp__TypesAndValues::HttpMessage http_message;
  if (_codec.decode(data, http_message) == -1) {
    loggers::get_instance().warning("http_layer::receive_data: Failed to decode data");
    return;
  }
  
  // Pass it to the ports
  to_all_upper_ports(http_message, params);
}

http_layer_factory http_layer_factory::_f;

