#include <stdio.h>
#include <pthread.h>
#include "kk_group_db.h"
#include "kk_group_handle.h"
#include "kk_sub_db.h"
#include "kk_tsl_load.h"
#include "kk_tsl_parse.h"
#include "kk_dm_api.h"
#include "kk_dm_msg.h"
#include "kk_property_db.h"
#include "kk_hal.h"
#include "kk_log.h"
#include "kk_linkkit.h"
#include <time.h>

extern void kk_sendData2gw(void* data, int len, char* chalMark);

/************************************************************
*功能描述：向网关发送群组相关的消息
*************************************************************/
static int kk_service_group_msg_send_to_gw(const char *type,cJSON *params,const char *productCode,const char *deviceCode,char *fatherDeviceCode)
{
	char buff[128];
	cJSON *root = cJSON_CreateObject();
	cJSON *info = cJSON_CreateObject();
	cJSON *payload = cJSON_CreateObject();

	memset(buff,0,sizeof(buff));
	sprintf(buff,"/thing/service/%s",type);
	cJSON_AddStringToObject(info,"msgtype",buff);
	cJSON_AddStringToObject(info,"productCode",productCode);
	cJSON_AddStringToObject(info,"deviceCode",deviceCode);


	char msgId[MSG_MAX_LEN] = {0};
	iotx_report_id(msgId);
	cJSON_AddStringToObject(payload,"msgId",msgId);
	cJSON_AddStringToObject(payload,"version","1.0");
	
	char tm[33] = {0};
	snprintf(tm,sizeof(tm),"%ld",time(NULL));
	cJSON_AddStringToObject(payload,"time",tm);

	memset(buff,0,sizeof(buff));
	sprintf(buff,"thing.service.%s",type);
	cJSON_AddStringToObject(payload,"method",buff);
	cJSON_AddItemToObject(payload,"params",params);

	cJSON_AddItemToObject(root,"info",info);
	cJSON_AddItemToObject(root,"payload",payload);
	
	char *data = cJSON_Print(root);
	kk_sendData2gw(data,strlen(data), fatherDeviceCode);
	cJSON_Delete(root);
	free(data);
	return 0;
}


/************************************************************
*功能描述：向云端发送添加群组REPLY
*************************************************************/
static int kk_service_addGroup_reply(cJSON *root,cJSON *msgId,const char *groupId)
{
	if(root == NULL || msgId == NULL || groupId == NULL){
		return INVALID_PARAMETER;
	}
	cJSON *deviceCode = cJSON_GetObjectItem(root, MSG_DEVICE_CODE_STR);	
	if(deviceCode == NULL){
		return FAIL_RETURN;
	}		
	cJSON *productCode = cJSON_GetObjectItem(root, MSG_PRODUCT_CODE_STR);	
	if(productCode == NULL){
		return FAIL_RETURN;
	}		
	cJSON *info = cJSON_CreateObject();
	cJSON_AddStringToObject(info, MSG_TYPE_STR, KK_THING_SERVICE_ADDGROUP_REPLY);
	cJSON_AddStringToObject(info, MSG_DEVICE_CODE_STR, deviceCode->valuestring);
	cJSON_AddStringToObject(info, MSG_PRODUCT_CODE_STR, productCode->valuestring);
	char *infff=cJSON_Print(info);

	cJSON *payload = cJSON_CreateObject();
	cJSON_AddStringToObject(payload, "desc", "success");
	cJSON_AddStringToObject(payload, "version", "1.0");
	cJSON_AddStringToObject(payload, "code", "0");
	cJSON_AddStringToObject(payload, "msgId", msgId->valuestring);
	cJSON_AddStringToObject(payload, "method", "thing.service.addGroup_reply");
	cJSON *paramInfo = cJSON_CreateObject();
	cJSON_AddStringToObject(paramInfo, "groupId", groupId);
	cJSON_AddItemToObject(payload, "params", paramInfo);
	char *payload11=cJSON_Print(payload);
	kk_sendData2app(infff,payload11,0);
	free(payload11);
	free(infff);
	cJSON_Delete(payload);
	cJSON_Delete(info);	
	return SUCCESS_RETURN;
}


