#include "kk_tsl_property_set.h"
#include "kk_rgb_hsl_convert.h"
#include "kk_tsl_property_get.h"
#include "kk_ncp_msg.h"
#include "kk_color_space.h"
#include "kk_device_table_db.h"
#include "com_api.h"
#include "kk_device_manager.h"
#include "kk_zigbee_api.h"
#include "../device-table/device-table.h"

static uint8_t kk_global_buffer[256];
static uint8_t kk_global_len;


//"identifier":["PowerSwitch_1","PowerSwitch_2","PowerSwitch_3"]



cJSON *kk_tsl_get_property_operation(jrpc_context * ctx, cJSON *params, cJSON *id,cJSON *mac)
{
	kk_device_table_s *dev;
	kk_dev_config_map *ptr;
	kk_dev_config_map *dev_info = NULL;
	kk_dev_config_item *item = NULL;
	EmberEUI64 localEui64;
	char localEui64Str[17];
	cJSON *array;
	cJSON *identifier = NULL;
	int num;

	uint8_t eui64[EUI64_SIZE];
	EmberNodeId nodeId = EMBER_AF_PLUGIN_DEVICE_TABLE_NULL_NODE_ID;
	UTIL_LOG_INFO("\n********************kk tsl get property operation********************\n");

	if(params == NULL){
		set_json_error_type(ctx,JRPC_INVALID_PARAMS,MSG_INVALID_PARAMS);
		goto error_return;
	}

	

	rpc_get_mac(mac->valuestring,eui64);
	emberAfGetEui64(localEui64);
	rpc_eui64ToString(localEui64,localEui64Str);
	if(strcmp(localEui64Str,mac->valuestring)==0){
		printf("&&&&&&&&&&&&&&&& ignore\n");
		goto error_return;
	}
	
	
	nodeId = emberAfDeviceTableGetNodeIdFromEui64(eui64);

	emberAfPrintBigEndianEui64(eui64);
	emberAfAppFlush();
	dev = kk_device_find_by_mac(eui64);
	if(dev == NULL){
		goto error_return;
	}
	dev_info = kk_device_config_find(dev->productCode);
	if(dev_info == NULL){
		goto error_return;
	}

	array = rpc_cJSON_GetObjectItem(params, "identifier");
	if(array == NULL){
		goto error_return;
	}
	num = rpc_cJSON_GetArraySize(array);

	kk_tsl_get_property_s(nodeId);
	
	for(int i=0;i<num;i++){
		
		identifier = rpc_cJSON_GetArrayItem(array,i);

		ptr = dev_info;
		item = &ptr->item;
		while(item!=NULL){
			if(item == NULL) continue;
			if(strcmp(item->identity,identifier->valuestring)==0){
				printf("\n================================\n");
				printf("ep=%d,cluster=0x%04X,attribute=0x%04X\n",item->endpoint,item->cluster,item->attribute);
				printf("\n================================\n");
				kk_tsl_get_pery_add(item->endpoint,item->cluster,item->attribute);
				break;
			}

			item = item->next;
		}
		
	}
	kk_tsl_get_property_e(nodeId);

	return rpc_cJSON_CreateNumber(0);

error_return:
	return rpc_cJSON_CreateNull();
}

cJSON *kk_topo_change_operation(jrpc_context * ctx, cJSON *params, cJSON *id,cJSON *mac)
{
	int res = 0;
    cJSON *changeTypeStr = NULL; 
	uint8_t eui64[EUI64_SIZE];
	uint16_t nodeId = 0;
 
 	UTIL_LOG_INFO("\n********************kk_topo_change_operation********************\n");
 
 	if(params == NULL){
 		set_json_error_type(ctx,JRPC_INVALID_PARAMS,MSG_INVALID_PARAMS);
		goto error_return;
	}else{
		changeTypeStr = rpc_cJSON_GetObjectItem(params, MSG_TOPO_CHANGE_TYPE_STR);
		if(changeTypeStr != NULL && changeTypeStr->valueint == 1){
		    cJSON *deviceArray = rpc_cJSON_GetObjectItem(params, MSG_TOPO_CHANGE_DEVICES_STR);
		    if(deviceArray == NULL){
			   goto error_return;
		    }			
			cJSON * item = deviceArray->child;
			while(item != NULL){
				char *deviceCode = rpc_cJSON_GetObjectItem(item,MSG_DEVICE_CODE_STR)->valuestring;
				rpc_get_mac(deviceCode,eui64);
				nodeId = emberAfDeviceTableGetNodeIdFromEui64(eui64);
				kk_zdo_leave_request(nodeId,true,false);
				item = item->next;
			}

		}
	}
	return rpc_cJSON_CreateNumber(res);
error_return:
	return rpc_cJSON_CreateNull();
}

