
#include <stdio.h>
#include "kk_tsl_api.h"
#include "kk_sub_db.h"
#include "sqlite3.h"
#include "kk_log.h"

#define KK_SUB_DB_FILE                                   "subDevice.db"

typedef struct {
    void *mutex;
	int  subDevNum;
    sqlite3 *pDb;	
} kk_subDb_ctx_t;

static kk_subDb_ctx_t s_kk_subDb_ctx = {NULL,0,NULL};
static kk_subDb_ctx_t *_kk_subDb_get_ctx(void)
{
    return &s_kk_subDb_ctx;
}
static void _kk_subDb_lock(void)
{
    kk_subDb_ctx_t *ctx = _kk_subDb_get_ctx();
    if (ctx->mutex) {
        HAL_MutexLock(ctx->mutex);
    }
}

static void _kk_subDb_unlock(void)
{
    kk_subDb_ctx_t *ctx = _kk_subDb_get_ctx();
    if (ctx->mutex) {
        HAL_MutexUnlock(ctx->mutex);
    }
}

static int kk_subDev_db_Init(void)
{
    kk_subDb_ctx_t *ctx = _kk_subDb_get_ctx();

    //eUtils_LockLock(&sLock);
    _kk_subDb_lock();
    
    if (sqlite3_open_v2(KK_SUB_DB_FILE, &ctx->pDb, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_FULLMUTEX, NULL) != SQLITE_OK)
    { 
        ERROR_PRINT("Error initialising linkage database (%s)", sqlite3_errmsg(ctx->pDb));
		_kk_subDb_unlock();
        return FAIL_RETURN; 
    }     
    INFO_PRINT("sub db Database opened\n");
    {
		const char *pSubDevTable = "CREATE TABLE IF NOT EXISTS SubDeviceInfo(idx INTEGER,isOnline INTEGER,productType varchar(33),productCode varchar(33),deviceCode varchar(33),fatherMac varchar(17),version varchar(33))";

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

    //eUtils_LockUnlock(&sLock);
    _kk_subDb_unlock();
    return SUCCESS_RETURN;
}
static int _kk_load_subDevice(void)
{
	const char *searchCmd = "select * from SubDeviceInfo;";	
	sqlite3_stmt *stmt;	
    kk_subDb_ctx_t *ctx = _kk_subDb_get_ctx();
	int devId = 0;
	int res = 0;
	_kk_subDb_lock();
	sqlite3_prepare_v2(ctx->pDb, searchCmd, strlen(searchCmd), &stmt, NULL);
	INFO_PRINT("_kk_load_subDevice total_column = %d\n", sqlite3_column_count(stmt));	
	while(sqlite3_step(stmt) == SQLITE_ROW){
		
	   res = dm_mgr_subdev_create(sqlite3_column_text(stmt, 2),sqlite3_column_text(stmt, 3),sqlite3_column_text(stmt, 4),
	   					sqlite3_column_text(stmt, 5),&devId);
	
	   if(res != SUCCESS_RETURN){
		   ERROR_PRINT("[%s][%d]dm_mgr_subdev_create FAIL!!!\n",__FUNCTION__,__LINE__);
	   }
	   else{
	   	   ctx->subDevNum++;
	   }
	   usleep(100000);
	   iotx_dm_subscribe(devId);
	   kk_dm_ota_report_version(devId,sqlite3_column_text(stmt, 6));//version
	   //usleep(100000);
    }	
	sqlite3_finalize(stmt);
	_kk_subDb_unlock();
	return SUCCESS_RETURN;

}
int kk_subDb_init(void)
{
	int res = 0;
    kk_subDb_ctx_t *ctx = _kk_subDb_get_ctx();
	
    /* Create Mutex */
    ctx->mutex = HAL_MutexCreate();
    if (ctx->mutex == NULL) {
        return FAIL_RETURN;
    }

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

	}
	_kk_load_subDevice();
	return SUCCESS_RETURN;
}
static int _kk_check_subDev_exist(const char* device_mac)
{
	int isExist = 0;
	sqlite3_stmt *stmt;
	char *pmac = NULL;
    kk_subDb_ctx_t *ctx = _kk_subDb_get_ctx();
	const char *searchCmd = "select * from SubDeviceInfo;";	
	_kk_subDb_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){
	   pmac = sqlite3_column_text(stmt, 4);
	   if(!strcmp(device_mac,pmac))
	   
{
		 isExist = 1;
		 break;
	   }
    }
    INFO_PRINT("\n");
	sqlite3_finalize(stmt);
	_kk_subDb_unlock();
	return isExist;

	

}