/************************************************************
*功能描述：向网关发送添加群组消息
*************************************************************/
static int kk_service_addGroup_send_to_gw(cJSON *param,const char *groupId)
{
	cJSON *groupName = cJSON_GetObjectItem(param, "groupName");
	cJSON *didList = cJSON_GetObjectItem(param, "didList");
	int didListCnt = cJSON_GetArraySize(didList);
	int i,pFlag=0;
	char parent[64];
	for(i=0;i<didListCnt;i++){
		cJSON *didListItem = cJSON_GetArrayItem(didList,i);
		cJSON *epNum = cJSON_GetObjectItem(didListItem, "epNum");
		cJSON *deviceCode = cJSON_GetObjectItem(didListItem, "deviceCode");

		char *ptr = strrchr(deviceCode->valuestring,'_');
		char *deviceCodeStr;
		if(ptr==NULL){
			deviceCodeStr = deviceCode->valuestring;
		}else{
			deviceCodeStr=ptr+1;
		}

		if(pFlag==0){
			memset(parent,0,sizeof(parent));
			if(kk_subDev_find_fatherDeviceCode(deviceCodeStr,parent)==SUCCESS_RETURN){
				pFlag = 1;
				break;
			}
		}
	}

	
	cJSON *params = cJSON_CreateObject();
	cJSON_AddStringToObject(params,"groupId",groupId);
	cJSON_AddStringToObject(params,"groupName",groupName->valuestring);
	char *didlistStr = cJSON_Print(didList);
	cJSON *didlistAry = cJSON_Parse(didlistStr);
	free(didlistStr);
	cJSON_AddItemToObject(params,"didList",didlistAry);

	dm_mgr_dev_node_t *node = NULL;
	if(strlen(parent)!=0&&dm_mgr_get_device_by_devicecode(parent, &node)==SUCCESS_RETURN){
		return kk_service_group_msg_send_to_gw("addGroup",params,node->productCode,node->deviceCode,parent);
	}
	return -1;
}




/************************************************************
*功能描述：向云端发送更新群组REPLY
*************************************************************/
static int kk_service_updateGroup_reply(cJSON *root,cJSON *msgId)
{
	if(root == NULL || msgId == NULL){
		return INVALID_PARAMETER;
	}
	cJSON *deviceCode = cJSON_GetObjectItem(root, MSG_DEVICE_CODE_STR);	
	if(deviceCode == NULL){
		return FAIL_RETURN;
	}		
	cJSON *productCode = cJSON_GetObjectItem(root, MSG_PRODUCT_CODE_STR);	
	if(productCode == NULL){
		return FAIL_RETURN;
	}		
	cJSON *info = cJSON_CreateObject();
	cJSON_AddStringToObject(info, MSG_TYPE_STR, KK_THING_SERVICE_UPDATEGROUP_REPLY);
	cJSON_AddStringToObject(info, MSG_DEVICE_CODE_STR, deviceCode->valuestring);
	cJSON_AddStringToObject(info, MSG_PRODUCT_CODE_STR, productCode->valuestring);
	char *infff=cJSON_Print(info);

	cJSON *payload = cJSON_CreateObject();
	cJSON_AddStringToObject(payload, "desc", "success");
	cJSON_AddStringToObject(payload, "version", "1.0");
	cJSON_AddStringToObject(payload, "code", "0");
	cJSON_AddStringToObject(payload, "msgId", msgId->valuestring);
	cJSON_AddStringToObject(payload, "method", "thing.service.updateGroup_reply");
	
	char *payload11=cJSON_Print(payload);
	kk_sendData2app(infff,payload11,0);
	free(payload11);
	free(infff);
	cJSON_Delete(payload);
	cJSON_Delete(info);	
	return SUCCESS_RETURN;
}

/************************************************************
*功能描述：向网关发送更新群组消息
*************************************************************/
static int kk_service_updateGroup_send_to_gw(cJSON *param,const char *groupId)
{
	cJSON *groupName = cJSON_GetObjectItem(param, "groupName");
	cJSON *didList = cJSON_GetObjectItem(param, "didList");
	int didListCnt = cJSON_GetArraySize(didList);
	int i,pFlag=0;
	char parent[64];
	for(i=0;i<didListCnt;i++){
		cJSON *didListItem = cJSON_GetArrayItem(didList,i);
		cJSON *epNum = cJSON_GetObjectItem(didListItem, "epNum");
		cJSON *deviceCode = cJSON_GetObjectItem(didListItem, "deviceCode");

		char *ptr = strrchr(deviceCode->valuestring,'_');
		char *deviceCodeStr;
		if(ptr==NULL){
			deviceCodeStr = deviceCode->valuestring;
		}else{
			deviceCodeStr=ptr+1;
		}

		if(pFlag==0){
			memset(parent,0,sizeof(parent));
			if(kk_subDev_find_fatherDeviceCode(deviceCodeStr,parent)==SUCCESS_RETURN){
				pFlag = 1;
				break;
			}
		}
	}

	
	cJSON *params = cJSON_CreateObject();
	cJSON_AddStringToObject(params,"groupId",groupId);
	cJSON_AddStringToObject(params,"groupName",groupName->valuestring);
	char *didlistStr = cJSON_Print(didList);
	cJSON *didlistAry = cJSON_Parse(didlistStr);
	free(didlistStr);
	cJSON_AddItemToObject(params,"didList",didlistAry);

	dm_mgr_dev_node_t *node = NULL;
	if(strlen(parent)!=0&&dm_mgr_get_device_by_devicecode(parent, &node)==SUCCESS_RETURN){
		return kk_service_group_msg_send_to_gw("updateGroup",params,node->productCode,node->deviceCode,parent);
	}
	return -1;
}




