#include "rpc_network_operate.h"
#include "network-creator.h"
#include "network-creator-security.h"



void nwkGetInfo(rpc_nwk_info_s *info)
{
	emberAfGetEui64(info->eui64);
	emberAfPrintBigEndianEui64(info->eui64);
	
	info->status = ezspNetworkState();
	if (info->status== EMBER_JOINED_NETWORK ){
		info->nodeid = emberAfGetNodeId();
		info->panid = emberAfGetPanId();
		info->ch = emberAfGetRadioChannel();

		if ( emberGetKey(EMBER_CURRENT_NETWORK_KEY,&info->nwkKey) == EMBER_SUCCESS )
		{
			emberAfAppPrintln("\r\nNetwork Key	 = " );
			emberAfPrintZigbeeKey(emberKeyContents(&info->nwkKey.key));
			emberAfAppFlush();
		}
		
	}

}

EmberStatus nwkFormCMD(bool centralized,uint16_t panId,int8_t txPower,uint8_t channel)
{
	EmberStatus status = emberAfPluginNetworkCreatorNetworkForm(centralized,
																panId,
																txPower,
																channel);
	emberAfCorePrintln("%p: %p: 0x%X",
						"NWK Creator",
						"Form",
						status);
	return status;
}

void nwkStartCMD(bool centralized)
{
	EmberStatus status = emberAfPluginNetworkCreatorStart(centralized);

	emberAfCorePrintln("%p: %p: 0x%X",
						"NWK Creator",
						"Form",
						status);
}

void nwkaddChMaskCMD(bool channelMaskIsPrimary,uint32_t channelOrNewMask)
{
	uint32_t *channelMask = (channelMaskIsPrimary
							 ? &emAfPluginNetworkCreatorPrimaryChannelMask
							 : &emAfPluginNetworkCreatorSecondaryChannelMask);
	

	if (channelOrNewMask < EMBER_MIN_802_15_4_CHANNEL_NUMBER
			|| channelOrNewMask > EMBER_MAX_802_15_4_CHANNEL_NUMBER) {
			emberAfCorePrintln("%p: %p: 0x%X",
								"NWK Creator",
								"Illegal 802.15.4 channel",
								channelOrNewMask);
	}else{
		*channelMask |= (1 << channelOrNewMask);
	}
	emberAfCorePrint("%p channel mask now: 0x%4X [",
					(channelMaskIsPrimary ? "Primary" : "Secondary"),
					*channelMask);
	emberAfPrintChannelListFromMask(*channelMask);
	emberAfCorePrintln("]");
}

void nwksubChMaskCMD(bool channelMaskIsPrimary,uint32_t channelOrNewMask)
{
	uint32_t *channelMask = (channelMaskIsPrimary
							 ? &emAfPluginNetworkCreatorPrimaryChannelMask
							 : &emAfPluginNetworkCreatorSecondaryChannelMask);
	

	if (channelOrNewMask < EMBER_MIN_802_15_4_CHANNEL_NUMBER
			|| channelOrNewMask > EMBER_MAX_802_15_4_CHANNEL_NUMBER) {
			emberAfCorePrintln("%p: %p: 0x%X",
								"NWK Creator",
								"Illegal 802.15.4 channel",
								channelOrNewMask);
	}else {
		*channelMask &= ~(1 << channelOrNewMask);
	}
	emberAfCorePrint("%p channel mask now: 0x%4X [",
					(channelMaskIsPrimary ? "Primary" : "Secondary"),
					*channelMask);
	emberAfPrintChannelListFromMask(*channelMask);
	emberAfCorePrintln("]");
}

void nwksetChMaskCMD(bool channelMaskIsPrimary,uint32_t channelOrNewMask)
{
	uint32_t *channelMask = (channelMaskIsPrimary
							 ? &emAfPluginNetworkCreatorPrimaryChannelMask
							 : &emAfPluginNetworkCreatorSecondaryChannelMask);

	*channelMask = channelOrNewMask;
	emberAfCorePrint("%p channel mask now: 0x%4X [",
					(channelMaskIsPrimary ? "Primary" : "Secondary"),
					*channelMask);
	emberAfPrintChannelListFromMask(*channelMask);
	emberAfCorePrintln("]");
}

