
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "kk_data_mng.h"
#include "kk_lan_node_db.h"

static kk_map_dev_ctx g_map_dev_mgr = {0};




kk_map_dev_ctx *_kk_map_dev_ctx(void)
{
	return &g_map_dev_mgr;
}

static void _kk_map_dev_mutex_lock(void)
{
	kk_map_dev_ctx *ctx = _kk_map_dev_ctx();
	if (ctx->mutex) {
		kk_MutexLock(ctx->mutex);
	}
}
static void _kk_map_dev_mutex_unlock(void)
{
	kk_map_dev_ctx *ctx = _kk_map_dev_ctx();
	if (ctx->mutex) {
		kk_MutexUnLock(ctx->mutex);
	}
}
int kk_map_dev_init(void)
{
	kk_map_dev_ctx *ctx = _kk_map_dev_ctx();
	memset(ctx, 0, sizeof(kk_map_dev_ctx));
	ctx->mutex = kk_MutexCreate(); 
	if (ctx->mutex == NULL) {
		return -1;
	}
	INIT_LIST_HEAD(&ctx->dev_list);
	return 0;
}


void kk_map_dev_deinit(void)
{
	kk_map_dev_ctx *ctx = _kk_map_dev_ctx();
	kk_map_dev_node_t *node = NULL;
	kk_map_dev_node_t *n = NULL;

	printf("[%s][%d]\n",__FUNCTION__,__LINE__);

	list_for_each_entry_safe(node,n,&ctx->dev_list, linked_list, kk_map_dev_node_t) {
		printf("[remove list] node->linked_list000000000\n");
		if (node != NULL) {
			_kk_map_dev_mutex_lock();

			if(node->json){
				printf("[delete cjson] node->json.\n");
				cJSON_Delete(node->json);
			}
			
			if(node->syn_opcode) {
				printf("[free] node->syn_opcode.\n");
				free(node->syn_opcode);
			}
			printf("[remove list] node->linked_list\n");
			dlist_del(&node->linked_list);
			memset(node,0,sizeof(kk_map_dev_node_t));
			_kk_map_dev_mutex_unlock();
		}
	}
}



static int kk_open_cfg_file(char *deviceCode,kk_map_dev_node_t *node)
{
	char path[128] = {0};
	unsigned int filesize;
	FILE *fp;
	char *buf = NULL;
	cJSON *json = NULL;
	cJSON *optype = NULL;
	cJSON *syn_type = NULL;
	
	sprintf(path,KK_DEVICE_MAP_FILE_PATH,deviceCode);
	printf("kk_open_cfg_file path:%s\n",path);
	if(!(fp =  fopen(path,"r")))
	{
		ERROR_PRINT("can't open the file tslPath:%s\n",path);
		return -1;
	}
	printf("[%s][%d]\n",__FUNCTION__,__LINE__);
	fseek(fp, 0L, SEEK_END);
	filesize = ftell(fp);	
	buf = malloc(filesize+1);
	if(buf == NULL)
	{
		ERROR_PRINT("MALLOC FAIL!!!\n");
		fclose(fp);
		return -1;
	}
	printf("[%s][%d]\n",__FUNCTION__,__LINE__);
	memset(buf,0x0,filesize+1);
	fseek(fp, 0L, SEEK_SET);
	fread(buf, 1, filesize, fp);
	printf("buf:%s\n",buf);
	json = cJSON_Parse(buf);  
	if(json == NULL){
		ERROR_PRINT("cJSON_Parse FAIL!!!\n");
		free(buf);
		fclose(fp);
		return -1;
	}
	node->json = json;
	
	printf("[%s][%d]\n",__FUNCTION__,__LINE__);
	optype = cJSON_GetObjectItem(json, OPEARTETYPE_STRING);
	if(optype != NULL){
		memcpy(node->opearteType,optype->valuestring,strlen(optype->valuestring));
	}
	syn_type = cJSON_GetObjectItem(json, "syn_type");
	if(syn_type){
		cJSON *syn_opcode = cJSON_GetObjectItem(json, "syn_opcode");
		node->syn_type = syn_type->valueint;
		node->syn_opcode= (char *)malloc(strlen(syn_opcode->valuestring)+1);
		memset(node->syn_opcode,0,strlen(node->syn_opcode)+1);
		memcpy(node->syn_opcode,syn_opcode->valuestring,strlen(syn_opcode->valuestring));
	}
	printf("[%s][%d]node->syn_type=%d****************\n",__FUNCTION__,__LINE__,node->syn_type);
	
	printf("[%s][%d]\n",__FUNCTION__,__LINE__);
	node->channelNum = cJSON_GetObjectItem(json, CHANNEL_STRING)->valueint;
	printf("[%s][%d]\n",__FUNCTION__,__LINE__);
	node->newccu = cJSON_GetObjectItem(json, NEWCCU_STRING);
	printf("[%s][%d]\n",__FUNCTION__,__LINE__);
	node->oldccu = cJSON_GetObjectItem(json, OLDCCU_STRING);
	printf("[%s][%d]\n",__FUNCTION__,__LINE__);
	if(node->newccu == NULL || node->oldccu == NULL){
		ERROR_PRINT("cJSON_Parse DATA FAIL!!!\n");
		free(buf);
		fclose(fp);
		return -1;
	}
	printf("[%s][%d]\n",__FUNCTION__,__LINE__);
	free(buf);
	fclose(fp);
	return 0;

}
int kk_creater_nodeid(char *deviceCode,int channel,char *nodeId)
{
	static int next = 1;
	int node=-1;
	
	if(deviceCode == NULL || channel == NULL || nodeId == NULL){
		printf("bbb\n");
		return -1;
	}
	printf("aaa\n");
	printf("channel=%d\n",channel);
	printf("deviceCode=%s\n",deviceCode);
	printf(",,,,\n");
	//INFO_PRINT("-------------->deviceCode=%s,channel=%d\n",deviceCode,channel);
	printf("aaa-1\n");
	
	if(kk_check_lan_node_exist(deviceCode,channel)){
		printf("aaa-2\n");
		printf("[%s][%d]\n",__FUNCTION__,__LINE__);
		node = kk_lan_db_node_get(deviceCode,channel);
	}else{
		printf("aaa-3\n");
		printf("[%s][%d]\n",__FUNCTION__,__LINE__);
		while(kk_check_lan_node(next)){
			++next;
		}
		INFO_PRINT("#################next=%d\n",next);
		if(0==kk_lan_db_node_insert(deviceCode,channel,next)){
			node=next;
		}
	}
	
	printf("[%s][%d]\n",__FUNCTION__,__LINE__);
	printf("aaa-44,node=%d\n",node);

	sprintf(nodeId,"%d",node);
	
	printf("aaa-4\n");
	//INFO_PRINT("[node]deviceCode=%s,channel=%d,node=%d,nodeId=%s\n",deviceCode,channel,node,nodeId);

	return 0;
	
}

