#include <iostream>
#include "cwmp.nsmap"
#include "httppost.h"
#include "soapcwmpService.h"
#include "plugin/threads.h"
#include <vector>
#include <algorithm>
#include <signal.h>
#include <thread>
#include <fstream>
#include "json.hpp"
#include <iomanip>
#include <chrono>


using json = nlohmann::json;

int port = 7547;
//int port = 8000;

int POST_handler(struct soap *soap);

struct http_post_handlers http_post_handlers[] = {
        {"POST", POST_handler},
        {NULL}
};
std::string currentISO8601TimeUTC() {
    auto now = std::chrono::system_clock::now();
    auto itt = std::chrono::system_clock::to_time_t(now);
    auto duration = now.time_since_epoch();
    auto millis = std::chrono::duration_cast<std::chrono::milliseconds>(duration).count();
    std::ostringstream ss;
    ss << std::put_time(gmtime(&itt), "%FT%T%z");
    return ss.str();
}
void handler(int s) {
    printf("Sassan Caught SIGPIPE...\n");
}

void *process_request(void *arg) {
    cwmpService *service = (cwmpService *) arg;
    THREAD_DETACH(THREAD_ID);
    if (service) {
        service->serve();
        service->destroy(); /* clean up */
        delete service;
    }
    return NULL;
}

//<editor-fold desc="zbx_keys">

std::string zbx_keys[] = {"InternetGatewayDevice.WANDevice.1.WANConnectionDevice.1.WANIPConnection.1.Uptime",
                          "InternetGatewayDevice.WEB_GUI.Network.LTE_Setting.Status.UL_MCS",
                          "InternetGatewayDevice.WEB_GUI.Network.LTE_Setting.Status.TX_Power",
                          "InternetGatewayDevice.DeviceInfo.SoftwareVersion",
                          "InternetGatewayDevice.WANDevice.1.X_TGT_WANNetConfigInfo.SINR2",
                          "InternetGatewayDevice.WANDevice.1.X_TGT_WANNetConfigInfo.SINR1",
                          "InternetGatewayDevice.WEB_GUI.Network.LTE_Setting.Status.RSRP2",
                          "InternetGatewayDevice.WANDevice.1.X_TGT_WANNetConfigInfo.RSRQ",
                          "InternetGatewayDevice.WEB_GUI.Network.LTE_Setting.Status.RSRQ",
                          "InternetGatewayDevice.LANDevice.1.LANHostConfigManagement.DHCPServerEnable",
                          "InternetGatewayDevice.WEB_GUI.Network.LTE_Setting.Setting.Status",
                          "InternetGatewayDevice.WANDevice.1.WANConnectionDevice.1.WANIPConnection.1.ConnectionStatus",
                          "InternetGatewayDevice.WEB_GUI.Network.LTE_Setting.Status.RSRP1",
                          "InternetGatewayDevice.WANDevice.1.WANConnectionDevice.1.WANIPConnection.1.ExternalIPAddress",
                          "InternetGatewayDevice.WEB_GUI.Overview.DeviceInfo.IMSI",
                          "InternetGatewayDevice.WEB_GUI.Overview.DeviceInfo.IMEI",
                          "InternetGatewayDevice.WANDevice.1.X_TGT_WANNetConfigInfo.EnodeBId",
                          "InternetGatewayDevice.DeviceInfo.MemoryStatus.Free",
                          "InternetGatewayDevice.WANDevice.1.X_TGT_WANNetConfigInfo.EnodeBId",
                          "InternetGatewayDevice.WEB_GUI.Network.LTE_Setting.Status.DL_MCS",
                          "InternetGatewayDevice.Time.CurrentLocalTime",
                          "InternetGatewayDevice.DeviceInfo.ProcessStatus.CPUUsage",
                          "InternetGatewayDevice.WANDevice.1.X_TGT_WANNetConfigInfo.CellId",
                          "InternetGatewayDevice.WANDevice.1.WANEthernetInterfaceConfig.Stats.BytesSent",
                          "InternetGatewayDevice.WANDevice.1.WANEthernetInterfaceConfig.Stats.BytesReceived",
                          "InternetGatewayDevice.WANDevice.1.WANEthernetInterfaceConfig.Stats.PacketsReceived",
                          "InternetGatewayDevice.WANDevice.1.WANEthernetInterfaceConfig.Stats.PacketsSent",
                          "InternetGatewayDevice.DeviceInfo.UpTime",
                          "InternetGatewayDevice.DeviceInfo.X_TGT_IMSI",
                          "InternetGatewayDevice.WEB_GUI.Network.Network_Mode.WANIPAddress",
                          "InternetGatewayDevice.WEB_GUI.Network.ScanMode.Settings.PCILock",
                          "InternetGatewayDevice.WEB_GUI.Overview.LTEStatus.DnsServer",
                          "InternetGatewayDevice.DeviceInfo.HardwareVersion",
                          "InternetGatewayDevice.DeviceInfo.Manufacturer",
                          "InternetGatewayDevice.DeviceInfo.ManufacturerOUI",
                          "InternetGatewayDevice.DeviceInfo.ModelName",
                          "InternetGatewayDevice.DeviceInfo.ModelNumber",
                          "InternetGatewayDevice.DeviceInfo.Description",
                          "InternetGatewayDevice.DeviceInfo.ProductClass",
                          "InternetGatewayDevice.DeviceInfo.SerialNumber",
                          "InternetGatewayDevice.LANDevice.1.LANEthernetInterfaceConfig.1.Enable",
                          "InternetGatewayDevice.LANDevice.1.LANEthernetInterfaceConfig.2.Enable",
                          "InternetGatewayDevice.WANDevice.1.WANEthernetInterfaceConfig.Enable",
                          "InternetGatewayDevice.WEB_GUI.Overview.LTEStatus.DL_DataRate_Current",
                          "InternetGatewayDevice.WEB_GUI.Overview.LTEStatus.UL_DataRate_Current",
                          "InternetGatewayDevice.WEB_GUI.Network.LTE_Setting.Status.PCI",
                          "InternetGatewayDevice.WEB_GUI.Overview.LANStatus.MacAddress",
                          "InternetGatewayDevice.WEB_GUI.Network.LTE_Setting.Status.DL_Frequency",
                          "InternetGatewayDevice.WEB_GUI.Network.LTE_Setting.Status.UL_Frequency",
                          "InternetGatewayDevice.ManagementServer.ConnectionRequestURL"
};



