/*#include <comdef.h>*/
#include "target.h"
#include "x509v3.h"

#include "tl_softsim_logic.h"
#include "tl_utils.h"
#include "tl_json.h"
#include "tl_fs.h"
#include "tl_errno.h"
#include "tl_heap.h"
#include "tl_log.h"

#define mk_json_parse_usim_line(_name)                        \
    cJSON *_json_##_name= cJSON_GetObjectItem(root, #_name);  \
    if(!_json_##_name) {                                      \
        SOFTSIM_LOGD("no %s!", #_name);                       \
        strcpy((char*)usim->_name, "");                       \
    } else {                                                  \
        /*SOFTSIM_LOGD(#_name" type is %d", _json_##_name->type);  */  \
        /*SOFTSIM_LOGD(#_name" is %s", _json_##_name->valuestring);*/  \
        strcpy((char*)usim->_name, (const char*)_json_##_name->valuestring); \
    }

#define mk_json_parse_plmn_line(_name)                        \
    cJSON *_json_##_name= cJSON_GetObjectItem(root, #_name);  \
    if(!_json_##_name) {                                      \
        SOFTSIM_LOGD("no %s!", #_name);                       \
        usim->_name = NULL;                                   \
    }else{                                                         \
        int asz_##_name = cJSON_GetArraySize(_json_##_name);       \
        /*SOFTSIM_LOGD(#_name" array size is %d",asz_##_name);*/   \
        int i_##_name = 0;                                         \
        cJSON *item_##_name;                                       \
        uint32_t _pos_##_name = 0;                                 \
        if(asz_##_name > 0) {                                      \
            for(i_##_name =0; i_##_name< asz_##_name; i_##_name++) {     \
                /*SOFTSIM_LOGD(#_name" +++++++ %d ++++++",i_##_name);  */\
                item_##_name = cJSON_GetArrayItem(_json_##_name, i_##_name);    \
                _pos_##_name += strlen(item_##_name->valuestring);                   \
                _pos_##_name += 1;                                                   \
            }                                                                        \
            usim->_name = tl_malloc(_pos_##_name);                                   \
            _pos_##_name = 0;                                                   \
            for(i_##_name =0; i_##_name< asz_##_name; i_##_name++) {            \
                item_##_name = cJSON_GetArrayItem(_json_##_name, i_##_name);    \
                /*SOFTSIM_LOGD(#_name" item type is %d",item_##_name->type);*/  \
                /*SOFTSIM_LOGD(#_name" item value is %s",item_##_name->valuestring);*/\
                strcpy((char*)usim->_name + _pos_##_name, item_##_name->valuestring); \
                _pos_##_name += strlen(item_##_name->valuestring);                    \
                strcpy((char*)usim->_name + _pos_##_name, ",");                       \
                _pos_##_name += 1;                                                    \
            }                                                                         \
            usim->_name[_pos_##_name - 1] = 0;        \
        }else {                                       \
            usim->_name = NULL;                       \
            SOFTSIM_LOGD(#_name" is NULL");           \
        }                                             \
    }

const char *json_str = "{ \"imsi\":\"147746112644399\",\"ki\": \"C441AC38DB1045A24712AF4EC06B921A\",\"opc\":  \"34b1f39d9a5ef0314d59e23518017b63\",\"apn\":\"yo\",\"spn\":\"Delcom\",\"simType\":\"smsaddr4\",\"iccid\": \"89852031400000003700\",\"fplmn\":[],\"plmn\":[\"460-00\"],  \"msisdn\":\"85255697360\"}";

int tl_json_parse_usim(const char * json_str, uint32_t size, usim_info_t *usim){
    int rc = 0;

    SOFTSIM_LOGD("file: %s, func: %s", __FILE_NAME__, __func__);
    /*SOFTSIM_LOGD("json_str: %s", json_str);*/
    /*dump_strings("json_str", json_str);*/
    cJSON *root;
    root = cJSON_Parse(json_str);
    if (root == NULL) {
        SOFTSIM_LOGD("fail to parse json string");
        return -1;
    }

    mk_json_parse_usim_line(imsi);
    mk_json_parse_usim_line(ki);
    mk_json_parse_usim_line(opc);
    mk_json_parse_usim_line(apn);
    mk_json_parse_usim_line(spn);
    mk_json_parse_usim_line(simType);
    mk_json_parse_usim_line(iccid);
    mk_json_parse_usim_line(msisdn);
    mk_json_parse_plmn_line(fplmn);
    mk_json_parse_plmn_line(plmn);

    if (root)
        cJSON_Delete(root);

    return rc;
}

static char *tl_strdup(const char *src){
    char *dest = NULL;

    dest = tl_malloc(strlen(src));
    if(NULL == dest){
        return NULL;
    }

    strcpy(dest, src);

    return dest;
}


int tl_json_parse_imsi_string(const char * json_str, char **imsi){
    int rc = 0;

    SOFTSIM_LOGD("file: %s, func: %s", __FILE_NAME__, __func__);
    /*SOFTSIM_LOGD("json_str: %s", json_str);*/

    dump_strings("json_str", json_str);
    cJSON *root;
    root = cJSON_Parse(json_str);

    cJSON *_json_imsi= cJSON_GetObjectItem(root, "imsi");
    if(!_json_imsi) {
        SOFTSIM_LOGD("no  imsi ! ");
        return -1;
    }
    SOFTSIM_LOGD("imsi type is %d", _json_imsi->type);
    SOFTSIM_LOGD("imsi is %s", _json_imsi->valuestring);

    *imsi = tl_strdup(_json_imsi->valuestring);
    if(*imsi == NULL){
        SOFTSIM_LOGD("strdup json imsi string error");
        rc = -2;
    }

    if (root){
        cJSON_Delete(root);
    }

    return rc;
}

int tl_json_build_free_buffer(char **buffer){
    SOFTSIM_LOGD("file: %s, func: %s", __FILE_NAME__, __func__);

    tl_free(*buffer);

    return 0;
}

int tl_json_build_apn_info(
        uint32_t slot,
        char *imsi,
        char *apn,
        char *plmn,
        char **output ){

    SOFTSIM_LOGD("file: %s, func: %s", __FILE_NAME__, __func__);

    cJSON *root = cJSON_CreateObject();
    cJSON_AddNumberToObject(root, "slot", slot);
    cJSON_AddStringToObject(root, "imsi", imsi);
    cJSON_AddStringToObject(root, "apn", apn);
    cJSON_AddStringToObject(root, "plmn", plmn);

    *output= cJSON_Print(root);

    SOFTSIM_LOGD("json output: %s", *output);

    if(NULL != root){
        cJSON_DeleteItemFromObject(root, "slot");
        cJSON_DeleteItemFromObject(root, "imsi");
        cJSON_DeleteItemFromObject(root, "apn");
        cJSON_DeleteItemFromObject(root, "plmn");

        cJSON_Delete(root);
    }

    return 0;
}
