#include "kk_ncp_common.h"
#include "kk_ncp_msg.h"
#include "kk_ncp_rpc.h"



static struct jrpc_server my_server;

typedef cJSON(*rpc_function)(jrpc_context * ctx, cJSON * params, cJSON *id);

typedef struct{
	rpc_function	func;
	char *			name;
}rpc_table_s;

extern cJSON *kk_tsl_property_operation(jrpc_context * ctx, cJSON * params, cJSON *id,cJSON *mac);
extern cJSON *kk_topo_change_operation(jrpc_context * ctx, cJSON *params, cJSON *id,cJSON *mac);
extern cJSON *kk_tsl_get_property_operation(jrpc_context * ctx, cJSON *params, cJSON *id,cJSON *mac);
extern cJSON *kk_wlist_add(jrpc_context * ctx, cJSON *params, cJSON *id,cJSON *mac);
extern cJSON *kk_wlist_delete(jrpc_context * ctx, cJSON *params, cJSON *id,cJSON *mac);


static rpc_table_s rpc_table[]={
	{(rpc_function*)kk_tsl_get_property_operation,KK_GET_PROPERTY_MSG_TYPE},\
	{(rpc_function*)kk_tsl_property_operation,KK_THING_SERVICE_PROPERTY_SET},\
	{(rpc_function*)kk_topo_change_operation,KK_DEVICE_TOPO_CHANGE_TYPE},\
	{(rpc_function*)kk_wlist_add,"/thing/service/addWhiteList"},\
	{(rpc_function*)kk_wlist_delete,"/thing/service/deleteWhiteList"}, \
};



struct jrpc_server *kk_get_jrpc_server(void)
{
	return &my_server;
}

void kk_jrpc_init(void)
{
	my_server.debug_level = 1;

	emberAfDebugPrintln("sizeof(rpc_table)=%d,sizeof(rpc_table_s)=%d,%d\n",sizeof(rpc_table),sizeof(rpc_table_s),sizeof(rpc_table)/sizeof(rpc_table_s));
	for(int i=0;i<sizeof(rpc_table)/sizeof(rpc_table_s);i++){
		emberAfDebugPrintln("i=%d,%s\r\n",i,rpc_table[i].name);
		jrpc_register_procedure(&my_server, rpc_table[i].func, rpc_table[i].name, NULL );
	}
}

static int invoke_procedure(struct jrpc_server *server,
									char *name, cJSON *params, cJSON *id,cJSON *mac) {
	cJSON *returned = NULL;
	int procedure_found = 0;
	jrpc_context ctx;
	int i = server->procedure_count;

	while (i--) {
		if (!strcmp(server->procedures[i].name, name)) {
			procedure_found = 1;
			ctx.data = server->procedures[i].data;
			returned = server->procedures[i].function(&ctx, params, id, mac);
			break;
		}
	}
	if (!procedure_found){
		emberAfDebugPrintln("[rpc invoke] Method not found...\n");
		return -1;
	}else {
		return 0;
	}
}

int kk_jrpc_eval_request(cJSON *root)
{
	cJSON *info,*payload;
	cJSON *msgType,*deviceCode,*productCode;
	cJSON *params,*id;
	
	info = rpc_cJSON_GetObjectItem(root, "info");
	payload = rpc_cJSON_GetObjectItem(root, "payload");

	if(info != NULL){
		msgType = rpc_cJSON_GetObjectItem(info, "msgType");
		deviceCode = rpc_cJSON_GetObjectItem(info, "deviceCode");
		productCode = rpc_cJSON_GetObjectItem(info, "productCode");
	}
	
	if(payload != NULL){
		params = rpc_cJSON_GetObjectItem(payload, "params");
		id = rpc_cJSON_GetObjectItem(payload, "msgId");
	}
	
	if(id != NULL && params != NULL && msgType != NULL && 
		deviceCode != NULL && deviceCode!= NULL){
		
		if(strcmp(msgType->valuestring,KK_GET_PROPERTY_MSG_TYPE)==0)
			kk_tsl_msg_ack(id->valuestring,msgType->valuestring,productCode->valuestring,deviceCode->valuestring);
		
		return invoke_procedure(&my_server, msgType->valuestring,
								params, id,deviceCode);	
	}

	return -1;
}























