/**
 * Namf_Communication
 * AMF Communication Service © 2019, 3GPP Organizational Partners (ARIB, ATIS,
 * CCSA, ETSI, TSDSI, TTA, TTC). All rights reserved.
 *
 * The version of the OpenAPI document: 1.1.0.alpha-1
 *
 *
 * NOTE: This class is auto generated by OpenAPI Generator
 * (https://openapi-generator.tech). https://openapi-generator.tech Do not edit
 * the class manually.
 */

#include "N1N2MessageCollectionDocumentApiImpl.h"
#include "itti.hpp"
//#include "itti_msg_n2.hpp"
#include "amf_n2.hpp"
#include "amf_n11.hpp"

//#include "amf_n2.hpp"
//#include "Paging.hpp"

#include "pdu_session_context.hpp"
using namespace amf_application;
using namespace ngap;

extern void octet_stream_2_hex_stream(uint8_t *buf, int len, std::string &out);
extern void msg_str_2_msg_hex(std::string msg, bstring& b);
extern void convert_string_2_hex(std::string& input, std::string& output);
extern itti_mw* itti_inst;
extern amf_n11* amf_n11_inst;
extern amf_n2* amf_n2_inst;
//extern amf_n2* amf_n2_inst;

extern void print_buffer(
    const std::string app, const std::string commit, uint8_t* buf, int len);