/******************************************
*从映射表中获取组件所需的值
*******************************************/
static char* kk_value_int_map_string(char *opcodemap,kk_map_dev_node_t *node,int idx)
{
	if(opcodemap == NULL || node == NULL){
		return -1;
	}
	cJSON * oldccuItem = node->oldccu->child;
	while(oldccuItem != NULL){
		char *opcode = cJSON_GetObjectItem(oldccuItem,OPCODE_STRING)->valuestring;
		char *dataType = cJSON_GetObjectItem(oldccuItem,DATATYPE_STRING)->valuestring;
		if(strcmp(opcode,opcodemap) == 0){
			cJSON *range = cJSON_GetObjectItem(oldccuItem,VALUERANGE_STRING);
			if(range != NULL){
				cJSON * pSub = cJSON_GetArrayItem(range, idx);
				if(pSub != NULL){
					if(strcmp(dataType,"string") == 0){
						return pSub->valuestring;
					}
				}
			}
		}
	}
	return "";
}
int kk_get_int_value_idx(cJSON * range,int val)
{
	int i = 0;
	int  array_size  = cJSON_GetArraySize (range);

	for(i = 0; i < array_size; i++){

		cJSON * pSub = cJSON_GetArrayItem(range, i);

		if(pSub != NULL && (pSub->valueint == val)){
			return i;
		}
	}
	return -1;
}

int mac_switchto_deviceCode(char *mac,char * deviceCode)
{
	char mac_bak[33] = {0};
	int i, j;
	int len =  strlen(mac);
	if(len!=23)
		return -1;
	
	for(i=0; i < len; i++)  /*将串s拷贝至串t*/
		mac_bak[i]=mac[i];
	mac_bak[i]='\0';

	for(i=0,j=0; i < len; i++){
		if((i+1)%3==0&&i!=0){
			continue;
		}
		deviceCode[j++] =mac_bak[i];
	}
	deviceCode[j]='\0';  /*在串s结尾加结束标志*/
	return 0;
}
int _deviceCode_switchto_mac(char * deviceCode,char *mac)
{
	char deviceCode_bak[33] = {0};
	int i, j;
	int len =  strlen(deviceCode);
	for(i=0; i < len; i++)  /*将串s拷贝至串t*/
		deviceCode_bak[i]=deviceCode[i];
	deviceCode_bak[i]='\0';
	for(i=0,j=0; i < len; i++){
		if( i % 2 == 0 && i != 0)
		{
			mac[j++]=':';
			mac[j++]=deviceCode_bak[i];
		}
		else
		{
			mac[j++]=deviceCode_bak[i];
		}
	}
	mac[j]='\0';  /*在串s结尾加结束标志*/
	return 0;
}



