
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "kk_product.h"
#include "cJSON.h"
#include "com_api.h"
#include "kcloud_log.h"

const char KK_URI_SYS_PREFIX[] = "/sys/%s/%s/#";
const char KK_URI_SYS_PREFIX_EX[] = "/sys/%s/%s/";
const char DM_URI_THING_SUB_REGISTER[] = "thing/sub/register";
const char DM_URI_THING_SUB_UNREGISTER[] = "thing/sub/unregister";
const char DM_URI_THING_TOPO_ADD[] = "thing/topo/add";
const char DM_URI_THING_TOPO_DELETE[] = "thing/topo/delete";
const char DM_URI_THING_TOPO_GET[] = "thing/topo/get";
const char DM_URI_THING_LIST_FOUND[] = "thing/list/found";
const char DM_URI_COMBINE_LOGIN[] = "combine/login";
const char DM_URI_COMBINE_LOGOUT[] = "combine/logout";
const char DM_URI_THING_EVENT_PROPERTY_POST[] = "thing/event/property/post";
const char DM_URI_THING_EVENT_POST[] = "thing/event/%.*s/post";
const char DM_URI_THING_SERVICE_RESPONSE[] = "thing/service/%.*s_reply";
const char DM_URI_THING_SERVICE_PROPERTY_SET_REPLY[] = "thing/service/property/set_reply";
const char KK_URI_OTA_PREFIX[] = "/ota/device/upgrade/%s/%s/#";
const char KK_URI_OTA_PROCESS[] = "/ota/device/progress/%s/%s";


int KK_Subdev_Subscribe(const cJSON *root)
{
	int res = 0;		
	cJSON *productType = NULL;
	cJSON *productCode = NULL;
	cJSON *data	= NULL;
	cJSON *cmd = NULL;	
    int url_len = 0;	
	
	data = cJSON_GetObjectItem(root, "data");
	if(data == NULL){
		return -1;
	}
	productType = cJSON_GetObjectItem(data,"productType");
	if(productType == NULL){
		return -1;
	}
	productCode = cJSON_GetObjectItem(data,"productCode");
	if(productCode == NULL){
		return -1;
	}	
    url_len = strlen(KK_URI_OTA_PREFIX) + strlen(productType->valuestring) + strlen(productCode->valuestring) + 1;
    char  *url = malloc(url_len);
    if (url == NULL) {
        return -1;
    }

    memset(url, 0, url_len);
    snprintf(url, url_len, KK_URI_OTA_PREFIX, productType->valuestring, productCode->valuestring);
    INFO_PRINT("ota [%s][%d] URL:%s\n",__FUNCTION__,__LINE__,url);
    res = KK_MQTT_SubTopic(url);
    
    memset(url, 0, url_len);
    snprintf(url, url_len, KK_URI_SYS_PREFIX, productType->valuestring, productCode->valuestring);
    INFO_PRINT("sys [%s][%d] URL:%s\n",__FUNCTION__,__LINE__,url);
    res = KK_MQTT_SubTopic(url);
    free(url);
	return res;

}

static int _kk_client_subscribe(char productType[PRODUCT_TYPE_LEN], char productCode[PRODUCT_CODE_LEN])
{
    int res = 0, index = 0, fail_count = 0;

    int url_len = 0;
    url_len = strlen(KK_URI_OTA_PREFIX) + strlen(productType) + strlen(productCode) + 1;
    char  *url = malloc(url_len);
    if (url == NULL) {
        return -1;
    }

    memset(url, 0, url_len);
    snprintf(url, url_len, KK_URI_OTA_PREFIX, productType, productCode);
    INFO_PRINT("ota [%s][%d] URL:%s\n",__FUNCTION__,__LINE__,url);
    res = KK_MQTT_SubTopic(url);
    
    memset(url, 0, url_len);

    snprintf(url, url_len, KK_URI_SYS_PREFIX, productType, productCode);
    INFO_PRINT("sys [%s][%d] URL:%s\n",__FUNCTION__,__LINE__,url);

    res = KK_MQTT_SubTopic(url);

    free(url);
    return res;
}

int KK_Client_Gateway_Subscribe(void)
{
	char prpductType[PRODUCT_TYPE_LEN];
	char prpductCode[PRODUCT_CODE_LEN];

	HAL_GetProduct_Type(prpductType);
	HAL_GetProduct_Code(prpductCode);
	return _kk_client_subscribe(prpductType,prpductCode);
}

static int _kk_utils_topic(_IN_ const char *name, _IN_ char *product_key,
                          _IN_ char *device_name, _OU_ char **topic)
{
    int service_name_len = 0;
    if (name == NULL|| product_key == NULL || device_name == NULL ||
        topic == NULL || *topic != NULL) {
        return -1;
    }

    service_name_len = strlen(KK_URI_SYS_PREFIX_EX) + strlen(product_key) + strlen(device_name)
    		+ strlen(name)+1;
    *topic = malloc(service_name_len);
    if (*topic == NULL) {
        return -1;
    }
    memset(*topic, 0, service_name_len);
    snprintf(*topic, service_name_len, KK_URI_SYS_PREFIX_EX, product_key, device_name);
    
    if (name != NULL) {
        memcpy(*topic + strlen(*topic), name, strlen(name));
    }

    return 0;
}