int kk_tsl_utils_memtok( char *input,  char *delimiter,  int index,  int *offset)
{
    int item_index = 0;
    int count = 0;
	int input_len = 0;


    if (input == NULL || offset == NULL) {
        return -1;
    }
	input_len = strlen(input);
    for (item_index = 0; item_index < input_len; item_index++) {
        if (input[item_index] == delimiter && (item_index + 1) < input_len) {
            count++;
            if (count == index) {
                *offset = item_index;

                return 0;
            }
        }
    }

    return -1;
}

cJSON *kk_tsl_property_operation(jrpc_context * ctx, cJSON *params, cJSON *id,cJSON *mac)
{
	int res = 0;
	EmberStatus status;;
	kk_device_table_s *dev;
	kk_dev_config_map *dev_info = NULL;
	kk_dev_config_item *item = NULL;
	cJSON *propertyItem = NULL;
	cJSON *propertyItem1 = NULL;	
	cJSON *propertyItem2 = NULL;	
	kk_rpc_set func;
	int rev = 0,startIdx1 = 0,startIdx2 = 0;
	char tmp_Identity[64] = {0};
	int findFlag = 0;

	uint8_t eui64[EUI64_SIZE];
	EmberNodeId nodeId = EMBER_AF_PLUGIN_DEVICE_TABLE_NULL_NODE_ID;
	UTIL_LOG_INFO("\n********************kk tsl property operation********************\n");

	if(params == NULL){
		set_json_error_type(ctx,JRPC_INVALID_PARAMS,MSG_INVALID_PARAMS);
		goto error_return;
	}else{
		rpc_get_mac(mac->valuestring,eui64);
		nodeId = emberAfDeviceTableGetNodeIdFromEui64(eui64);
		dev = kk_device_find_by_mac(eui64); 
		if(dev == NULL){
			goto error_return;
		}	
		dev_info = kk_device_config_find(dev->productCode);
		if(dev_info == NULL){
			goto error_return;
		}
		item = &dev_info->item;
		while(item!=NULL){
			rev = kk_tsl_utils_memtok(item->identity,'.',2,&startIdx2);
			if(!rev){
				kk_tsl_utils_memtok(item->identity,'.',1,&startIdx1);
				memset(tmp_Identity,0x0,sizeof(tmp_Identity));
				memcpy(tmp_Identity, item->identity, startIdx1);
				propertyItem2 = rpc_cJSON_GetObjectItem(params,tmp_Identity);
				if(propertyItem2 != NULL){
					memset(tmp_Identity,0x0,sizeof(tmp_Identity));
					memcpy(tmp_Identity, item->identity+startIdx1+1, startIdx2-startIdx1);
					propertyItem1 = rpc_cJSON_GetObjectItem(propertyItem2,tmp_Identity);
					if(propertyItem1 != NULL){
						propertyItem = rpc_cJSON_GetObjectItem(propertyItem1,item->identity+startIdx2+1);
						if(propertyItem != NULL){
							findFlag = 1;
						}

					}
				}

			}			
			else{

				rev = kk_tsl_utils_memtok(item->identity,'.',1,&startIdx1);
				if(!rev){
					memset(tmp_Identity,0x0,sizeof(tmp_Identity));
					memcpy(tmp_Identity, item->identity, startIdx1);
					propertyItem1 = rpc_cJSON_GetObjectItem(params,tmp_Identity);
					if(propertyItem1 != NULL){
						propertyItem = rpc_cJSON_GetObjectItem(propertyItem1,item->identity+startIdx1+1);
						if(propertyItem != NULL){
							findFlag = 1;
						}
					}

				}
				else{
					propertyItem = rpc_cJSON_GetObjectItem(params, item->identity);
					if(propertyItem != NULL){
						findFlag = 1;
					}
				}
			}
			if(findFlag == 1){
				int value = 0;
				if(propertyItem->type != cJSON_Number){
					value = rpc_get_u8(propertyItem->valuestring);
				}else{
					value = propertyItem->valueint;
				}	
				func = item->controlFunc;
				res = func(ctx,nodeId,item->endpoint,&value);
				findFlag = 0;
			}
			item = item->next;
		}
		return rpc_cJSON_CreateNumber(res);
	}

error_return:
	return rpc_cJSON_CreateNull();
}


