#include <stdio.h>
#include "kk_tsl_api.h"
#include "kk_dm_mng.h"
#include "sqlite3.h"
#include "kk_log.h"
#include "kk_area_handle.h"
#include "kk_hal.h"
#include "id.h"

extern sqlite3 *g_kk_pDb;

static kk_dev_list_t *s_device_list = NULL;

typedef struct {
    void *mutex;
	int  roomNum;
    sqlite3 *pDb;	
} kk_area_ctx_t;



static kk_area_ctx_t s_kk_area_ctx = {NULL,0,NULL};

static kk_area_ctx_t *_kk_area_get_ctx(void)
{
    return &s_kk_area_ctx;
}
static void _kk_area_lock(void)
{
    kk_area_ctx_t *ctx = _kk_area_get_ctx();
    if (ctx->mutex) {
        HAL_MutexLock(ctx->mutex);
    }
}

static void _kk_area_unlock(void)
{
    kk_area_ctx_t *ctx = _kk_area_get_ctx();
	
    if (ctx->mutex) {
        HAL_MutexUnlock(ctx->mutex);
    }
}
static int _kk_area_db_init(void)
{
    kk_area_ctx_t *ctx = _kk_area_get_ctx();
    char *pcErr;

    //eUtils_LockLock(&sLock);
    _kk_area_lock();
    ctx->pDb = g_kk_pDb;
   
    INFO_PRINT("area db Database opened\n");
    
	const char *pAreaTable = "CREATE TABLE IF NOT EXISTS AreaInfo( \
		idx INTEGER PRIMARY KEY, \
		name varchar(256), \
		roomId varchar(256))";

    if (sqlite3_exec(ctx->pDb, pAreaTable, NULL, NULL, &pcErr) != SQLITE_OK)
    {
        ERROR_PRINT("Error creating table (%s)\n", pcErr);
        sqlite3_free(pcErr);
        //eUtils_LockUnlock(&sLock);
        _kk_area_unlock();
        return FAIL_RETURN;
    }

	const char *pAreaDevTable = "CREATE TABLE IF NOT EXISTS AreaDevInfo( \
		idx INTEGER PRIMARY KEY, \
		roomId varchar(256), \
		deviceCode varchar(33), \
		epNum varchar(10))";

    if (sqlite3_exec(ctx->pDb, pAreaDevTable, NULL, NULL, &pcErr) != SQLITE_OK)
    {
        ERROR_PRINT("Error creating table (%s)\n", pcErr);
        sqlite3_free(pcErr);
        //eUtils_LockUnlock(&sLock);
        _kk_area_unlock();
        return FAIL_RETURN;
    }

    _kk_area_unlock();
    return SUCCESS_RETURN;
}


int kk_area_init(void)
{
	int res = 0;
    kk_area_ctx_t *ctx = _kk_area_get_ctx();
	set_workid(100);
    /* Create Mutex */
    ctx->mutex = HAL_MutexCreate();
    if (ctx->mutex == NULL) {
        return FAIL_RETURN;
    }

	res = _kk_area_db_init();
	if(res != SUCCESS_RETURN){
		ERROR_PRINT("[%s][%d]kk_area_init FAIL!!!\n",__FUNCTION__,__LINE__);
	}
	return SUCCESS_RETURN;
}


int kk_room_add(const char *name,const char *roomId)
{
	int res = 0;
    kk_area_ctx_t *ctx = _kk_area_get_ctx();
	char *sqlCmd = NULL;
	char *zErrMsg = 0;

	const char *insertCmd = "insert into AreaInfo (name, roomId) \
								values ('%s','%s');";						
	_kk_area_lock();
	ctx->roomNum++;
	HAL_GetTime_s((char*)roomId);

	sqlCmd = sqlite3_mprintf(insertCmd,name,roomId);	
	res = sqlite3_exec(ctx->pDb, sqlCmd, NULL, NULL, &zErrMsg);
	if( res != SQLITE_OK ){
	   ERROR_PRINT("SQL error: %s\n", zErrMsg);
	   sqlite3_free(zErrMsg);
	}else{
	   //INFO_PRINT("sub device insert data successfully\n");
	}
	sqlite3_free(sqlCmd);
	_kk_area_unlock();
	return SUCCESS_RETURN;
}

int kk_room_delete(const char *roomId)
{
	int res = 0;
    kk_area_ctx_t *ctx = _kk_area_get_ctx();
	char *sqlCmd = NULL;
	char *zErrMsg = 0;
	const char *deleteCmd = "delete from AreaInfo where roomId = '%s';";

								
	_kk_area_lock();
	 sqlCmd = sqlite3_mprintf(deleteCmd,roomId);	

	INFO_PRINT("Table delete data sqlCmd:%s\n",sqlCmd);
	res = sqlite3_exec(ctx->pDb, sqlCmd, NULL, NULL, &zErrMsg);
	if( res != SQLITE_OK ){
	   ERROR_PRINT("SQL error: %s\n", zErrMsg);
	   sqlite3_free(zErrMsg);
	}else{
	   //INFO_PRINT("Table delete data successfully\n");
	   ctx->roomNum--;
	}
	sqlite3_free(sqlCmd);
	
	_kk_area_unlock();
	return SUCCESS_RETURN;
}