int kk_subDev_insert_db(int isOnline,char productType[PRODUCT_TYPE_MAXLEN],char productCode[PRODUCT_CODE_MAXLEN], \
										char deviceCode[DEVICE_CODE_MAXLEN],char fatherMac[DEVICE_MAC_MAXLEN],char version[DEVICE_VERSION_MAXLEN])
{
	const char *insertCmd = "insert into SubDeviceInfo (idx,isOnline, productType,productCode,deviceCode,fatherMac,version) values ('%d','%d', '%s', '%s','%s','%s','%s');";
	char *sqlCmd = NULL;
	int rc = 0;
	char *zErrMsg = 0;
    kk_subDb_ctx_t *ctx = _kk_subDb_get_ctx();


	if(_kk_check_subDev_exist((const char*)deviceCode) == 1)
	{
		WARNING_PRINT("[%s][%d] DATA ALREADY EXIST!!!\n",__FUNCTION__,__LINE__);
		return SUCCESS_RETURN;
	}
	_kk_subDb_lock();
	sqlCmd = sqlite3_mprintf(insertCmd,ctx->subDevNum,isOnline,productType,productCode,deviceCode,fatherMac,version);	

	rc = sqlite3_exec(ctx->pDb, sqlCmd, NULL, NULL, &zErrMsg);
	if( rc != SQLITE_OK ){
	   ERROR_PRINT("SQL error: %s\n", zErrMsg);
	   sqlite3_free(zErrMsg);
	}else{
	   INFO_PRINT("sub device insert data successfully\n");
	}
	sqlite3_free(sqlCmd);
	ctx->subDevNum++;
	_kk_subDb_unlock();
	return SUCCESS_RETURN;
}
int kk_subDev_delete_byMac(char deviceCode[DEVICE_CODE_MAXLEN])
{
	const char *deleteCmd = "delete from SubDeviceInfo where deviceCode = %s;";
	char *sqlCmd = NULL;
	int rc = 0;
	char *zErrMsg = 0;
	kk_subDb_ctx_t *ctx = _kk_subDb_get_ctx();

	_kk_subDb_lock();
	 sqlCmd = sqlite3_mprintf(deleteCmd,deviceCode);	

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

int kk_subDev_update_online(int isOnline,const char *device_mac)
{
	char *sqlCmd = NULL;
	int len =0;
	int rc = 0;
	char *zErrMsg = 0;
	kk_subDb_ctx_t *ctx = _kk_subDb_get_ctx();

	_kk_subDb_lock();
	sqlCmd = sqlite3_mprintf("UPDATE SubDeviceInfo SET isOnline=%d  WHERE device_mac=%s",isOnline,device_mac);	
	INFO_PRINT("kk_subDev_update_online sqlCmd:%s\n",sqlCmd);
	rc = sqlite3_exec(ctx->pDb, sqlCmd, NULL, NULL, &zErrMsg);
	if( rc != SQLITE_OK ){
	   ERROR_PRINT("SQL error: %s\n", zErrMsg);
	   sqlite3_free(zErrMsg);
	}else{
	   INFO_PRINT("Table updata data successfully\n");
	}
    sqlite3_free(sqlCmd);
	_kk_subDb_unlock();
	return SUCCESS_RETURN;
}


