
#include <stdio.h>
#include ".././jsonrpc/jsonrpc-c.h"
#include ".././jsonrpc/rpccJSON.h"
#include "kk_ncp_common.h"
#include "kk_wlist_mng.h"
#include "sqlite3.h"

#define KK_TSL_GATAWAY_ADDWHITELIST_IDENTIFIER      	   "addWhiteList"
#define KK_TSL_GATAWAY_WHITELISTDEVICE_IDENTIFIER      	   "Devices"
#define KK_TSL_GATAWAY_WHITELISTMAC_IDENTIFIER      	   "getWhiteListNotification.Devices[%d].MACAddress"
#define KK_TSL_GATAWAY_WHITELISTPRODUCTID_IDENTIFIER       "getWhiteListNotification.Devices[%d].ProductId"
#define KK_TSL_GATAWAY_WHITELISTSN_IDENTIFIER      	       "getWhiteListNotification.Devices[%d].SN"
#define KK_TSL_GATAWAY_WHITELISTDEVICEID_IDENTIFIER        "getWhiteListNotification.Devices[%d].deviceId"

#define KK_WLIST_DB_FILE                                   "/usr/kk/kk_wlist.db"


typedef struct {
    void *mutex;
	int  isOpened;
    sqlite3 *pDb;	
} kk_wlist_ctx_t;

static kk_wlist_ctx_t s_kk_wlist_ctx = {NULL,0,NULL};
static kk_wlist_ctx_t *_kk_wlist_get_ctx(void)
{
    return &s_kk_wlist_ctx;
}
static void _kk_wlist_lock(void)
{
    kk_wlist_ctx_t *ctx = _kk_wlist_get_ctx();
    if (ctx->mutex) {
        HAL_MutexLock(ctx->mutex);
    }
}

static void _kk_wlist_unlock(void)
{
    kk_wlist_ctx_t *ctx = _kk_wlist_get_ctx();
    if (ctx->mutex) {
        HAL_MutexUnlock(ctx->mutex);
    }
}

static int kk_wlist_db_Init(void)
{
    kk_wlist_ctx_t *ctx = _kk_wlist_get_ctx();

    //eUtils_LockLock(&sLock);
    _kk_wlist_lock();
    
    if (sqlite3_open_v2(KK_WLIST_DB_FILE, &ctx->pDb, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_FULLMUTEX, NULL) != SQLITE_OK)
    { 
        printf("Error initialising linkage database (%s)", sqlite3_errmsg(ctx->pDb));
		_kk_wlist_unlock();
        return FAIL_RETURN; 
    }     
    printf("wlist Database opened\n");
    {
		const char *pwListTable = "CREATE TABLE IF NOT EXISTS WhiteList(deviceMac varchar(17),productId varchar(33), deviceSN varchar(33), deviceId varchar(33),open INTEGER)";

	    char *pcErr;
        
//     DBG_vPrintf(DBG_SQL, "Execute SQL: '%s'\n", pConditionTableDef);
        
        if (sqlite3_exec(ctx->pDb, pwListTable, NULL, NULL, &pcErr) != SQLITE_OK)
        {
            printf("Error creating table (%s)\n", pcErr);
            sqlite3_free(pcErr);
            //eUtils_LockUnlock(&sLock);
            _kk_wlist_unlock();
            return FAIL_RETURN;
        }
	 
    }

    //eUtils_LockUnlock(&sLock);
    _kk_wlist_unlock();
    return SUCCESS_RETURN;
}
static int _kk_check_exist(const char* device_mac)
{
	int isExist = 0;
	sqlite3_stmt *stmt;
	char *pmac = NULL;
    kk_wlist_ctx_t *ctx = _kk_wlist_get_ctx();
	const char *searchCmd = "select * from WhiteList;";	
	sqlite3_prepare_v2(ctx->pDb, searchCmd, strlen(searchCmd), &stmt, NULL);
	printf("total_column = %d\n", sqlite3_column_count(stmt));
	while(sqlite3_step(stmt) == SQLITE_ROW){
	   pmac = sqlite3_column_text(stmt, 1);
	   if(!strcmp(device_mac,pmac))
	   
{
		 isExist = 1;
		 break;
	   }
    }
    printf("\n");
	sqlite3_finalize(stmt);
	return isExist;

	

}
static int kk_wlist_insert_db(char device_mac[DEVICE_MAC_MAXLEN],char product_Id[PRODUCT_CODE_MAXLEN], \
										char device_SN[DEVICE_SN_MAXLEN],char device_Id[DEVICE_CODE_MAXLEN])
{
	const char *insertCmd = "insert into WhiteList (deviceMac, productId,deviceSN,deviceId,open) values ('%s','%s','%s','%s','%d');";
	char *sqlCmd = NULL;
	int len =0;
	int rc = 0;
	char *zErrMsg = 0;
    kk_wlist_ctx_t *ctx = _kk_wlist_get_ctx();
	
	if(ctx->isOpened != 1){
		printf("[%s][%d] PLEASE OPNE THE WHITELIST FUNCTION FIRST!!!\n",__FUNCTION__,__LINE__);
		return FAIL_RETURN;
	}

	_kk_wlist_lock();
	len = strlen(insertCmd)+DEVICE_MAC_MAXLEN+DEVICE_SN_MAXLEN+DEVICE_CODE_MAXLEN+PRODUCT_CODE_MAXLEN;
	sqlCmd = (char*)malloc(len);
	if(sqlCmd == NULL)
	{
		_kk_wlist_unlock();
		return MEMORY_NOT_ENOUGH;
	}
	memset(sqlCmd,0x0,len);
	sprintf(sqlCmd, insertCmd,device_mac,product_Id,device_SN,device_Id,1);
	
	rc = sqlite3_exec(ctx->pDb, sqlCmd, NULL, NULL, &zErrMsg);
	if( rc != SQLITE_OK ){
	   printf("SQL error: %s\n", zErrMsg);
	   sqlite3_free(zErrMsg);
	}else{
	   printf("kk_wlist_insert_db successfully\n");
	}
	free(sqlCmd);
	sqlCmd = NULL;
	_kk_wlist_unlock();
	return SUCCESS_RETURN;
}