/************************************************************
*功能描述：向云端发送删除群组REPLY
*************************************************************/
static int kk_service_deleteGroup_reply(cJSON *root,cJSON *msgId)
{
	if(root == NULL || msgId == NULL){
		return INVALID_PARAMETER;
	}
	cJSON *deviceCode = cJSON_GetObjectItem(root, MSG_DEVICE_CODE_STR);	
	if(deviceCode == NULL){
		return FAIL_RETURN;
	}		
	cJSON *productCode = cJSON_GetObjectItem(root, MSG_PRODUCT_CODE_STR);	
	if(productCode == NULL){
		return FAIL_RETURN;
	}		
	cJSON *info = cJSON_CreateObject();
	cJSON_AddStringToObject(info, MSG_TYPE_STR, KK_THING_SERVICE_DELETEGROUP_REPLY);
	cJSON_AddStringToObject(info, MSG_DEVICE_CODE_STR, deviceCode->valuestring);
	cJSON_AddStringToObject(info, MSG_PRODUCT_CODE_STR, productCode->valuestring);
	char *infff=cJSON_Print(info);

	cJSON *payload = cJSON_CreateObject();
	cJSON_AddStringToObject(payload, "desc", "success");
	cJSON_AddStringToObject(payload, "version", "1.0");
	cJSON_AddStringToObject(payload, "code", "0");
	cJSON_AddStringToObject(payload, "msgId", msgId->valuestring);
	cJSON_AddStringToObject(payload, "method", "thing.service.deleteGroup_reply");
	
	char *payload11=cJSON_Print(payload);
	kk_sendData2app(infff,payload11,0);
	free(payload11);
	free(infff);
	cJSON_Delete(payload);
	cJSON_Delete(info);	
	return SUCCESS_RETURN;
}

/************************************************************
*功能描述：向网关发送删除群组消息
*************************************************************/
static int kk_service_deleteGroup_send_to_gw(cJSON *param,const char *groupId)
{
	char parent[64] ={0};

	kk_group_device_db_find_parent(groupId,parent);

	cJSON *params = cJSON_CreateObject();
	cJSON_AddStringToObject(params,"groupId",groupId);

	
	dm_mgr_dev_node_t *node = NULL;

	if(strlen(parent)!=0&&dm_mgr_get_device_by_devicecode(parent, &node)==SUCCESS_RETURN){
		return kk_service_group_msg_send_to_gw("deleteGroup",params,node->productCode,node->deviceCode,parent);
	}

	return -1;
}



/************************************************************
*功能描述：向云端发送查询群组REPLY
*************************************************************/
static int kk_service_queryGroup_reply(cJSON *info_root,cJSON *msgId)
{
	if(info_root == NULL || msgId == NULL){
		return INVALID_PARAMETER;
	}
	cJSON *deviceCode = cJSON_GetObjectItem(info_root, MSG_DEVICE_CODE_STR);	
	if(deviceCode == NULL){
		return FAIL_RETURN;
	}		
	cJSON *productCode = cJSON_GetObjectItem(info_root, MSG_PRODUCT_CODE_STR);	
	if(productCode == NULL){
		return FAIL_RETURN;
	}		
	cJSON *info = cJSON_CreateObject();
	cJSON_AddStringToObject(info, MSG_TYPE_STR, KK_THING_SERVICE_QUERYGROUP_REPLY);
	cJSON_AddStringToObject(info, MSG_DEVICE_CODE_STR, deviceCode->valuestring);
	cJSON_AddStringToObject(info, MSG_PRODUCT_CODE_STR, productCode->valuestring);
	char *infff=cJSON_Print(info);

	cJSON *payload = cJSON_CreateObject();
	cJSON_AddStringToObject(payload, "desc", "success");
	cJSON_AddStringToObject(payload, "version", "1.0");
	cJSON_AddStringToObject(payload, "code", "0");
	cJSON_AddStringToObject(payload, "msgId", msgId->valuestring);
	cJSON_AddStringToObject(payload, "method", "thing.service.queryGroup_reply");
	cJSON *params = kk_group_db_query(0);
	cJSON_AddItemToObject(payload, "params", params);
	
	char *payload11=cJSON_Print(payload);
	kk_sendData2app(infff,payload11,0);
	free(payload11);
	free(infff);
	cJSON_Delete(payload);
	cJSON_Delete(info);	
	return SUCCESS_RETURN;
}