//</editor-fold>

void ZBX_Send(char **Name, char **Value, char **imsi) {
    if (!strcmp(*Name, "InternetGatewayDevice.WEB_GUI.Network.LTE_Setting.Status.DL_MCS") == 0 or
        !strcmp(*Name, "InternetGatewayDevice.WEB_GUI.Network.LTE_Setting.Status.UL_MCS") == 0) {
        if (!strcmp(*Value, "QPSK")) {
            *Value = "4";
        } else if (!strcmp(*Value, "QAM8")) {
            *Value = "8";
        } else if (!strcmp(*Value, "QAM16")) {
            *Value = "16";
        } else if (!strcmp(*Value, "QAM32")) {
            *Value = "32";
        } else if (!strcmp(*Value, "QAM64")) {
            *Value = "64";
        }
        std::ofstream zbx_data;
        std::string _time{};
        time_t second;
        second = time(NULL);
        std::stringstream strstream;
        strstream << second;
        strstream >> _time;
        zbx_data.open("/var/tmp/zbx_sender-"+_time, std::ios_base::app);
        zbx_data << "IMSI-" << *imsi << " " << *Name << " " << second << " \"" << *Value << "\"" << std::endl;

    }
}

std::string url_encode(const std::string &value) {
    std::ostringstream escaped;
    escaped.fill('0');
    escaped << std::hex;

    for (std::string::const_iterator i = value.begin(), n = value.end(); i != n; ++i) {
        std::string::value_type c = (*i);

        // Keep alphanumeric and other accepted characters intact
        if (isalnum(c) || c == '-' || c == '_' || c == '.' || c == '~') {
            escaped << c;
            continue;
        }

        // Any other characters are percent-encoded
        escaped << std::uppercase;
        escaped << '%' << std::setw(2) << int((unsigned char) c);
        escaped << std::nouppercase;
    }

    return escaped.str();
}

int main() {
    signal(SIGPIPE, handler);
    std::cout << "TR069 Server Started (1.1)...\n" << std::endl;
    cwmpService service(SOAP_XML_INDENT);
    service.soap->send_timeout = service.soap->recv_timeout = 5;
    service.soap->transfer_timeout = 30;

    service.soap->keep_alive = 1;
    service.soap->tcp_keep_alive = 1;
    service.soap->bind_flags |= SO_REUSEADDR;
    service.soap->bind_flags |= SO_REUSEPORT;
    service.soap->bind_flags |= MSG_NOSIGNAL;

    soap_init2(service.soap, SOAP_IO_KEEPALIVE, SOAP_IO_KEEPALIVE);
    SOAP_SOCKET m = service.bind(NULL, port, 1024);              /* master socket */
    if (soap_valid_socket(m)) {
        while (soap_valid_socket(service.accept())) {
            THREAD_TYPE tid;
            void *arg = (void *) service.copy();
            if (arg)
                while (THREAD_CREATE(&tid, (void *(*)(void *)) process_request, arg))
                    sleep(1);
        }
    }
    service.soap_stream_fault(std::cerr);
    service.destroy(); /* clean up */

    return 0;
}


