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


const char KK_URI_SYS_PREFIX[] = "/sys/kk/%s/%s/#";
const char KK_URI_SYS_PREFIX_EX[] = "/sys/kk/%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/kk/%s/%s/#";
const char KK_URI_OTA_PROCESS[] = "/ota/device/progress/%s/%s";
const char KK_URI_OTA_INFORM[] = "/ota/device/inform/%s/%s";



int KK_Subdev_Subscribe(const cJSON *root)
{
	int res = 0;		
	cJSON *deviceCode = NULL;
	cJSON *productCode = NULL;
	cJSON *data	= NULL;
	cJSON *cmd = NULL;	
    int url_len = 0;	
	
	data = cJSON_GetObjectItem(root, "data");
	if(data == NULL){
		return -1;
	}
	deviceCode = cJSON_GetObjectItem(data,MSG_DEVICE_CODE_STR);
	if(deviceCode == NULL){
		return -1;
	}
	productCode = cJSON_GetObjectItem(data,MSG_PRODUCT_CODE_STR);
	if(productCode == NULL){
		return -1;
	}	
    url_len = strlen(KK_URI_OTA_PREFIX) + strlen(productCode->valuestring) + strlen(deviceCode->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, productCode->valuestring, deviceCode->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, productCode->valuestring, deviceCode->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 productCode[PRODUCT_CODE_LEN],char deviceCode[DEVICE_CODE_LEN])
{
    int res = 0, index = 0, fail_count = 0;

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

    memset(url, 0, url_len);
    snprintf(url, url_len, KK_URI_OTA_PREFIX, productCode,deviceCode);
    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, productCode,deviceCode);
    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 productCode[PRODUCT_CODE_LEN] = {0};
	char deviceCode[MAC_ADDR_LEN] = {0};

	HAL_GetProduct_Code(productCode);
	HAL_Get_mac(deviceCode);
	return _kk_client_subscribe(productCode,"CCU_66666");
}

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

    service_name_len = strlen(KK_URI_SYS_PREFIX_EX) + strlen(product_code) + strlen(device_code)
    		+ 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_code, device_code);
    
    if (name != NULL) {
        memcpy(*topic + strlen(*topic), name, strlen(name));
    }

    return 0;
}
 static int _kk_utils_topic_ota(_IN_ char* str, _OU_ char **topic)
{
    int service_name_len = 0;
	int *pstr_uri = NULL;
    if (str == NULL ||topic == NULL || *topic != NULL) {
        return -1;
    }

    service_name_len = strlen(str)+1;
    *topic = malloc(service_name_len);
    if (*topic == NULL) {
        return -1;
    }
    memset(*topic, 0, service_name_len);
    memcpy(*topic,str,service_name_len);

    return 0;
}

char* KK_Make_Topic(cJSON *info)
{
	cJSON *type,*product_code,*device_code;
	char *topic = NULL;
	//root=cJSON_Parse((char*)info->valuestring);

	type = cJSON_GetObjectItem(info, MSG_TYPE_STR);
	if(type == NULL){
		goto errorreturn;
	}
	#if 0 //just for test
	if(strstr(type->valuestring,"/thing/topo/add") != NULL){
		 KK_MQTT_SubTopic("/sys/kk/2/1122334455667788/#");
	}
	#endif
	product_code = cJSON_GetObjectItem(info, MSG_PRODUCT_CODE_STR);
	if(product_code == NULL){
		goto errorreturn;
	}	
	device_code = cJSON_GetObjectItem(info, MSG_DEVICE_CODE_STR);
	if(device_code == NULL){
		goto errorreturn;
	}	
	if(strstr(type->valuestring,"/ota/device/inform") ||strstr(type->valuestring,"/ota/device/progress")){
		_kk_utils_topic_ota(type->valuestring,&topic);
	}
	else{
		_kk_utils_topic(type->valuestring,product_code->valuestring,device_code->valuestring,&topic);
	}
	
#if 0
	switch(msgtype)
	{
		case MSG_REGISTER:
			_kk_utils_topic(DM_URI_THING_SUB_REGISTER,product_code->valuestring,device_code->valuestring,&topic);
			break;
		case MSG_UNREGISTER:
			_kk_utils_topic(DM_URI_THING_SUB_UNREGISTER,product_code->valuestring,device_code->valuestring,&topic);
			break;	
		case MSG_TOPOADD:
			_kk_utils_topic(DM_URI_THING_TOPO_ADD,product_code->valuestring,device_code->valuestring,&topic);
			break;
		case MSG_TOPODELETE:
			_kk_utils_topic(DM_URI_THING_TOPO_DELETE,product_code->valuestring,device_code->valuestring,&topic);
			break;		
		case MSG_TOPOGET:
			_kk_utils_topic(DM_URI_THING_TOPO_GET,product_code->valuestring,device_code->valuestring,&topic);
			break;	
		case MSG_LISTFOUND:
			_kk_utils_topic(DM_URI_THING_LIST_FOUND,product_code->valuestring,device_code->valuestring,&topic);
			break;
		case MSG_LOGIN:
			_kk_utils_topic(DM_URI_COMBINE_LOGIN,product_code->valuestring,device_code->valuestring,&topic);
			break;
		case MSG_LOGOUT:
			_kk_utils_topic(DM_URI_COMBINE_LOGOUT,product_code->valuestring,device_code->valuestring,&topic);
			break;	
		case MSG_PROPERTYPOST:
			_kk_utils_topic(DM_URI_THING_EVENT_PROPERTY_POST,product_code->valuestring,device_code->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_code->valuestring,device_code->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_code->valuestring,device_code->valuestring,&topic);
				free(service_name);
			}
			break;
		case MSG_SETREPLY:
			_kk_utils_topic(DM_URI_THING_SERVICE_PROPERTY_SET_REPLY,product_code->valuestring,device_code->valuestring,&topic);
			break;
		case MSG_OTA_PROCESS:
			_kk_utils_topic_ota(0,product_code->valuestring,device_code->valuestring,&topic);
			break;
		case MSG_OTA_INFORM:
			_kk_utils_topic_ota(1,product_code->valuestring,device_code->valuestring,&topic);
			break;

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

}