/************************************************************
*功能描述：向云端发送执行群组REPLY
*************************************************************/
static int kk_service_executeGroup_reply(cJSON *root,cJSON *msgId)
{
	if(root == NULL || msgId == NULL){
		return INVALID_PARAMETER;
	}
	cJSON *deviceCode = cJSON_GetObjectItem(root, MSG_DEVICE_CODE_STR);	
	if(deviceCode == NULL){
		return FAIL_RETURN;
	}		
	cJSON *productCode = cJSON_GetObjectItem(root, MSG_PRODUCT_CODE_STR);	
	if(productCode == NULL){
		return FAIL_RETURN;
	}		
	cJSON *info = cJSON_CreateObject();
	cJSON_AddStringToObject(info, MSG_TYPE_STR, KK_THING_SERVICE_EXCUTEGROUP_REPLY);
	cJSON_AddStringToObject(info, MSG_DEVICE_CODE_STR, deviceCode->valuestring);
	cJSON_AddStringToObject(info, MSG_PRODUCT_CODE_STR, productCode->valuestring);
	char *infff=cJSON_Print(info);

	cJSON *payload = cJSON_CreateObject();
	cJSON_AddStringToObject(payload, "desc", "success");
	cJSON_AddStringToObject(payload, "version", "1.0");
	cJSON_AddStringToObject(payload, "code", "0");
	cJSON_AddStringToObject(payload, "msgId", msgId->valuestring);
	cJSON_AddStringToObject(payload, "method", "thing.service.excuteGroup_reply");
	
	char *payload11=cJSON_Print(payload);
	kk_sendData2app(infff,payload11,0);
	free(payload11);
	free(infff);
	cJSON_Delete(payload);
	cJSON_Delete(info);	
	return SUCCESS_RETURN;
}





/******************************************************************************/
/* 函 数 名:  kk_service_addGroup_handle										  */
/* 描    述: 添加group处理      */
/* 返 回 值:  返回'0'表示成功，其它返回值表示出错号							*/
/******************************************************************************/
int kk_service_addGroup_handle(cJSON *root,cJSON *param,cJSON *msgId)
{
	cJSON *groupName = NULL;
	cJSON *ccuRoomId = NULL;
	cJSON *didList = NULL;
	cJSON *didListItem = NULL,*epNum = NULL,*deviceCode = NULL;
	int i,didListCnt = 0;
	char groupId[64] = {0};
	HAL_GetTime_s(groupId);
	groupName = cJSON_GetObjectItem(param, "groupName");
	ccuRoomId = cJSON_GetObjectItem(param, "ccuRoomId");
	didList = cJSON_GetObjectItem(param, "didList");
	didListCnt = cJSON_GetArraySize(didList);
	for(i=0;i<didListCnt;i++){
		didListItem = cJSON_GetArrayItem(didList,i);
		epNum = cJSON_GetObjectItem(didListItem, "epNum");
		deviceCode = cJSON_GetObjectItem(didListItem, "deviceCode");

		char *ptr = strrchr(deviceCode->valuestring,'_');
		char *deviceCodeStr;
		if(ptr==NULL){
			deviceCodeStr = deviceCode->valuestring;
		}else{
			deviceCodeStr=ptr+1;
		}
		
		INFO_PRINT("epNum = %s,deviceCode = %s\n",epNum->valuestring,deviceCodeStr);
		char parent[64];
		memset(parent,0,sizeof(parent));
		if(kk_subDev_find_fatherDeviceCode(deviceCodeStr,parent)==SUCCESS_RETURN){
			INFO_PRINT("parent1 = %s\n",parent);
			kk_group_db_insert(groupId,groupName->valuestring,ccuRoomId->valuestring,epNum->valuestring,deviceCodeStr,parent);
		}else{
			INFO_PRINT("not find parent.\n");
		}
	}
	kk_service_addGroup_send_to_gw(param,groupId);
	return kk_service_addGroup_reply(root,msgId,groupId);
}