int POST_handler(struct soap *soap) {
//    struct _cwmp__GetParameterValues *res = soap_new__cwmp__GetParameterValues(soap, -1);
//    struct ParameterNames *list = soap_new_ParameterNames(soap, -1);
    const char *buf;
    size_t len;
    buf = soap_http_get_body(soap, &len);
//    std::cerr<<"Sassan3 ID:  "<<soap->header->cwmp__SupportedCWMPVersions<<std::endl;
//    std::cerr<<"Debug1: "<<len<<std::endl;
//    std::cerr<<"Debug2: "<<buf<<std::endl;
    /* if HTTP has a content type header or a HTTP body is present then return 404 */
    if (len == 0) {
        std::cerr << "Sassan 204...: " << buf << std::endl;
        return 204; // HTTP 400 Bad Request
//    }else {
//        std::cerr<<"Debug0: "<<buf<<std::endl;
//        std::cerr<<"Debug1: "<<len<<std::endl;
//        std::cerr<<"Debug2: "<<buf<<std::endl;
    }

//    if (soap->http_content || soap_http_has_body(soap))
//        return 404;
//    (void)soap_end_recv(soap);
//    /* populate the response with one array item */
//    if (res && list)
//    {
//        list->__size = 1;
//        if ((list->__ptrstring = (char**)soap_malloc(soap, list->__size * sizeof(char*))) != NULL)
//        {
//            list->__ptrstring[0] = soap_strdup(soap, "...");
//            res->ParameterNames = list;
//        }
//    }
//    /* send response */
//    soap->encodingStyle = "";
//    soap_serializeheader(soap);
//    soap_serialize__cwmp__GetParameterValues(soap, res);
//    if (soap_begin_count(soap))
//        return soap->error;
//    if (soap->mode & SOAP_IO_LENGTH)
//    {
//        if (soap_envelope_begin_out(soap)
//            || soap_putheader(soap)
//            || soap_body_begin_out(soap)
//            || soap_put__cwmp__GetParameterValues(soap, res, "cwmp:GetParameterValues", "")
//            || soap_body_end_out(soap)
//            || soap_envelope_end_out(soap))
//            return soap->error;
//    };
//    if (soap_end_count(soap)
//        || soap_response(soap, SOAP_OK)
//        || soap_envelope_begin_out(soap)
//        || soap_putheader(soap)
//        || soap_body_begin_out(soap)
//        || soap_put__cwmp__GetParameterValues(soap, res, "cwmp:GetParameterValues", "")
//        || soap_body_end_out(soap)
//        || soap_envelope_end_out(soap)
//        || soap_end_send(soap))
//        return soap->error;
//    return soap_closesock(soap);
}

int cwmpService::GetParameterNames(struct _cwmp__GetParameterNames *cwmp__GetParameterNames,
                                   struct _cwmp__GetParameterNamesResponse *cwmp__GetParameterNamesResponse) { return SOAP_OK; }

int cwmpService::GetParameterValues(struct _cwmp__GetParameterValues *cwmp__GetParameterValues,
                                    struct _cwmp__GetParameterValuesResponse *cwmp__GetParameterValuesResponse) { return SOAP_OK; }

int cwmpService::SetParameterValues(struct _cwmp__SetParameterValues *cwmp__SetParameterValues,
                                    struct _cwmp__SetParameterValuesResponse *cwmp__SetParameterValuesResponse) { return SOAP_OK; }

int cwmpService::SetParameterAttributes(
        struct _cwmp__SetParameterAttributes *cwmp__SetParameterAttributes,
        struct _cwmp__SetParameterAttributesResponse *cwmp__SetParameterAttributesResponse) { return SOAP_OK; }

int cwmpService::GetParameterAttributes(struct _cwmp__GetParameterAttributes *cwmp__GetParameterAttributes,
                                        struct _cwmp__GetParameterAttributesResponse *cwmp__GetParameterAttributesResponse) { return SOAP_OK; }

int cwmpService::Download(struct _cwmp__Download *cwmp__Download,
                          struct _cwmp__DownloadResponse *cwmp__DownloadResponse) { return SOAP_OK; }

int cwmpService::Upload(
        struct _cwmp__Upload *cwmp__Upload,
        struct _cwmp__UploadResponse *cwmp__UploadResponse) { return SOAP_OK; }

int cwmpService::AddObject(
        struct _cwmp__AddObject *cwmp__AddObject,
        struct _cwmp__AddObjectResponse *cwmp__AddObjectResponse) { return SOAP_OK; }