void nwkgetChMaskCMD(void)
{
	uint8_t i;
	uint32_t masks[] = { 0,
						emAfPluginNetworkCreatorPrimaryChannelMask,
						emAfPluginNetworkCreatorSecondaryChannelMask };

	emberAfCorePrintln("%p: %p:",
						"NWK Creator",
						"Channel mask");
	for (i = 1; i <= 2; i++) {
		emberAfCorePrint("    (%d) 0x%4X [",
						i,
						masks[i]);
		emberAfPrintChannelListFromMask(masks[i]);
		emberAfCorePrintln("]");
	}
}

EmberStatus nwkPermitJoinCMD(bool open)
{
	EmberStatus status;
	status = (open
				? emberAfPluginNetworkCreatorSecurityOpenNetwork()
				: emberAfPluginNetworkCreatorSecurityCloseNetwork());

	emberAfCorePrintln("%p: %p network: 0x%X",
						"NWK Creator Security",
						(open ? "Open" : "Close"),
						status);
	return status;
}


void nwkPermitJoinWithKeyCMD(EmberEUI64 eui64,EmberKeyData keyData)
{
	EmberStatus status;

	status = emberAfPluginNetworkCreatorSecurityOpenNetworkWithKeyPair(eui64, keyData);

	emberAfCorePrintln("%p: Open network: 0x%X",
						"NWK Creator Security",
						status);
}

void nwkSetJoiningLinkKeyCMD(EmberEUI64 eui64,EmberKeyData keyData)
{
	EmberStatus status;

	status = ezspAddTransientLinkKey(eui64, &keyData);

	emberAfCorePrintln("%p: %p: 0x%X",
						"NWK Creator Security",
						"Set joining link key",
						status);
}

void nwkClearJoiningLinkKeyCMD(void)
{
	ezspClearTransientLinkKeys();

	emberAfCorePrintln("%p: %p: 0x%X",
						"NWK Creator Security",
						"Clear joining link keys",
						EMBER_SUCCESS);
}

// network leave
EmberStatus nwkLeave(void)
{
	EmberStatus status;
	status = emberLeaveNetwork();

	emberAfAppPrintln("%p 0x%x", "leave", status);
	return status;
}
EmberStatus nwkLeaveRequest(EmberNodeId target,bool removeChildren,bool rejoin)
{
	EmberEUI64 nullEui64 = { 0, 0, 0, 0, 0, 0, 0, 0 };
	EmberStatus status;

	uint8_t options = 0;
	if (rejoin) {
		options |= EMBER_ZIGBEE_LEAVE_AND_REJOIN;
	}
	if (removeChildren) {
		options |= EMBER_ZIGBEE_LEAVE_AND_REMOVE_CHILDREN;
	}

	status = emberLeaveRequest(target,
								nullEui64,
								options,
								EMBER_APS_OPTION_RETRY);

	emberAfAppPrintln("Leave %p0x%X", "Request: ", status);
	return status;
}



/**************************************************************************************************/
/*
void nwkStartCMD(bool centralized);
void nwkaddChMaskCMD(bool channelMaskIsPrimary,uint32_t channelOrNewMask);
void nwksubChMaskCMD(bool channelMaskIsPrimary,uint32_t channelOrNewMask);
void nwksetChMaskCMD(bool channelMaskIsPrimary,uint32_t channelOrNewMask);
void nwkgetChMaskCMD(void);
void nwkPermitJoinCMD(bool open);
void nwkPermitJoinWithKeyCMD(EmberEUI64 eui64,EmberKeyData keyData);
void nwkSetJoiningLinkKeyCMD(EmberEUI64 eui64,EmberKeyData keyData);
void nwkClearJoiningLinkKeyCMD(void);
cJSON * test_func(jrpc_context * ctx, cJSON * params, cJSON *id) {

	cJSON * item1 = rpc_cJSON_CreateObject();
	cJSON * item2 = rpc_cJSON_CreateObject();

	rpc_cJSON_AddNullToObject(item1,"Null");
	rpc_cJSON_AddTrueToObject(item1,"True");
	rpc_cJSON_AddFalseToObject(item1,"False");
	rpc_cJSON_AddNumberToObject(item1, "Number",12345);
	rpc_cJSON_AddStringToObject(item1, "String","hello world!");

	rpc_cJSON_AddNullToObject(item2,"1");
	rpc_cJSON_AddTrueToObject(item2,"2");
	rpc_cJSON_AddFalseToObject(item2,"3");
	rpc_cJSON_AddNumberToObject(item2, "4",12345);
	rpc_cJSON_AddStringToObject(item2, "5","hello world!");

	rpc_cJSON_AddItemToObject(item1,"hhhhhh",item2);

	return item1;
}*/


