
#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/newkk/%s/%s/thing/service/property/set";
const char KK_URI_SYS_PREFIX_SERVICE[] = "biz/newkk/%s/%s/thing/service/+";
const char KK_URI_SYS_PREFIX_TOPO_CHANGE[] = "biz/newkk/%s/%s/thing/topo/change";
const char KK_URI_SYS_PREFIX_EX[] = "biz/newkk/%s/%s";
const char KK_URI_OTA_PREFIX[] = "ota/device/%s/%s/upgrade";
const char KK_URI_OTA_PROCESS[] = "ota/device/%s/%s/progress";
const char KK_URI_OTA_REPLY[] = "ota/device/%s/%s/upgrade_reply";

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) + 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 URL:%s\n",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);

	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;
}
static int s_ccu_topic_sub = 0;
void KK_reset_sub_flag(void) 
{
	if(s_ccu_topic_sub)
		s_ccu_topic_sub = 0;
}
int KK_CCU_TOPIC_Subscribe(void)
{
	char productCode[PRODUCT_CODE_LEN] = {0};
	if(s_ccu_topic_sub == 1){
		INFO_PRINT("[%s][%d] already Subscribe\n",__FUNCTION__,__LINE__);
		//return -1;
	}
	char ccuid[32] = {0};
	KK_Get_ccuid(ccuid);	
	s_ccu_topic_sub = 1;
	HAL_GetProduct_Code(productCode);

	return _kk_ccu_topic_subscribe(productCode,ccuid);
}

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_process(_IN_ char* product_code,_IN_ char* device_code, _OU_ char **topic)
{
	int service_name_len = 0;
	if (product_code == NULL || device_code == NULL ||
		topic == NULL || *topic != NULL) {
		return -1;
	}

	service_name_len = strlen(KK_URI_OTA_PROCESS) + strlen(product_code) + strlen(device_code) +1;
	*topic = malloc(service_name_len);
	if (*topic == NULL) {
		return -1;
	}
	memset(*topic, 0, service_name_len);
	snprintf(*topic, service_name_len, KK_URI_OTA_PROCESS, product_code, device_code);

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

	service_name_len = strlen(KK_URI_OTA_REPLY) + strlen(product_code) + strlen(device_code) +1;
	*topic = malloc(service_name_len);
	if (*topic == NULL) {
		return -1;
	}
	memset(*topic, 0, service_name_len);
	snprintf(*topic, service_name_len, KK_URI_OTA_REPLY, product_code, device_code);
	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 *data)
{
	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,KK_CCU_PRODUCTID)) && \
		(strstr(type->valuestring,"thing/status/online") != NULL)){
		KK_CCU_TOPIC_Subscribe();
	}
	if(!strcmp(product_code->valuestring,KK_GW_PRODUCTID)){
		//printf("[%s][%d]:%s\n",__FUNCTION__,__LINE__,type->valuestring);
		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,"/thing/event/otaProgress/post")){
		_kk_utils_topic_ota_process(product_code->valuestring,device_code->valuestring,&topic);
	}
	else if(strstr(type->valuestring,"/ota/device/upgrade_reply") != NULL){
		_kk_utils_topic_upgrade_reply(product_code->valuestring,device_code->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;

}