int cwmpService::DeleteObject(
        struct _cwmp__DeleteObject *cwmp__DeleteObject,
        struct _cwmp__DeleteObjectResponse *cwmp__DeleteObjectResponse) { return SOAP_OK; }

int cwmpService::GetRPCMethods(
        struct _cwmp__GetRPCMethods *cwmp__GetRPCMethods,
        struct _cwmp__GetRPCMethodsResponse *cwmp__GetRPCMethodsResponse) { return SOAP_OK; }

int cwmpService::GetParameterValuesResponse(
        struct _cwmp__GetParameterValuesResponse *cwmp__GetParameterValuesResponse) { return SOAP_OK; }

int cwmpService::Inform(struct _cwmp__Inform *cwmp__Inform,
                        struct _cwmp__InformResponse *cwmp__InformResponse) {


    std::string _id = std::string(cwmp__Inform->DeviceId->OUI) + "-" + std::string(cwmp__Inform->DeviceId->ProductClass)
                      + "-" + std::string(cwmp__Inform->DeviceId->SerialNumber);
    std::cerr << "Inform Recieved from: " << url_encode(_id) << " at " << time(NULL) << std::endl;
    char *imsi;
    auto timestamp = std::chrono::high_resolution_clock::now();
    std::vector<std::thread> th;
    std::vector<std::thread> th_acs;
//    int indexes[24];
    std::vector<int> ind;

    std::ofstream mongoData;
    time_t second;
    std::string _time;
    std::map<std::string, std::string> tr069{};
    second = time(NULL);
    std::stringstream strstream;
    strstream << second;
    strstream >> _time;
    for (int i = 0; i < cwmp__Inform->ParameterList->__size; ++i) {
        char *_Name = cwmp__Inform->ParameterList->__ptrParameterValueStruct[i]->Name;
        char *_Value = cwmp__Inform->ParameterList->__ptrParameterValueStruct[i]->Value;
        if (std::string(_Name).compare("InternetGatewayDevice.DeviceInfo.X_TGT_IMSI")==0) {
            imsi = _Value;
        }
        std::string cpe = cwmp__Inform->DeviceId->SerialNumber;
        auto j = std::find(std::begin(zbx_keys), std::end(zbx_keys),_Name);
        if (j != std::end(zbx_keys)) {
//            th.push_back(std::thread(ZBX_Send, &_Name,&_Value, &imsi));
//            ind.push_back(i);
            th.push_back(std::thread(ZBX_Send, &cwmp__Inform->ParameterList->__ptrParameterValueStruct[i]->Name,
                                     &cwmp__Inform->ParameterList->__ptrParameterValueStruct[i]->Value, &imsi));

//<editor-fold desc="Map Filler">
            if (std::string(_Name).compare("InternetGatewayDevice.DeviceInfo.HardwareVersion") == 0)
                tr069.insert({"HardwareVersion", _Value});
            else if (std::string(_Name).compare("InternetGatewayDevice.DeviceInfo.SoftwareVersion") == 0)
                tr069.insert({"SoftwareVersion", _Value});
            else if (std::string(_Name).compare("InternetGatewayDevice.DeviceInfo.UpTime") == 0)
                tr069.insert({"UpTime", _Value});
            else if (std::string(_Name).compare("InternetGatewayDevice.WEB_GUI.Overview.DeviceInfo.IMEI") == 0)
                tr069.insert({"IMEI", _Value});
            else if (std::string(_Name).compare("InternetGatewayDevice.DeviceInfo.X_TGT_IMSI") == 0)
                tr069.insert({"IMSI", _Value});
            else if (std::string(_Name).compare("InternetGatewayDevice.DeviceInfo.MemoryStatus.Free") == 0)
                tr069.insert({"Free", _Value});
            else if (std::string(_Name).compare("InternetGatewayDevice.DeviceInfo.ProcessStatus.CPUUsage") == 0)
                tr069.insert({"CPUUsage", _Value});
            else if (std::string(_Name).compare("InternetGatewayDevice.Time.CurrentLocalTime") == 0)
                tr069.insert({"CurrentLocalTime", _Value});
            else if (std::string(_Name).compare("InternetGatewayDevice.LANDevice.1.LANEthernetInterfaceConfig.1.Enable") == 0)
                tr069.insert({"LAN1Enable", _Value});
            else if (std::string(_Name).compare("InternetGatewayDevice.LANDevice.1.LANEthernetInterfaceConfig.2.Enable") == 0)
                tr069.insert({"LAN2Enable", _Value});
            else if (std::string(_Name).compare("InternetGatewayDevice.WANDevice.1.X_TGT_WANNetConfigInfo.SINR1") == 0)
                tr069.insert({"SINR1", _Value});
            else if (std::string(_Name).compare("InternetGatewayDevice.WANDevice.1.X_TGT_WANNetConfigInfo.SINR2") == 0)
                tr069.insert({"SINR2", _Value});
            else if (std::string(_Name).compare("InternetGatewayDevice.WANDevice.1.X_TGT_WANNetConfigInfo.EnodeBId") ==
                     0)
                tr069.insert({"EnodeBId", _Value});
            else if (std::string(_Name).compare("InternetGatewayDevice.WANDevice.1.X_TGT_WANNetConfigInfo.CellId") == 0)
                tr069.insert({"CellId", _Value});
            else if (std::string(_Name).compare(
                    "InternetGatewayDevice.WANDevice.1.WANEthernetInterfaceConfig.Stats.BytesSent") == 0)
                tr069.insert({"BytesSent", _Value});
            else if (std::string(_Name).compare(
                    "InternetGatewayDevice.WANDevice.1.WANEthernetInterfaceConfig.Stats.BytesReceived") == 0)
                tr069.insert({"BytesReceived", _Value});
            else if (std::string(_Name).compare(
                    "InternetGatewayDevice.WANDevice.1.WANEthernetInterfaceConfig.Stats.PacketsSent") == 0)
                tr069.insert({"PacketsSent", _Value});
            else if (std::string(_Name).compare(
                    "InternetGatewayDevice.WANDevice.1.WANEthernetInterfaceConfig.Stats.PacketsReceived") == 0)
                tr069.insert({"PacketsReceived", _Value});
            else if (std::string(_Name).compare(
                    "InternetGatewayDevice.WANDevice.1.WANConnectionDevice.1.WANIPConnection.1.ConnectionStatus") == 0)
                tr069.insert({"ConnectionStatus", _Value});
            else if (std::string(_Name).compare(
                    "InternetGatewayDevice.WANDevice.1.WANConnectionDevice.1.WANIPConnection.1.Uptime") == 0)
                tr069.insert({"Uptime", _Value});
            else if (std::string(_Name).compare(
                    "InternetGatewayDevice.WANDevice.1.WANConnectionDevice.1.WANIPConnection.1.ExternalIPAddress") == 0)
                tr069.insert({"ExternalIPAddress", _Value});
            else if (std::string(_Name).compare("InternetGatewayDevice.WEB_GUI.Network.LTE_Setting.Status.RSRP1") == 0)
                tr069.insert({"RSRP1", _Value});
            else if (std::string(_Name).compare("InternetGatewayDevice.WEB_GUI.Network.LTE_Setting.Status.RSRP2") == 0)
                tr069.insert({"RSRP2", _Value});
            else if (std::string(_Name).compare("InternetGatewayDevice.WEB_GUI.Network.LTE_Setting.Status.TX_Power") ==
                     0)
                tr069.insert({"TX_Power", _Value});
            else if (std::string(_Name).compare("InternetGatewayDevice.WEB_GUI.Network.LTE_Setting.Status.DL_MCS") == 0)
                tr069.insert({"DL_MCS", _Value});
            else if (std::string(_Name).compare("InternetGatewayDevice.WEB_GUI.Network.LTE_Setting.Status.UL_MCS") == 0)
                tr069.insert({"UL_MCS", _Value});
            else if (std::string(_Name).compare("InternetGatewayDevice.WEB_GUI.Network.LTE_Setting.Setting.Status") ==
                     0)
                tr069.insert({"LTEStatus", _Value});
            else if (std::string(_Name).compare("InternetGatewayDevice.WEB_GUI.Network.ScanMode.Settings.PCILock") == 0)
                tr069.insert({"PCILock", _Value});
            else if (std::string(_Name).compare("InternetGatewayDevice.WEB_GUI.Network.Network_Mode.WANIPAddress") == 0)
                tr069.insert({"WANIPAddress", _Value});
            else if (std::string(_Name).compare("InternetGatewayDevice.WEB_GUI.Overview.LTEStatus.DnsServer") == 0)
                tr069.insert({"DnsServer", _Value});
            else if (std::string(_Name).compare("InternetGatewayDevice.WEB_GUI.Overview.DeviceInfo.IMSI") == 0)
                tr069.insert({"IMSI", _Value});
            else if (std::string(_Name).compare("InternetGatewayDevice.DeviceInfo.Manufacturer") == 0)
                tr069.insert({"Manufacturer", _Value});
            else if (std::string(_Name).compare("InternetGatewayDevice.DeviceInfo.ManufacturerOUI") == 0)
                tr069.insert({"OUI", _Value});
            else if (std::string(_Name).compare("InternetGatewayDevice.DeviceInfo.ModelName") == 0)
                tr069.insert({"ModelName", _Value});
            else if (std::string(_Name).compare("InternetGatewayDevice.DeviceInfo.ModelNumber") == 0)
                tr069.insert({"ModelNumber", _Value});
            else if (std::string(_Name).compare("InternetGatewayDevice.DeviceInfo.Description") == 0)
                tr069.insert({"Description", _Value});
            else if (std::string(_Name).compare("InternetGatewayDevice.DeviceInfo.ProductClass") == 0)
                tr069.insert({"ProductClass", _Value});
            else if (std::string(_Name).compare("InternetGatewayDevice.DeviceInfo.SerialNumber") == 0)
                tr069.insert({"SerialNumber", _Value});
            else if (std::string(_Name).compare("InternetGatewayDevice.WANDevice.1.X_TGT_WANNetConfigInfo.RSRQ") == 0)
                tr069.insert({"RSRQ", _Value});
            else if (std::string(_Name).compare("InternetGatewayDevice.LANDevice.1.LANHostConfigManagement.DHCPServerEnable") == 0)
                tr069.insert({"DHCPServerEnable", _Value});
            else if (std::string(_Name).compare("InternetGatewayDevice.WANDevice.1.WANEthernetInterfaceConfig.Enable") == 0)
                tr069.insert({"WANEthernetInterfaceConfigEnable", _Value});
            else if (std::string(_Name).compare("InternetGatewayDevice.ManagementServer.ConnectionRequestURL") == 0)
                tr069.insert({"ConnectionRequestURL", _Value});
            else if (std::string(_Name).compare("InternetGatewayDevice.WEB_GUI.Overview.LTEStatus.DL_DataRate_Current") == 0)
                tr069.insert({"DL_DataRate_Current", _Value});
            else if (std::string(_Name).compare("InternetGatewayDevice.WEB_GUI.Overview.LTEStatus.UL_DataRate_Current") == 0)
                tr069.insert({"UL_DataRate_Current", _Value});
            else if (std::string(_Name).compare("InternetGatewayDevice.WEB_GUI.Network.LTE_Setting.Status.PCI") == 0)
                tr069.insert({"PCI", _Value});
            else if (std::string(_Name).compare("InternetGatewayDevice.WEB_GUI.Network.LTE_Setting.Status.UL_Frequency") == 0)
                tr069.insert({"UL_Frequency", _Value});
            else if (std::string(_Name).compare("InternetGatewayDevice.WEB_GUI.Network.LTE_Setting.Status.DL_Frequency") == 0)
                tr069.insert({"DL_Frequency", _Value});
            else if (std::string(_Name).compare("InternetGatewayDevice.WEB_GUI.Overview.LANStatus.MacAddress") == 0)
                tr069.insert({"MacAddress", _Value});


//            std::cerr<<"Key: "<<cwmp__Inform->ParameterList->__ptrParameterValueStruct[i]->Name<<std::endl;
//            std::cerr<<"Value: "<<cwmp__Inform->ParameterList->__ptrParameterValueStruct[i]->Value<<std::endl;



//</editor-fold>
        }
    }
    for (auto &t : th) {
        t.join();
    }

//<editor-fold desc="Json">
    std::string ISOTime=currentISO8601TimeUTC();
    json tr069_json{};
    tr069_json["_id"]=url_encode(_id);
    tr069_json["_deviceId"]["_Manufacturer"]=cwmp__Inform->DeviceId->Manufacturer;
    tr069_json["_deviceId"]["_OUI"]=cwmp__Inform->DeviceId->OUI ;
    tr069_json["_deviceId"]["_ProductClass"]=cwmp__Inform->DeviceId->ProductClass;
    tr069_json["_deviceId"]["_SerialNumber"]=cwmp__Inform->DeviceId->SerialNumber;
    tr069_json["_lastInform"]=ISOTime;
    tr069_json["InternetGatewayDevice"]["WANDevice"]["1"]["WANConnectionDevice"]["1"]["WANIPConnection"]["1"]["Uptime"]["_value"]=tr069["Uptime"] ;
    tr069_json["InternetGatewayDevice"]["WEB_GUI"]["Network"]["LTE_Setting"]["Status"]["UL_MCS"]["_value"]=tr069["UL_MCS"] ;
    tr069_json["InternetGatewayDevice"]["WEB_GUI"]["Network"]["LTE_Setting"]["Status"]["TX_Power"]["_value"]=tr069["TX_Power"] ;
    tr069_json["InternetGatewayDevice"]["DeviceInfo"]["SoftwareVersion"]["_value"]=tr069["SoftwareVersion"] ;
    tr069_json["InternetGatewayDevice"]["WANDevice"]["1"]["X_TGT_WANNetConfigInfo"]["SINR2"]["_value"]=tr069["SINR2"] ;
    tr069_json["InternetGatewayDevice"]["WANDevice"]["1"]["X_TGT_WANNetConfigInfo"]["SINR1"]["_value"]=tr069["SINR1"] ;
    tr069_json["InternetGatewayDevice"]["WEB_GUI"]["Network"]["LTE_Setting"]["Status"]["RSRP2"]["_value"]=tr069["RSRP2"] ;
    tr069_json["InternetGatewayDevice"]["WANDevice"]["1"]["X_TGT_WANNetConfigInfo"]["RSRQ"]["_value"]=tr069["RSRQ"] ;
    tr069_json["InternetGatewayDevice"]["WEB_GUI"]["Network"]["LTE_Setting"]["Status"]["RSRQ"]["_value"]=tr069["RSRQ"] ;
    tr069_json["InternetGatewayDevice"]["LANDevice"]["1"]["LANHostConfigManagement"]["DHCPServerEnable"]["_value"]=tr069["DHCPServerEnable"] ;
    tr069_json["InternetGatewayDevice"]["WEB_GUI"]["Network"]["LTE_Setting"]["Setting"]["Status"]["_value"]=tr069["LTEStatus"] ;
    tr069_json["InternetGatewayDevice"]["WANDevice"]["1"]["WANConnectionDevice"]["1"]["WANIPConnection"]["1"]["ConnectionStatus"]["_value"]=tr069["ConnectionStatus"] ;
    tr069_json["InternetGatewayDevice"]["WEB_GUI"]["Network"]["LTE_Setting"]["Status"]["RSRP1"]["_value"]=tr069["RSRP1"] ;
    tr069_json["InternetGatewayDevice"]["WANDevice"]["1"]["WANConnectionDevice"]["1"]["WANIPConnection"]["1"]["ExternalIPAddress"]["_value"]=tr069["ExternalIPAddress"] ;
    tr069_json["InternetGatewayDevice"]["WEB_GUI"]["Overview"]["DeviceInfo"]["IMSI"]["_value"]=tr069["IMSI"] ;
    tr069_json["InternetGatewayDevice"]["WEB_GUI"]["Overview"]["DeviceInfo"]["IMEI"]["_value"]=tr069["IMEI"] ;
    tr069_json["InternetGatewayDevice"]["WANDevice"]["1"]["X_TGT_WANNetConfigInfo"]["EnodeBId"]["_value"]=tr069["EnodeBId"] ;
    tr069_json["InternetGatewayDevice"]["DeviceInfo"]["MemoryStatus"]["Free"]["_value"]=tr069["Free"] ;
    tr069_json["InternetGatewayDevice"]["WANDevice"]["1"]["X_TGT_WANNetConfigInfo"]["EnodeBId"]["_value"]=tr069["EnodeBId"] ;
    tr069_json["InternetGatewayDevice"]["WEB_GUI"]["Network"]["LTE_Setting"]["Status"]["DL_MCS"]["_value"]=tr069["DL_MCS"] ;
    tr069_json["InternetGatewayDevice"]["Time"]["CurrentLocalTime"]["_value"]=tr069["CurrentLocalTime"] ;
    tr069_json["InternetGatewayDevice"]["DeviceInfo"]["ProcessStatus"]["CPUUsage"]["_value"]=tr069["CPUUsage"] ;
    tr069_json["InternetGatewayDevice"]["WANDevice"]["1"]["X_TGT_WANNetConfigInfo"]["CellId"]["_value"]=tr069["CellId"] ;
    tr069_json["InternetGatewayDevice"]["WANDevice"]["1"]["WANEthernetInterfaceConfig"]["Stats"]["BytesSent"]["_value"]=tr069["BytesSent"] ;
    tr069_json["InternetGatewayDevice"]["WANDevice"]["1"]["WANEthernetInterfaceConfig"]["Stats"]["BytesReceived"]["_value"]=tr069["BytesReceived"] ;
    tr069_json["InternetGatewayDevice"]["WANDevice"]["1"]["WANEthernetInterfaceConfig"]["Stats"]["PacketsReceived"]["_value"]=tr069["PacketsReceived"] ;
    tr069_json["InternetGatewayDevice"]["WANDevice"]["1"]["WANEthernetInterfaceConfig"]["Stats"]["PacketsSent"]["_value"]=tr069["PacketsSent"] ;
    tr069_json["InternetGatewayDevice"]["DeviceInfo"]["UpTime"]["_value"]=tr069["UpTime"] ;
    tr069_json["InternetGatewayDevice"]["DeviceInfo"]["X_TGT_IMSI"]["_value"]=tr069["IMSI"] ;
    tr069_json["InternetGatewayDevice"]["LANDevice"]["1"]["LANEthernetInterfaceConfig"]["1"]["Enable"]["_value"]=tr069["Enable"] ;
    tr069_json["InternetGatewayDevice"]["WEB_GUI"]["Network"]["Network_Mode"]["WANIPAddress"]["_value"]=tr069["WANIPAddress"] ;
    tr069_json["InternetGatewayDevice"]["WEB_GUI"]["Network"]["ScanMode"]["Settings"]["PCILock"]["_value"]=tr069["PCILock"] ;
    tr069_json["InternetGatewayDevice"]["WEB_GUI"]["Overview"]["LTEStatus"]["DnsServer"]["_value"]=tr069["DnsServer"] ;
    tr069_json["InternetGatewayDevice"]["DeviceInfo"]["HardwareVersion"]["_value"]=tr069["HardwareVersion"] ;
    tr069_json["InternetGatewayDevice"]["DeviceInfo"]["Manufacturer"]["_value"]=cwmp__Inform->DeviceId->Manufacturer;
    tr069_json["InternetGatewayDevice"]["DeviceInfo"]["ManufacturerOUI"]["_value"]=cwmp__Inform->DeviceId->OUI;
    tr069_json["InternetGatewayDevice"]["DeviceInfo"]["ModelName"]["_value"]=tr069["ModelName"] ;
    tr069_json["InternetGatewayDevice"]["DeviceInfo"]["ModelNumber"]["_value"]=tr069["ModelNumber"] ;
    tr069_json["InternetGatewayDevice"]["DeviceInfo"]["Description"]["_value"]=tr069["Description"] ;
    tr069_json["InternetGatewayDevice"]["DeviceInfo"]["ProductClass"]["_value"]=cwmp__Inform->DeviceId->ProductClass;
    tr069_json["InternetGatewayDevice"]["DeviceInfo"]["SerialNumber"]["_value"]=cwmp__Inform->DeviceId->SerialNumber;
    tr069_json["InternetGatewayDevice"]["LANDevice"]["1"]["LANEthernetInterfaceConfig"]["1"]["Enable"]["_value"]=tr069["LAN1Enable"] ;
    tr069_json["InternetGatewayDevice"]["LANDevice"]["1"]["LANEthernetInterfaceConfig"]["2"]["Enable"]["_value"]=tr069["LAN2Enable"] ;
    tr069_json["InternetGatewayDevice"]["ManagementServer"]["ConnectionRequestURL"]["_value"]=tr069["ConnectionRequestURL"] ;
    tr069_json["InternetGatewayDevice"]["WANDevice"]["1"]["WANEthernetInterfaceConfig"]["Enable"]["_value"]=tr069["WANEthernetInterfaceConfigEnable"] ;
    tr069_json["InternetGatewayDevice"]["WEB_GUI"]["Overview"]["LTEStatus"]["DL_DataRate_Current"]["_value"]=tr069["DL_DataRate_Current"] ;
    tr069_json["InternetGatewayDevice"]["WEB_GUI"]["Overview"]["LTEStatus"]["UL_DataRate_Current"]["_value"]=tr069["UL_DataRate_Current"] ;
    tr069_json["InternetGatewayDevice"]["WEB_GUI"]["Network"]["LTE_Setting"]["Status"]["PCI"]["_value"]=tr069["PCI"] ;
    tr069_json["InternetGatewayDevice"]["WEB_GUI"]["Overview"]["LANStatus"]["MacAddress"]["_value"]=tr069["MacAddress"] ;
    tr069_json["InternetGatewayDevice"]["WEB_GUI"]["Network"]["LTE_Setting"]["Status"]["DL_Frequency"]["_value"]=tr069["DL_Frequency"] ;
    tr069_json["InternetGatewayDevice"]["WEB_GUI"]["Network"]["LTE_Setting"]["Status"]["UL_Frequency"]["_value"]=tr069["UL_Frequency"] ;
//</editor-fold>
            std::ofstream json_data;
//            time_t second;
    second = time(NULL);
    strstream << second;
    strstream >> _time;
            json_data.open("/var/tmp/json_data/"+url_encode(_id)+"_"+_time, std::ios_base::app);
            json_data <<tr069_json.dump(4);
//
//    for(auto elem : tr069)
//    {
//        std::cerr<<elem.first<<"\t"<<elem.second<<std::endl;
//    }
//    std::cerr<< "Size: "<<tr069.size()<<std::endl;
    return SOAP_OK;
}