char* KK_Make_Topic(cJSON *info)
{
	cJSON *type,*product_type,*device_name,*root;
	kk_msg_type_t msgtype;
	char *topic = NULL;
	root=cJSON_Parse((char*)info->valuestring);

	type = cJSON_GetObjectItem(root, MSG_TYPE_STR);
	if(type == NULL){
		goto errorreturn;
	}
	product_type = cJSON_GetObjectItem(root, MSG_PRODUCT_TYPE_STR);
	if(product_type == NULL){
		goto errorreturn;
	}	
	device_name = cJSON_GetObjectItem(root, MSG_DEVICE_NAME_STR);
	if(device_name == NULL){
		goto errorreturn;
	}	
	msgtype = atoi(type->valuestring);
	switch(msgtype)
	{
		case MSG_REGISTER:
			_kk_utils_topic(DM_URI_THING_SUB_REGISTER,product_type->valuestring,device_name->valuestring,&topic);
			break;
		case MSG_UNREGISTER:
			_kk_utils_topic(DM_URI_THING_SUB_UNREGISTER,product_type->valuestring,device_name->valuestring,&topic);
			break;	
		case MSG_TOPOADD:
			_kk_utils_topic(DM_URI_THING_TOPO_ADD,product_type->valuestring,device_name->valuestring,&topic);
			break;
		case MSG_TOPODELETE:
			_kk_utils_topic(DM_URI_THING_TOPO_DELETE,product_type->valuestring,device_name->valuestring,&topic);
			break;		
		case MSG_TOPOGET:
			_kk_utils_topic(DM_URI_THING_TOPO_GET,product_type->valuestring,device_name->valuestring,&topic);
			break;	
		case MSG_LISTFOUND:
			_kk_utils_topic(DM_URI_THING_LIST_FOUND,product_type->valuestring,device_name->valuestring,&topic);
			break;
		case MSG_LOGIN:
			_kk_utils_topic(DM_URI_COMBINE_LOGIN,product_type->valuestring,device_name->valuestring,&topic);
			break;
		case MSG_LOGOUT:
			_kk_utils_topic(DM_URI_COMBINE_LOGOUT,product_type->valuestring,device_name->valuestring,&topic);
			break;	
		case MSG_PROPERTYPOST:
			_kk_utils_topic(DM_URI_THING_EVENT_PROPERTY_POST,product_type->valuestring,device_name->valuestring,&topic);
			break;				
		case MSG_EVENTPOST:
			{
				cJSON *identify;
				char *service_name = NULL;
				int service_name_len = 0;
				identify = cJSON_GetObjectItem(root, MSG_INDENTIFIER_STR);
				if(identify == NULL){
					goto errorreturn;
				}
				service_name_len = strlen(DM_URI_THING_EVENT_POST) + strlen(identify->valuestring) + 1;
				service_name = malloc(service_name_len);
				if (service_name == NULL) {
					goto errorreturn;
				}
				snprintf(service_name,service_name_len,DM_URI_THING_EVENT_POST,identify->valuestring);

				_kk_utils_topic(service_name,product_type->valuestring,device_name->valuestring,&topic);
				free(service_name);
			}
			break;	
		case MSG_SERVICERESPONSE:
			{
				cJSON *identify;
				char *service_name = NULL;
				int service_name_len = 0;
				identify = cJSON_GetObjectItem(root, MSG_INDENTIFIER_STR);
				if(identify == NULL){
					goto errorreturn;
				}
				service_name_len = strlen(DM_URI_THING_SERVICE_RESPONSE) + strlen(identify->valuestring) + 1;
				service_name = malloc(service_name_len);
				if (service_name == NULL) {
					goto errorreturn;
				}
				snprintf(service_name,service_name_len,DM_URI_THING_SERVICE_RESPONSE,identify->valuestring);

				_kk_utils_topic(service_name,product_type->valuestring,device_name->valuestring,&topic);
				free(service_name);
			}
			break;
		case MSG_SETREPLY:
			_kk_utils_topic(DM_URI_THING_SERVICE_PROPERTY_SET_REPLY,product_type->valuestring,device_name->valuestring,&topic);
			break;
		case MSG_OTA_PROCESS:
			_kk_utils_topic(KK_URI_OTA_PROCESS,product_type->valuestring,device_name->valuestring,&topic);
			break;

	}
	INFO_PRINT("[%s][%d] TOPIC:%s\n",__FUNCTION__,__LINE__,topic);
	cJSON_Delete(root);
	return topic;
errorreturn:
	cJSON_Delete(root);
	return NULL;

}



