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

const char KK_URI_SYS_PREFIX[] = "biz/kk/%s/%s/thing/service/property/set";
const char KK_URI_SYS_PREFIX_SERVICE[] = "biz/kk/%s/%s/thing/service/+";
const char KK_URI_SYS_PREFIX_TOPO_CHANGE[] = "biz/kk/%s/%s/thing/topo/change";
const char KK_URI_SYS_PREFIX_EX[] = "biz/kk/%s/%s";
const char KK_URI_OTA_PREFIX[] = "ota/device/%s/%s/upgrade";
const char KK_URI_OTA_PROCESS[] = "/ota/device/progress/%s/%s";
const char KK_URI_OTA_INFORM[] = "/ota/device/inform/%s/%s";

static int s_gw_status = DEVICE_OFFLINE;
int kk_set_gw_status(int status)
{
	s_gw_status = status;
	return 0;
}
int kk_get_gw_status(void)
{
	return s_gw_status;
}
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_SYS_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);
    memset(url, 0, url_len);
    snprintf(url, url_len, KK_URI_SYS_PREFIX_SERVICE, productCode->valuestring, deviceCode->valuestring);
    INFO_PRINT("sys [%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_TOPO_CHANGE, 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_ccu_topic_subscribe(char productCode[PRODUCT_CODE_LEN],char deviceCode[DEVICE_CODE_LEN])
{
    int res = 0;

    int url_len = 0;
    url_len = strlen(KK_URI_SYS_PREFIX_SERVICE) + 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_SERVICE, productCode,deviceCode);
    INFO_PRINT("sys [%s][%d] URL:%s\n",__FUNCTION__,__LINE__,url);

    res = KK_MQTT_SubTopic(url);

    free(url);
    return res;
}
static int s_ccu_topic_sub = 0;
int KK_CCU_TOPIC_Subscribe(void)
{
	char productCode[PRODUCT_CODE_LEN] = {0};
	char deviceCode[MAC_ADDR_LEN] = {0};
	if(s_ccu_topic_sub == 1){
		INFO_PRINT("[%s][%d] already Subscribe\n",__FUNCTION__,__LINE__);
		return -1;
	}
	s_ccu_topic_sub = 1;
	HAL_GetProduct_Code(productCode);
	HAL_Get_mac(deviceCode);
	return _kk_ccu_topic_subscribe(productCode,KK_CCU_ID);
}

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;
    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;
}

int KK_Subdev_UnSubscribe_By_DeviceCode(const char *deviceCode,const char *productCode )
{
	 char *topic = NULL;
	 int topic_len = 0;

	 topic_len = strlen(KK_URI_SYS_PREFIX) + strlen(productCode)+strlen(deviceCode) + 1;
	 topic = malloc(topic_len);
	 if (topic == NULL) {
		 return -1;
	 }
	 memset(topic,0,topic_len);
	 snprintf(topic, topic_len, KK_URI_SYS_PREFIX, productCode,deviceCode);
	 INFO_PRINT("[%s][%d] TOPIC:%s\n",__FUNCTION__,__LINE__,topic);
	 KK_MQTT_UnsubTopic(topic);
	 memset(topic,0,topic_len);
	 snprintf(topic, topic_len, KK_URI_SYS_PREFIX_SERVICE, productCode,deviceCode);
	 INFO_PRINT("[%s][%d] TOPIC:%s\n",__FUNCTION__,__LINE__,topic);
	 KK_MQTT_UnsubTopic(topic);	 
	 snprintf(topic, topic_len, KK_URI_SYS_PREFIX_TOPO_CHANGE, productCode,deviceCode);
	 INFO_PRINT("[%s][%d] TOPIC:%s\n",__FUNCTION__,__LINE__,topic);
	 KK_MQTT_UnsubTopic(topic);	 	 
	 free(topic);
	 return 0;

}
int KK_Subdev_UnSubscribe(cJSON *payload)
{
	cJSON *params,*productCode,*deviceCode;

	if(payload == NULL){
		goto errorreturn;
	}
	params = cJSON_GetObjectItem(payload, MSG_PARAMS_STR);
	if(params == NULL){
		goto errorreturn;
	}		
	productCode = cJSON_GetObjectItem(params, MSG_PRODUCT_CODE_STR);
	if(productCode == NULL){
		goto errorreturn;
	}	
	deviceCode = cJSON_GetObjectItem(params, MSG_DEVICE_CODE_STR);
	if(deviceCode == NULL){
		goto errorreturn;
	}	
	KK_Subdev_UnSubscribe_By_DeviceCode(deviceCode->valuestring,productCode->valuestring);

	return 0;
errorreturn:
	return -1;

}
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;
	}

	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((!strcmp(product_code->valuestring,"15") || !strcmp(product_code->valuestring,"ccu_n12")) && \
		(strstr(type->valuestring,"thing/status/online") != NULL)){
		KK_CCU_TOPIC_Subscribe();
	}
	if(!strcmp(product_code->valuestring,KK_GW_PRODUCTID)){
		if(strstr(type->valuestring,"/thing/status/offline") != NULL){
			kk_set_gw_status(DEVICE_OFFLINE);
		}else if(strstr(type->valuestring,"/thing/status/online") != NULL){
			kk_set_gw_status(DEVICE_ONLINE);
		}
	}	
	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);
	}
			
	INFO_PRINT("[%s][%d] TOPIC:%s\n",__FUNCTION__,__LINE__,topic);
	return topic;
errorreturn:
	return NULL;

}