int kk_create_devices_to_sdk(cJSON *root)
{
	kk_map_dev_node_t *node = NULL;
	char nodeid[32] = {0};
	char gwmac[32] = {0};
	char submac[32] = {0};
	char channel[4];
	int idx = 1;

	kk_map_dev_ctx *ctx = _kk_map_dev_ctx();
	cJSON *devices = cJSON_CreateArray();
	list_for_each_entry(node, &ctx->dev_list, linked_list, kk_map_dev_node_t) {
		if (node != NULL) {

			
			
			for(idx = 1; idx <= node->channelNum; idx++){
				printf("[%s][%d]\n",__FUNCTION__,__LINE__);
				cJSON *subdevicesItem = cJSON_CreateObject();
				sprintf(channel,"%d",idx);
				cJSON_AddStringToObject(subdevicesItem, CHANNEL_STRING, channel);
				cJSON_AddStringToObject(subdevicesItem, DEVICE_FIELD_STRING, "");
				cJSON_AddStringToObject(subdevicesItem, DEVICE_FIELD_IDNDEX_STRING, "1");
				cJSON_AddStringToObject(subdevicesItem, DEVICE_ICON_STRING, "");
				cJSON_AddStringToObject(subdevicesItem, DEVICE_POS_STRING, "1");
				_deviceCode_switchto_mac(node->gwDeviceCode,gwmac);
				printf("gwmac:%s\n",gwmac);
				cJSON_AddStringToObject(subdevicesItem, GW_MAC_STRING, gwmac);
				_deviceCode_switchto_mac(node->deviceCode,submac);
				cJSON_AddStringToObject(subdevicesItem, MAC_STRING, submac);
				//todo name字段
				cJSON_AddStringToObject(subdevicesItem, NAME_STRING, "默认灯");
				memset(nodeid,0x0,sizeof(nodeid));
				kk_creater_nodeid(node->deviceCode,idx,nodeid);
				cJSON_AddStringToObject(subdevicesItem, NODEID_STRING, nodeid);
				cJSON_AddStringToObject(subdevicesItem, OPERATE_TYPE_STRING, node->opearteType);
				cJSON_AddStringToObject(subdevicesItem, ROOM_ID_STRING, "1");
				cJSON_AddItemToArray(devices, subdevicesItem);
			}
			
			

		}
	}
	cJSON_AddItemToObject(root, DEVICES_STRING, devices);
	return 0;
}


char *double_value_string(double val)
{
	char *value = (char *)malloc(33);
	memset(value,0,33);
	
	snprintf(value,32,"%6f",val);
	return value;
}




int kk_create_devicestatus_to_sdk(cJSON *root)
{
	
	kk_map_dev_node_t *node = NULL;
	char nodeid[32] = {0};
	char indxId[4] = {0};
	int idx = 1;
	int syn_type = 0;
	
	kk_map_dev_ctx *ctx = _kk_map_dev_ctx();
	cJSON *device_status = cJSON_CreateArray();
	cJSON *args;
	cJSON *sub_device;
	list_for_each_entry(node, &ctx->dev_list, linked_list, kk_map_dev_node_t){

		if(node->syn_type==1){
			kk_creater_nodeid(node->deviceCode,1,nodeid);
			
			if((args = kk_devicestatus_build(node))!=NULL){
				sub_device=old_ccu_msg_build_json_node_int(atoi(nodeid),node->syn_opcode,NULL,args);
				if(sub_device){
					cJSON_AddItemToArray(device_status,sub_device);
				}
			}
		}else{
			kk_devicestatus_build_aaa(device_status,node);
		}
	}
	
	cJSON_AddItemToObject(root, DEVICE_STATUS_STRING, device_status);
	
	return 0;
}






int kk_map_dev_update_int_value(kk_map_dev_node_t *node,char *identifier,int val)
{
	int ret = 0;

	if(node != NULL && node->newccu != NULL){
		cJSON * newccuItem = node->newccu->child;
		while(newccuItem != NULL){
			char *identifier_tmp = cJSON_GetObjectItem(newccuItem,MSG_INDENTIFIER_STR)->valuestring;
			if(strcmp(identifier_tmp,identifier) == 0){
				cJSON_ReplaceItemInObject(newccuItem, "value", cJSON_CreateNumber(val));
				break;
			}
			newccuItem = newccuItem->next;
		}
	}
	return 0;
}
int kk_map_dev_update_int_value_by_devicecode(char *deviceCode,char *identifier,int val)
{
    int ret = 0;
    kk_map_dev_node_t *node = NULL;
    ret = kk_map_dev_search_by_deviceCode(deviceCode,&node);
    if(ret != 0){
        ERROR_PRINT("kk_map_dev_update_int_value, err: %s", deviceCode);
        return ret;
    }
    if(node != NULL && node->newccu != NULL){
        cJSON * newccuItem = node->newccu->child;
        while(newccuItem != NULL){
            char *identifier_tmp = cJSON_GetObjectItem(newccuItem,MSG_INDENTIFIER_STR)->valuestring;
            if(strcmp(identifier_tmp,identifier) == 0){
                cJSON_ReplaceItemInObject(newccuItem, "value", cJSON_CreateNumber(val));
                break;
            }
            newccuItem = newccuItem->next;
        }    
    }    
    return 0;
}