static int _kk_check_dev_exist(const char* deviceCode)
{
	int isExist = 0;
	sqlite3_stmt *stmt;
	char *pDeviceCode = NULL;
    kk_area_ctx_t *ctx = _kk_area_get_ctx();
	const char *searchCmd = "select * from AreaDevInfo;";	
	_kk_area_lock();
	
	sqlite3_prepare_v2(ctx->pDb, searchCmd, strlen(searchCmd), &stmt, NULL);
	//INFO_PRINT("total_column = %d\n", sqlite3_column_count(stmt));
	while(sqlite3_step(stmt) == SQLITE_ROW){
	   pDeviceCode = (char*)sqlite3_column_text(stmt, DB_DEV_DEVICECODE);
	   if(!strcmp(deviceCode,pDeviceCode))
	   
{
		 isExist = 1;
		 break;
	   }
    }
    //INFO_PRINT("\n");
	sqlite3_finalize(stmt);
	_kk_area_unlock();
	return isExist;
}

int kk_room_dev_add(const char *roomId,const char *deviceCode,const char *epNum)
{
	int res = 0;
    kk_area_ctx_t *ctx = _kk_area_get_ctx();
	char *sqlCmd = NULL;
	char *zErrMsg = 0;

	if(_kk_check_dev_exist(deviceCode)){
		sqlCmd = sqlite3_mprintf("UPDATE AreaDevInfo SET roomId='%s', epNum='%s' \
					WHERE deviceCode= '%s'",roomId,epNum,deviceCode);	

	}
	else{
		const char *insertCmd = "insert into AreaDevInfo (roomId, deviceCode, epNum) \
							values ('%s','%s','%s');";	
		sqlCmd = sqlite3_mprintf(insertCmd,roomId,deviceCode,epNum);
	}
								
	_kk_area_lock();
	res = sqlite3_exec(ctx->pDb, sqlCmd, NULL, NULL, &zErrMsg);
	if( res != SQLITE_OK ){
	   ERROR_PRINT("SQL error: %s\n", zErrMsg);
	   sqlite3_free(zErrMsg);
	}else{
	   //INFO_PRINT("sub device insert data successfully\n");
	}
	sqlite3_free(sqlCmd);
	_kk_area_unlock();
	return SUCCESS_RETURN;
}

int kk_room_dev_remove(const char *deviceCode,const char *epNum)
{
	int res = 0;
    kk_area_ctx_t *ctx = _kk_area_get_ctx();
	char *sqlCmd = NULL;
	char *zErrMsg = 0;
	const char *insertCmd = NULL;

	if(epNum == NULL){
		insertCmd = "delete from AreaDevInfo where deviceCode = '%s';";
	}
	else{
		insertCmd = "delete from AreaDevInfo where deviceCode = '%s' and epNum = '%s';";
	}
								
	_kk_area_lock();
	sqlCmd = sqlite3_mprintf(insertCmd,deviceCode,epNum);	
	res = sqlite3_exec(ctx->pDb, sqlCmd, NULL, NULL, &zErrMsg);
	if( res != SQLITE_OK ){
	   ERROR_PRINT("SQL error: %s\n", zErrMsg);
	   sqlite3_free(zErrMsg);
	}else{
	   //INFO_PRINT("sub device insert data successfully\n");
	}
	sqlite3_free(sqlCmd);
	_kk_area_unlock();
	return SUCCESS_RETURN;
}



int kk_room_device_list_add(const char *deviceCode)
{
	//int len;
	kk_dev_list_t *ptr,*pre;
	
	ptr = pre = s_device_list;
	if(deviceCode == NULL){
		return FAIL_RETURN;
	}
	
	while(ptr!=NULL){
		pre = ptr;
		if(strcmp(ptr->deviceCode,deviceCode) == 0){
			return SUCCESS_RETURN;
		}
		ptr = ptr->next;
	}
	ptr = (kk_dev_list_t*)malloc(sizeof(kk_dev_list_t));
	memset(ptr,0,sizeof(kk_dev_list_t));
	memcpy(ptr->deviceCode,deviceCode,strlen(deviceCode));

	if(s_device_list==NULL){
		s_device_list = ptr;
	}else{
		pre->next = ptr;
	}

	return SUCCESS_RETURN;
}

kk_dev_list_t*  kk_get_room_deviceCode(const char* roomId)
{
	sqlite3_stmt *stmt;
	char *sqlCmd = NULL;
    kk_area_ctx_t *ctx = _kk_area_get_ctx();
	const char *searchCmd = "select * from AreaDevInfo;";	
	_kk_area_lock();
	sqlCmd = sqlite3_mprintf(searchCmd,roomId);	
	sqlite3_prepare_v2(ctx->pDb, sqlCmd, strlen(sqlCmd), &stmt, NULL);
	//INFO_PRINT("total_column = %d\n", sqlite3_column_count(stmt));
	while(sqlite3_step(stmt) == SQLITE_ROW){
	   if(strcmp((char*)sqlite3_column_text(stmt, DB_DEV_ROOM_ID),roomId) == 0){
	   		kk_room_device_list_add((char*)sqlite3_column_text(stmt, DB_DEV_DEVICECODE));
	   }
    }
	sqlite3_finalize(stmt);
	_kk_area_unlock();
	return s_device_list;
}
void kk_free_room_dev_list(void)
{
	kk_dev_list_t *ptr = s_device_list;
	kk_dev_list_t *ptmp = NULL;
	while(ptr != NULL){
		ptmp = ptr->next;
		free(ptr);
		ptr = NULL;
		ptr = ptmp;
	}
	s_device_list = NULL;
}