cJSON *rpc_nwkLeaveRequest(jrpc_context * ctx, cJSON * params, cJSON *id)
{
	cJSON *item_target,*item_rm,*item_rejoin;
	EmberNodeId target;
	bool removeChildren;
	bool rejoin;
	EmberStatus status;

	if(params == NULL){
		emberAfCorePrintln("\r\nparams == NULL\r\n" );
		set_json_error_type(ctx,JRPC_INVALID_PARAMS,MSG_INVALID_PARAMS);
		goto error_return;
	}else if(params->type == cJSON_Object){
		item_target = rpc_cJSON_GetObjectItem(params, "target");
		item_rm = rpc_cJSON_GetObjectItem(params, "removeChildren");
		item_rejoin = rpc_cJSON_GetObjectItem(params, "rejoin");
		
	}else if(params->type == cJSON_Array){
		//
	}
	if(item_target==NULL||item_rm==NULL||item_rejoin==NULL){
		set_json_error_type(ctx,JRPC_INVALID_PARAMS,MSG_INVALID_PARAMS);
		kk_print_debug("1....\n");
		goto error_return;
	}
	if(item_target->type!=cJSON_String ||
		(item_rm->type!=cJSON_False&& item_rm->type!=cJSON_True)||
		(item_rejoin->type!=cJSON_False&& item_rejoin->type!=cJSON_True)){
		set_json_error_type(ctx,JRPC_INVALID_PARAMS,MSG_INVALID_PARAMS);
		kk_print_debug(".2....\n");
		goto error_return;
	}
	target = rpc_get_u16(item_target->valuestring);
	removeChildren = (item_rm->type==cJSON_True)?true:false;
	rejoin = (item_rejoin->type==cJSON_True)?true:false;
	status = nwkLeaveRequest(target,removeChildren,rejoin);
	return rpc_cJSON_CreateNumber(status);

	error_return:
		return rpc_cJSON_CreateNull();	

}

cJSON *rpc_nwkLeave(jrpc_context * ctx, cJSON * params, cJSON *id)
{
	EmberStatus status;

	if(params == NULL){
		emberAfCorePrintln("\r\nparams == NULL\r\n" );
		set_json_error_type(ctx,JRPC_INVALID_PARAMS,MSG_INVALID_PARAMS);
		return rpc_cJSON_CreateNull();
	}else{
		status = nwkLeave();
		return rpc_cJSON_CreateNumber(status);
	}

}



cJSON *rpc_nwkGetInfo(jrpc_context * ctx, cJSON *params, cJSON *id)
{
	rpc_nwk_info_s info;
	if(params == NULL){
		emberAfCorePrintln("\r\nparams == NULL\r\n" );
		set_json_error_type(ctx,JRPC_INVALID_PARAMS,MSG_INVALID_PARAMS);
		return rpc_cJSON_CreateNull();
	}else{

		nwkGetInfo(&info);
		cJSON *item = rpc_cJSON_CreateObject();
		char buffer[100];
		sprintf(buffer, "%02X %02X %02X %02X %02X %02X %02X %02X",
				info.eui64[7],
				info.eui64[6],
				info.eui64[5],
				info.eui64[4],
				info.eui64[3],
				info.eui64[2],
				info.eui64[1],
				info.eui64[0]);
		rpc_cJSON_AddStringToObject(item, "MAC",buffer);
		
		info.status = ezspNetworkState();

		switch(info.status){
			case EMBER_NO_NETWORK:
				rpc_cJSON_AddStringToObject(item, "network","no network");
				break;
			case EMBER_JOINING_NETWORK:
				rpc_cJSON_AddStringToObject(item, "network","joining");
				break;
			case EMBER_JOINED_NETWORK:
				rpc_cJSON_AddStringToObject(item, "network","joined");
				break;
			case EMBER_JOINED_NETWORK_NO_PARENT:
				rpc_cJSON_AddStringToObject(item, "network","no parent");
				break;
			case EMBER_LEAVING_NETWORK:
				rpc_cJSON_AddStringToObject(item, "network","leaving");
				break;
			default:
				rpc_cJSON_AddStringToObject(item, "network","unkown");
				break;
		}
		
		if(info.status == EMBER_JOINED_NETWORK){
			rpc_cJSON_AddNumberToObject(item, "channel",info.ch);
			sprintf(buffer,"0x%04X",info.nodeid);
			rpc_cJSON_AddStringToObject(item, "node id",buffer);
			sprintf(buffer,"0x%04X",info.panid);
			rpc_cJSON_AddStringToObject(item, "pan id",buffer);

			for(int i=0;i<EMBER_ENCRYPTION_KEY_SIZE;i++){
				sprintf(&buffer[i*3],"%02X ",info.nwkKey.key.contents[EMBER_ENCRYPTION_KEY_SIZE-1-i]);
			}
			rpc_cJSON_AddStringToObject(item, "network key",buffer);
		}
		
		return item;
	}
}