int kk_tsl_set_gloabl_OnOff(jrpc_context * ctx,EmberNodeId node,unsigned char ep,void* data)
{
	uint8_t Onoff	= 0;
	EmberStatus status = 0;

	Onoff = *(int*)data;
	emberAfAppPrintln("[tsl set:OnOff],Onoff=0x%02x",Onoff);

	if(node==EMBER_AF_PLUGIN_DEVICE_TABLE_NULL_NODE_ID){
		if(ctx)
			set_json_error_type(ctx,JRPC_INVALID_PARAMS,MSG_INVALID_PARAMS);
		goto error_return;
	}
	
	if(Onoff==1){
		status = zclOnOff_On(node,ep);
		emberAfAppPrintln("On");
	}else if(Onoff==0){
		status = zclOnOff_Off(node,ep);
		emberAfAppPrintln("Off");
	}else{
		if(ctx)
			set_json_error_type(ctx,JRPC_INVALID_PARAMS,MSG_INVALID_PARAMS);
		goto error_return;
	}

	emberAfAppPrintln("status=0x%02x",status);
	return status;
error_return:
	return -1;

}


int kk_tsl_set_windowCovering_OperationMode(jrpc_context * ctx,EmberNodeId node,unsigned char ep,void* data)
{
	uint8_t Operation	= 0;
	EmberStatus status = 0;

	Operation = *(int*)data;
	emberAfAppPrintln("[tsl set:Window Covering Operation Mode],mode=0x%02x",Operation);

	if(node==EMBER_AF_PLUGIN_DEVICE_TABLE_NULL_NODE_ID){
		if(ctx)
			set_json_error_type(ctx,JRPC_INVALID_PARAMS,MSG_INVALID_PARAMS);
		goto error_return;
	}
	
	if(Operation==0){
		status = WindowCover_UpOpen(node,ep);
		emberAfAppPrintln("Up/Open");
	}else if(Operation==1){
		status = WindowCover_DownClose(node,ep);
		emberAfAppPrintln("Down/Close");
	}else if(Operation==2){
		status = WindowCover_Stop(node,ep);
		emberAfAppPrintln("Stop");
	}else{
		if(ctx)
			set_json_error_type(ctx,JRPC_INVALID_PARAMS,MSG_INVALID_PARAMS);
		goto error_return;
	}

	emberAfAppPrintln("status=0x%02x",status);
	return status;
error_return:
	return -1;
}

int kk_tsl_set_windowCovering_mode(jrpc_context * ctx,EmberNodeId node,unsigned char ep,void* data)
{
	uint8_t mode	= 0;
	uint8_t WCmode	= 0;
	EmberStatus status = 0;

	mode = *(int*)data;
	emberAfAppPrintln("[tsl set:Window Covering Run Mode],mode=0x%02x",mode);

	if(mode==WC_calibration_mode){
		WCmode |= BIT(1);
	
		status = zclGWrite(node,1,ep,false,ZCL_WINDOW_COVERING_CLUSTER_ID,
					ZCL_MODE_ATTRIBUTE_ID,
					ZCL_BITMAP8_ATTRIBUTE_TYPE,
					1,
					WCmode,
					true);
		emberAfAppPrintln("Calibration Mode");
	}else if(mode==WC_reversed_dir){
		WCmode |= BIT(0);
		status = zclGWrite(node,1,ep,false,ZCL_WINDOW_COVERING_CLUSTER_ID,
							ZCL_MODE_ATTRIBUTE_ID,
							ZCL_BITMAP8_ATTRIBUTE_TYPE,
							1,
							WCmode,
							true);
		emberAfAppPrintln("Dir:reversed");
	}else if(mode==WC_normal_dir){
		WCmode = 0;
		status = zclGWrite(node,1,ep,false,ZCL_WINDOW_COVERING_CLUSTER_ID,
						ZCL_MODE_ATTRIBUTE_ID,
						ZCL_BITMAP8_ATTRIBUTE_TYPE,
						1,
						WCmode,
						true);
		emberAfAppPrintln("Dir:Normal");
	}else{
		if(ctx)
			set_json_error_type(ctx,JRPC_INVALID_PARAMS,MSG_INVALID_PARAMS);
		goto error_return;
	}
	emberAfAppPrintln("status=0x%02x",status);
	return status;
error_return:
	return -1;
}
int kk_tsl_set_windowCovering_position(jrpc_context * ctx,EmberNodeId node,unsigned char ep,void* data)
{
	uint8_t position	= 0;
	EmberStatus status = 0;

	position = *(int*)data;
	emberAfAppPrintln("[tsl set:Window Covering Position],position=0x%02x",position);

	status = WindowCover_GotoLiftPercentage(node,ep,position);

	emberAfAppPrintln("status=0x%02x",status);
	return status;
error_return:
	return -1;
}