namespace oai {
namespace amf {
namespace api {

using namespace oai::amf::model;

N1N2MessageCollectionDocumentApiImpl::N1N2MessageCollectionDocumentApiImpl(
    std::shared_ptr<Pistache::Rest::Router> rtr,
    amf_application::amf_app* amf_app_inst)
    : N1N2MessageCollectionDocumentApi(rtr), m_amf_app(amf_app_inst) {}

void N1N2MessageCollectionDocumentApiImpl::n1_n2_message_transfer(
    const std::string& ueContextId,
    const N1N2MessageTransferReqData& n1N2MessageTransferReqData,
    Pistache::Http::ResponseWriter& response) {
  Logger::amf_server().debug("Response OK");
  response.send(
      Pistache::Http::Code::Ok,
      "N1N2MessageCollectionDocumentApiImpl::n1_n2_message_transfer API has "
      "not been implemented yet!");
}


void N1N2MessageCollectionDocumentApiImpl::n1_n2_message_transfer(
    const std::string& ueContextId,
    const N1N2MessageTransferReqData& n1N2MessageTransferReqData,
    std::string& n1sm_str, Pistache::Http::ResponseWriter& response) {
  Logger::amf_server().debug(
      "Receive N1N2MessageTransfer Request, handling...");

  bstring n1sm;
  msg_str_2_msg_hex(n1sm_str, n1sm);
  print_buffer(
      "amf_server", "Received N1 SM", (uint8_t*) bdata(n1sm), blength(n1sm));
  response.send(
      Pistache::Http::Code::Ok,
      "N1N2MessageCollectionDocumentApiImpl::n1_n2_message_transfer API has "
      "not been implemented yet!");
}

void N1N2MessageCollectionDocumentApiImpl::n1_n2_message_transfer(
    const std::string& ueContextId,
    const N1N2MessageTransferReqData& n1N2MessageTransferReqData,
    std::string& n1sm_str, std::string& n2sm_str,
    Pistache::Http::ResponseWriter& response) {
  Logger::amf_server().debug(
      "Receive N1N2MessageTransfer Request, handling...");
  response.send(Pistache::Http::Code::Ok, "OK");

  std::string supi = ueContextId;
  Logger::amf_server().debug(
      "Key for PDU Session context: SUPI (%s)", supi.c_str());
  //std::shared_ptr<pdu_session_context> psc;
std::shared_ptr<pdu_session_context> psc = std::shared_ptr<pdu_session_context>(new pdu_session_context());
  //***************************stateless
    sleep(1);
  nlohmann::json udsf_response;

  std::string record_id = "RECORD_ID=\'" +supi  + "\'";
  std::string udsf_url = "http://10.103.239.53:7123/nudsf-dr/v1/amfdata/" + std::string("pdu_session_context/records/") + record_id ;
  if(!amf_n2_inst->curl_http_client_udsf(udsf_url,"","GET",udsf_response)){
    Logger::amf_n2().error("No existing pdu_session_context with assoc_id ");
  }
  else{
     Logger::amf_n2().debug("udsf_response: %s", udsf_response.dump().c_str());
      psc.get()->pdu_session_context_from_json(udsf_response);
      //psc = std::shared_ptr<pdu_session_context>(psc1);
  }
  //***************************stateless

//   if (amf_n11_inst->is_supi_to_pdu_ctx(supi)) {
//     psc = amf_n11_inst->supi_to_pdu_ctx(supi);
//   } else {
//     Logger::amf_server().error(
//         "Cannot get pdu_session_context with SUPI (%s)", supi.c_str());
//   }
  bstring n1sm;
  msg_str_2_msg_hex(
      n1sm_str.substr(0, n1sm_str.length()),
      n1sm);  // TODO: verify n1sm_length

  bstring n2sm;
  msg_str_2_msg_hex(n2sm_str, n2sm);

  psc.get()->n1sm             = n1sm;
  psc.get()->isn1sm_avaliable = true;
  psc.get()->n2sm             = n2sm;
  psc.get()->isn2sm_avaliable = true;

    string n1sm_udsf;
    string n2sm_udsf;
    octet_stream_2_hex_stream((uint8_t*) bdata(psc.get()->n1sm), blength(psc.get()->n1sm), n1sm_udsf);
    octet_stream_2_hex_stream((uint8_t*) bdata(psc.get()->n2sm), blength(psc.get()->n2sm), n2sm_udsf);


    record_id = "RECORD_ID=\'" +supi  + "\'";
    std::string udsf_put_url = "http://10.103.239.53:7123/nudsf-dr/v1/amfdata/" + std::string("pdu_session_context/records/") + record_id ;
    nlohmann::json udsf_put_pdu_session_context;
    //nlohmann::json udsf_response;
    udsf_put_pdu_session_context["meta"] ["tags"] = {
                                        {"RECORD_ID",nlohmann::json::array({supi})},
                                        {"from_nf_ID",nlohmann::json::array({"AMF_1234"})}
                                        } ;
    udsf_put_pdu_session_context["blocks"] = nlohmann::json::array({
    {{"Content-ID", "n2sm"},{"Content-Type", "varchar(1024)"},{"content",n2sm_udsf}},
    {{"Content-ID", "isn2sm_avaliable"},{"Content-Type", "varchar(32)"},{"content",to_string(psc.get()->isn2sm_avaliable)}},
    {{"Content-ID", "n1sm"},{"Content-Type", "varchar(1024)"},{"content", n1sm_udsf}},
    {{"Content-ID", "isn1sm_avaliable"},{"Content-Type", "varchar(32)"},{"content", to_string(psc.get()->isn1sm_avaliable)}},
    });
    std::string json_part = udsf_put_pdu_session_context.dump();
    amf_n2_inst->curl_http_client_udsf(udsf_put_url,json_part,"PUT",udsf_response);


  Logger::amf_server().debug(
      "n2sm size in amf_server(%d)", blength(psc.get()->n2sm));

  itti_n1n2_message_transfer_request* itti_msg =
      new itti_n1n2_message_transfer_request(AMF_SERVER, TASK_AMF_APP);
  itti_msg->supi        = ueContextId;
  itti_msg->n1sm        = n1sm;
  itti_msg->is_n1sm_set = true;
  itti_msg->n2sm        = n2sm;
  itti_msg->is_n2sm_set = true;
  itti_msg->pdu_session_id =
      (uint8_t) n1N2MessageTransferReqData.getPduSessionId();
  std::shared_ptr<itti_n1n2_message_transfer_request> i =
      std::shared_ptr<itti_n1n2_message_transfer_request>(itti_msg);
  int ret = itti_inst->send_msg(i);
  if (0 != ret) {
    Logger::amf_server().error(
        "Could not send ITTI message %s to task TASK_AMF_N2",
        i->get_msg_name());
  }
}

}  // namespace api
}  // namespace amf
}  // namespace oai