cJSON *rpc_nwkFormCMD(jrpc_context * ctx, cJSON * params, cJSON *id)
{
	cJSON *item_centralized;
	cJSON *item_panId;
	cJSON *item_txPower;
	cJSON *item_channel;
	EmberStatus status;
	
	if(params == NULL){
		set_json_error_type(ctx,JRPC_INVALID_PARAMS,MSG_INVALID_PARAMS);
		goto error_return;
	}else if(params->type == cJSON_Object){
		item_centralized = rpc_cJSON_GetObjectItem(params, "centralized");
		item_txPower = rpc_cJSON_GetObjectItem(params, "txPower");
		item_channel = rpc_cJSON_GetObjectItem(params, "channel");
		item_panId = rpc_cJSON_GetObjectItem(params, "panId");
	}else if(params->type == cJSON_Array){
		item_centralized = rpc_cJSON_GetArrayItem(params, 0);
		item_panId = rpc_cJSON_GetArrayItem(params, 1);
		item_txPower= rpc_cJSON_GetArrayItem(params, 2);
		item_channel =  rpc_cJSON_GetArrayItem(params, 3);
	}
	else{
		set_json_error_type(ctx,JRPC_INVALID_PARAMS,MSG_INVALID_PARAMS);
		goto error_return;
	}
	
	if(item_centralized == NULL ||
		item_panId == NULL ||
		item_txPower == NULL ||
		item_channel == NULL){
		set_json_error_type(ctx,JRPC_INVALID_PARAMS,MSG_INVALID_PARAMS);
		goto error_return;
	}
	if(item_centralized->type != cJSON_Number ||
		item_panId->type != cJSON_Number ||
		item_txPower->type != cJSON_Number ||
		item_channel->type != cJSON_Number ){
		set_json_error_type(ctx,JRPC_INVALID_PARAMS,MSG_INVALID_PARAMS);
		goto error_return;
	}

	status = nwkFormCMD(item_centralized->valueint,item_panId->valueint,item_txPower->valueint,item_channel->valueint);
		
	return rpc_cJSON_CreateNumber(status);

	error_return:
	return rpc_cJSON_CreateNull();
}

cJSON *rpc_nwkStar(jrpc_context * ctx, cJSON * params, cJSON *id)
{
	return rpc_cJSON_CreateNull();
}
cJSON *rpc_nwkaddChMaskCMD(jrpc_context * ctx, cJSON * params, cJSON *id)
{
	kk_print_debug("1\r\n");
	return rpc_cJSON_CreateNull();
}

cJSON *rpc_nwksubChMaskCMD(jrpc_context * ctx, cJSON * params, cJSON *id)
{
	kk_print_debug("\r\n");
	return rpc_cJSON_CreateNull();
}

cJSON *rpc_nwksetChMaskCMD(jrpc_context * ctx, cJSON * params, cJSON *id)
{
	kk_print_debug("\r\n");
	return rpc_cJSON_CreateNull();
}

cJSON *rpc_nwkgetChMaskCMD(jrpc_context * ctx, cJSON * params, cJSON *id)
{
	kk_print_debug("\r\n");
	return rpc_cJSON_CreateNull();
}



cJSON *rpc_nwkPermitJoinWithKeyCMD(jrpc_context * ctx, cJSON * params, cJSON *id)
{
	kk_print_debug("1\r\n");
	return rpc_cJSON_CreateNull();
}

cJSON *rpc_nwkSetJoiningLinkKeyCMD(jrpc_context * ctx, cJSON * params, cJSON *id)
{
	kk_print_debug("1\r\n");
	return rpc_cJSON_CreateNull();
}

cJSON *rpc_nwkClearJoiningLinkKeyCMD(jrpc_context * ctx, cJSON * params, cJSON *id)
{
	kk_print_debug("2\r\n");
	return rpc_cJSON_CreateNull();
}






