int kk_map_dev_search_by_deviceCode(char *deviceCode, kk_map_dev_node_t **node)
{
    kk_map_dev_ctx *ctx = _kk_map_dev_ctx();
    kk_map_dev_node_t *search_node = NULL;

    list_for_each_entry(search_node, &ctx->dev_list, linked_list, kk_map_dev_node_t) {
        if ( (strlen(search_node->deviceCode) == strlen(deviceCode)) &&
            (memcmp(search_node->deviceCode, deviceCode, strlen(deviceCode)) == 0)) {
            /* dm_log_debug("Device Found, devid: %d", devid); */
            if (node) {
                *node = search_node;
            }
            return 0;
        }
    }

	ERROR_PRINT("Device Not Found, deviceCode: %s\n", deviceCode);
	return -1;
}



kk_map_dev_node_t *kk_map_dev_add(char *deviceCode,char *productCode,char *gwdeviceCode,char *onlineStatus)
{
	#if 1
	kk_map_dev_node_t *node = NULL;
	kk_map_dev_ctx *ctx = _kk_map_dev_ctx();

	node = malloc(sizeof(kk_map_dev_node_t));
	if (node == NULL) {
		return NULL;
	}
	printf("----------------------------------------->%s\n",onlineStatus);
	printf("[%s][%d]\n",__FUNCTION__,__LINE__);
	_kk_map_dev_mutex_lock();
	printf("[%s][%d]%d\n",__FUNCTION__,__LINE__,onlineStatus);
	memset(node,0x0,sizeof(kk_map_dev_node_t));
	printf("[%s][%d]%d\n",__FUNCTION__,__LINE__,onlineStatus);
	memcpy(node->gwDeviceCode,gwdeviceCode,strlen(gwdeviceCode));
	printf("[%s][%d]%d\n",__FUNCTION__,__LINE__,onlineStatus);
	memcpy(node->deviceCode,deviceCode,strlen(deviceCode));
	printf("[%s][%d]%d\n",__FUNCTION__,__LINE__,onlineStatus);
	memcpy(node->productCode,productCode,strlen(productCode));
	printf("[%s][%d]%d\n",__FUNCTION__,__LINE__,onlineStatus);
	if(onlineStatus){
		printf("[%s][%d]\n",__FUNCTION__,__LINE__);
		printf("[%s][%d]%d\n",__FUNCTION__,__LINE__,onlineStatus);
	}else{
		printf("[%s][%d]\n",__FUNCTION__,__LINE__);
	}
	printf("[%s][%d]\n",__FUNCTION__,__LINE__);
	if(strcmp(onlineStatus,"1")==0){
		node->online_status=1;
	}else{
		node->online_status=0;
	}
	printf("[%s][%d]\n",__FUNCTION__,__LINE__);
	kk_open_cfg_file(productCode,node);
	printf("[%s][%d]\n",__FUNCTION__,__LINE__);
	INIT_LIST_HEAD(&node->linked_list);
	printf("[%s][%d]\n",__FUNCTION__,__LINE__);
	printf("#55,%d\n",node);
	list_add_tail(&node->linked_list, &ctx->dev_list);  
	printf("[%s][%d]\n",__FUNCTION__,__LINE__);  
	_kk_map_dev_mutex_unlock();
	printf("[%s][%d]\n",__FUNCTION__,__LINE__);
	return node;
	#endif
}



/*
int get_productCode_by_deviceCode(const char *deviceCode)
{
	kk_map_dev_ctx *ctx = _kk_map_dev_ctx();
	kk_map_dev_node_t *search_node = NULL;

	list_for_each_entry(search_node, &ctx->dev_list, linked_list, kk_map_dev_node_t) {
		if ( (strlen(search_node->deviceCode) == strlen(deviceCode)) &&
			(memcmp(search_node->deviceCode, deviceCode, strlen(deviceCode)) == 0)) {

			item = kk_zb_dev_hw_info_build(search_node->deviceCode,search_node->productCode,search_node->online_status,NULL,NULL);

			return item;
		}
	}
	return NULL;
}
*/
