static uint8_t s_RgbCount = 0;
static COLOR_RGB s_rgb;

static int kk_zclColorControlMovetohueandsat(EmberNodeId node,unsigned char ep)
{
	unsigned short h;
	unsigned char s,l;
	COLOR_HSL hsl;
	EmberStatus status = 0;	
	if(s_RgbCount >= 3){
		RGB_to_HSL(s_rgb.red, s_rgb.green, s_rgb.blue,&h,&s,&l);

		emberAfAppPrintln("[kk_zclColorControlMovetohueandsat]");

		kk_device_table_s* dev = kk_device_find_by_node(node);
		dev->manage.dev.ColorLighting.color.HSL.L = l;
		dev->manage.dev.ColorLighting.CloorSetFlag = true;
		
		emberAfAppPrintln("Save l:%d",l);
		status = zclColorControlMovetohueandsat(node,ep,h*254/360,s*254/100,0,0,0,0);
		status |= zclLevel_MoveToLevel(node,ep,l,0,NULL,NULL);
		s_RgbCount = 0;
	}
	return status;
}
int kk_tsl_set_colorlight_RGB_red(jrpc_context * ctx,EmberNodeId node,unsigned char ep,void* data)
{
	int value = *(int*)data;
	EmberStatus status = 0;
	emberAfAppPrintln("[tsl set:kk_tsl_set_colorloght_RGB_red],value=0x%02x",value);
	//s_Red  = value;
	s_rgb.red = value;
	s_RgbCount++;
	status = kk_zclColorControlMovetohueandsat(node,ep);
	return status;
}
int kk_tsl_set_colorlight_RGB_green(jrpc_context * ctx,EmberNodeId node,unsigned char ep,void* data)
{
	int value = *(int*)data;
	EmberStatus status = 0;	
	emberAfAppPrintln("[tsl set:kk_tsl_set_colorloght_RGB_green],value=0x%02x",value);
	//s_Green  = value;
	s_rgb.green = value;
	s_RgbCount++;
	status = kk_zclColorControlMovetohueandsat(node,ep);
	return status;
}
int kk_tsl_set_colorlight_RGB_blue(jrpc_context * ctx,EmberNodeId node,unsigned char ep,void* data)
{
	int value = *(int*)data;
	EmberStatus status = 0;	
	emberAfAppPrintln("[tsl set:kk_tsl_set_colorloght_RGB_blue],value=0x%02x",value);
	//s_Blue  = value;
	s_rgb.blue = value;
	s_RgbCount++;
	status = kk_zclColorControlMovetohueandsat(node,ep);
	return status;
}

int kk_tsl_set_colorlight_Brightness(jrpc_context * ctx,EmberNodeId node,unsigned char ep,void* data)
{
	int value = *(int*)data;
	EmberStatus status = 0;	
	emberAfAppPrintln("[tsl set:kk_tsl_set_colorloght_Brightness],value=0x%02x",value);
	if(node==EMBER_AF_PLUGIN_DEVICE_TABLE_NULL_NODE_ID){
		if(ctx)
			set_json_error_type(ctx,JRPC_INVALID_PARAMS,MSG_INVALID_PARAMS);
		return -1;
	}	

	status = zclLevel_MoveToLevel(node,ep,value,0,NULL,NULL);
	return status;		
}

int kk_tsl_set_colorlight_mode(jrpc_context * ctx,EmberNodeId node,unsigned char ep,void* data)
{
	int value = *(int*)data;
	EmberStatus status = EMBER_ERR_FATAL;	
	kk_dev_config_item_extra_data *mode;
	int ix = 1;

	emberAfAppPrintln("[tsl set:kk_tsl_set_colorlight_mode],value=0x%02x",value);
	if(node==EMBER_AF_PLUGIN_DEVICE_TABLE_NULL_NODE_ID){
		if(ctx)
			set_json_error_type(ctx,JRPC_INVALID_PARAMS,MSG_INVALID_PARAMS);
		return -1;
	}
	
	mode = kk_find_extra_data(node,"Mode");
	while(mode!=NULL){
		if(ix++==value){
			kk_global_len = mode->len + 1;
			kk_global_buffer[0] = mode->len;
			memcpy(&kk_global_buffer[1],mode->data,kk_global_buffer[0] - 1);
			
			kk_private_protocol(node,kk_global_len,kk_global_buffer);
			emberAfCorePrintln("~~~~~~~~~~~data~~~~~~~~~~");
			emberAfCorePrintBuffer(mode->data,mode->len,true);
			emberAfCorePrintln("\n");
			break;
		}
		mode = mode->next;
	}
	

	return status;		

}





