/******************************************************************************/
/* 函 数 名:  kk_service_updateGroup_handle										  */
/* 描    述: 更新group处理      */
/* 返 回 值:  返回'0'表示成功，其它返回值表示出错号							*/
/******************************************************************************/
int kk_service_updateGroup_handle(cJSON *root,cJSON *param,cJSON *msgId)
{
	cJSON *groupName = NULL;
	cJSON *ccuRoomId = NULL;
	cJSON *didList = NULL;
	cJSON *didListItem = NULL,*epNum = NULL,*deviceCode = NULL;
	int i,didListCnt = 0;
	cJSON *groupId = NULL;

	groupId = cJSON_GetObjectItem(param, "groupId");
	groupName = cJSON_GetObjectItem(param, "groupName");
	ccuRoomId = cJSON_GetObjectItem(param, "ccuRoomId");
	didList = cJSON_GetObjectItem(param, "didList");
	didListCnt = cJSON_GetArraySize(didList);

	kk_group_db_delete(groupId->valuestring);
	for(i=0;i<didListCnt;i++){
		didListItem = cJSON_GetArrayItem(didList,i);
		epNum = cJSON_GetObjectItem(didListItem, "epNum");
		deviceCode = cJSON_GetObjectItem(didListItem, "deviceCode");
		char *ptr = strrchr(deviceCode->valuestring,'_');
		char *deviceCodeStr;
		if(ptr==NULL){
			deviceCodeStr = deviceCode->valuestring;
		}else{
			deviceCodeStr=ptr+1;
		}

		char parent[64];
		memset(parent,0,sizeof(parent));
		if(kk_subDev_find_fatherDeviceCode(deviceCodeStr,parent)==SUCCESS_RETURN){
			INFO_PRINT("parent = %s\n",parent);
			kk_group_db_insert(groupId->valuestring,groupName->valuestring,ccuRoomId->valuestring,epNum->valuestring,deviceCodeStr,parent);
		}else{
			INFO_PRINT("not find parent.\n");
		}
	}
	kk_service_updateGroup_send_to_gw(param,groupId->valuestring);
	return kk_service_updateGroup_reply(root,msgId);
}


/******************************************************************************/
/* 函 数 名:  kk_service_deleteGroup_handle										  */
/* 描    述: 删除group处理      */
/* 返 回 值:  返回'0'表示成功，其它返回值表示出错号							*/
/******************************************************************************/
int kk_service_deleteGroup_handle(cJSON *root,cJSON *param,cJSON *msgId)
{
	cJSON *groupId = NULL;
	groupId = cJSON_GetObjectItem(param, "groupId");

	kk_service_deleteGroup_send_to_gw(param,groupId->valuestring);

	
	kk_group_db_delete(groupId->valuestring);
	
	return kk_service_deleteGroup_reply(root,msgId);
}

/******************************************************************************/
/* 函 数 名:  kk_service_queryGroup_handle										  */
/* 描    述: 查询group处理      */
/* 返 回 值:  返回'0'表示成功，其它返回值表示出错号							*/
/******************************************************************************/
int kk_service_queryGroup_handle(cJSON *root,cJSON *msgId)
{
	return kk_service_queryGroup_reply(root,msgId);
}


/******************************************************************************/
/* 函 数 名:  kk_service_executeGroup_handle										  */
/* 描    述: 执行group处理      */
/* 返 回 值:  返回'0'表示成功，其它返回值表示出错号							*/
/******************************************************************************/
int kk_service_executeGroup_handle(cJSON *info_root,cJSON *param,cJSON *msgId)
{
	cJSON *groupId = NULL;
	cJSON *controlType = NULL;
	cJSON *propertyValue = NULL;
	INFO_PRINT("kk_service_executeGroup_handle \n");

	groupId = cJSON_GetObjectItem(param, "groupId");
	controlType = cJSON_GetObjectItem(param, "controlType");
	propertyValue = cJSON_GetObjectItem(param, "propertyValue");

	int type;
	if(controlType->type==cJSON_String){
		type = atoi(controlType->valuestring);
	}else{
		type = controlType->valueint;
	}

	char parent[64];
	memset(parent,0,sizeof(parent));
	cJSON *actions = kk_group_device_db_exe_act(groupId->valuestring,type,propertyValue->valueint,parent);

	cJSON *params = cJSON_CreateObject();
	cJSON_AddStringToObject(params,"groupId",groupId->valuestring);
	cJSON_AddItemToObject(params,"actions",actions);

	dm_mgr_dev_node_t *node = NULL;
	if(strlen(parent)!=0&&dm_mgr_get_device_by_devicecode(parent, &node)==SUCCESS_RETURN){
		return kk_service_group_msg_send_to_gw("excuteGroup",params,node->productCode,node->deviceCode,parent);
	}

	return kk_service_executeGroup_reply(info_root,msgId);
}




