static int _kk_wlist_delete_db_byMac(char device_mac[DEVICE_MAC_MAXLEN])
{
	const char *deleteCmd = "delete from WhiteList where deviceMac = %s;";
	char *sqlCmd = NULL;
	int len =0;
	int rc = 0;
	char *zErrMsg = 0;
	kk_wlist_ctx_t *ctx = _kk_wlist_get_ctx();
	if(ctx->isOpened != 1){
		printf("[%s][%d] PLEASE OPNE THE WHITELIST FUNCTION FIRST!!!\n",__FUNCTION__,__LINE__);
		return FAIL_RETURN;
	}

	_kk_wlist_lock();
	len = strlen(deleteCmd)+DEVICE_MAC_MAXLEN;
	sqlCmd = (char*)malloc(len);
	if(sqlCmd == NULL)
	{
		_kk_wlist_unlock();
		return MEMORY_NOT_ENOUGH;
	}
	memset(sqlCmd,0x0,len);
	sprintf(sqlCmd, deleteCmd,device_mac);
	 printf("Table delete data sqlCmd:%s\n",sqlCmd);
	rc = sqlite3_exec(ctx->pDb, sqlCmd, NULL, NULL, &zErrMsg);
	if( rc != SQLITE_OK ){
	   printf("SQL error: %s\n", zErrMsg);
	   sqlite3_free(zErrMsg);
	}else{
	   printf("Table delete data successfully\n");
	}
	free(sqlCmd);
	sqlCmd = NULL;
	_kk_wlist_unlock();
	return SUCCESS_RETURN;
}

int kk_wlist_status_open(int isOpen)
{
	int res = 0;
    kk_wlist_ctx_t *ctx = _kk_wlist_get_ctx();

	ctx->isOpened = isOpen;
	return SUCCESS_RETURN;
}

int kk_wlist_init(void)
{
	int res = 0;
    kk_wlist_ctx_t *ctx = _kk_wlist_get_ctx();
	
    /* Create Mutex */
    ctx->mutex = HAL_MutexCreate();
    if (ctx->mutex == NULL) {
        return FAIL_RETURN;
    }

	res = kk_wlist_db_Init();
	if(res != SUCCESS_RETURN){
		printf("[%s][%d]kk_wlist_db_Init FAIL!!!\n",__FUNCTION__,__LINE__);

	}
	return SUCCESS_RETURN;
}

cJSON *kk_wlist_add(jrpc_context * ctx, cJSON *params, cJSON *id,cJSON *mac)
{
	int res = 0;
	char *macStr = NULL;
	char *productCodeStr = NULL;
	EmberEUI64 localEui64  = {0};

	emberAfGetEui64(localEui64);
	if(params == NULL){
		goto error_return;
	}else{
		cJSON *deviceArray = rpc_cJSON_GetObjectItem(params,"Devices");
		cJSON * item = deviceArray->child;
		while(item != NULL){
			macStr = rpc_cJSON_GetObjectItem(item,"MACAddress")->valuestring;
			productCodeStr = rpc_cJSON_GetObjectItem(item,"ProductId")->valuestring;
			if(!_kk_check_exist(macStr)){
				kk_wlist_insert_db(macStr,productCodeStr,"",macStr);
			}
			item = item->next;
		}
		kk_msg_report_whiteListAddedNotification("",localEui64);
		return rpc_cJSON_CreateNumber(res);
	}

error_return:
	return rpc_cJSON_CreateNull();
}

cJSON *kk_wlist_delete(jrpc_context * ctx, cJSON *params, cJSON *id,cJSON *mac)
{
	int res = 0;
	char *macStr = NULL;
	EmberEUI64 localEui64  = {0};

	emberAfGetEui64(localEui64);	
	if(params == NULL){
		goto error_return;
	}else{
		cJSON *deviceArray = rpc_cJSON_GetObjectItem(params,"Devices");
		cJSON * item = deviceArray->child;
		while(item != NULL){
			macStr = rpc_cJSON_GetObjectItem(item,"MACAddress")->valuestring;
			_kk_wlist_delete_db_byMac(macStr);
			item = item->next;
		}
		kk_msg_report_whiteListDelNotification("",localEui64);
		return rpc_cJSON_CreateNumber(res);
	}

error_return:
	return rpc_cJSON_CreateNull();
}


