/************************************************************
*版权所有 （C）2020，公司（或个人）名称
*
*文件名称： kk_history_db.c
*内容摘要：窗帘面板绑定窗帘电机模块
*其他说明： 
*当前版本：  
*************************************************************/
 
/*************************************************************
头文件引用 
*************************************************************/
	
#include <stdio.h>
#include "kk_tsl_api.h"
#include "sqlite3.h"
#include "kk_log.h"
#include "kk_hal.h"
#include "kk_motor_bind_db.h"
#include "kk_dm_mng.h"

 /*************************************************************
全局变量定义 
*************************************************************/
extern sqlite3 *g_kk_pDb;
/*************************************************************
函数实现 
*************************************************************/
typedef struct {
	void *mutex;
	sqlite3 *pDb;
} kk_motor_bind_ctx_t;

static kk_motor_bind_ctx_t s_kk_motor_bind_ctx = {NULL};
kk_motor_bind_ctx_t *_kk_motor_bind_get_ctx(void)
{
	return &s_kk_motor_bind_ctx;
}
void _kk_motor_bind_lock(void)
{
	kk_motor_bind_ctx_t *ctx = _kk_motor_bind_get_ctx();
	if (ctx->mutex) {
		HAL_MutexLock(ctx->mutex);
	}
}

void _kk_motor_bind_unlock(void)
{
	kk_motor_bind_ctx_t *ctx = _kk_motor_bind_get_ctx();

	if (ctx->mutex) {
		HAL_MutexUnlock(ctx->mutex);
	}
}

/************************************************************
*功能描述： 历史记录数据库初始化
*输入参数： 无
*输出参数： 无
*返 回 值：  0：成功；其他：失败
*其他说明：
*************************************************************/
int kk_motor_bind_db_init(void)
{
	kk_motor_bind_ctx_t *ctx = _kk_motor_bind_get_ctx();
	char *pcErr;

	ctx->pDb = g_kk_pDb;

	INFO_PRINT("kk_motor_bind db Database opened\n");
	
	/* Create Mutex */
	ctx->mutex = HAL_MutexCreate();
	if (ctx->mutex == NULL) {
		return FAIL_RETURN;
	}
	_kk_motor_bind_lock();	
	const char *pPanelBindMotor = "CREATE TABLE IF NOT EXISTS PanelBindMotor( \
		panelDCode varchar(255), \
		panelEpNum INTEGER, \
		motorDCode varchar(255), \
		motorEpNum INTEGER, \
		dummyId INTEGER)";

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

	_kk_motor_bind_unlock();
	return SUCCESS_RETURN;
}



static int kk_motor_bind_db_check(const char* panelDCode,int panelEpNum,const char* motorDCode,int motorEpNum)
{
	int isExist = 0;
	sqlite3_stmt *stmt;
	const unsigned char *panelDeviceCode = NULL;
	const unsigned char *motorDeviceCode = NULL;
	int panel_ep = 0;
	int motor_ep = 0;
	kk_motor_bind_ctx_t *ctx = _kk_motor_bind_get_ctx();

	const char *searchCmd = "select * from PanelBindMotor;";	
	_kk_motor_bind_lock();
	sqlite3_prepare_v2(ctx->pDb, searchCmd, strlen(searchCmd), &stmt, NULL);

	while(sqlite3_step(stmt) == SQLITE_ROW){
		panelDeviceCode = sqlite3_column_text(stmt, MOTOR_BIND_DB_PANEL_DEVICECODE);
		panel_ep = sqlite3_column_int(stmt, MOTOR_BIND_DB_PANEL_EP);
		motorDeviceCode = sqlite3_column_text(stmt, MOTOR_BIND_DB_PANEL_DEVICECODE);
		motor_ep = sqlite3_column_int(stmt, MOTOR_BIND_DB_MOTOR_EP);

		if(!strcmp(panelDCode,(const char *)panelDeviceCode) && 
			!strcmp(motorDCode,(const char *)motorDeviceCode) && 
			panel_ep==panelEpNum &&motor_ep==motorEpNum)
		{
			isExist = 1;
			break;
		}
	}

	sqlite3_finalize(stmt);
	_kk_motor_bind_unlock();
	return isExist;
}


int kk_motor_bind_db_insert(const char* panelDCode,int panelEpNum,const char* motorDCode,int motorEpNum,int dummyId)
{
	int res = 0;
	kk_motor_bind_ctx_t *ctx = _kk_motor_bind_get_ctx();
	char *sqlCmd = NULL;
	char *zErrMsg = 0;
	sqlite3_stmt *stmt;
	time_t rtime = 0;
	int count = 0;

	const char *insertCmd = "insert into PanelBindMotor (panelDCode, panelEpNum,motorDCode,motorEpNum,dummyId) \
								values ('%s','%d','%s','%d','%d');";	

	if(kk_motor_bind_db_check(panelDCode,panelEpNum,motorDCode,motorEpNum)){
		INFO_PRINT("already exist.--->panelDCode:%s,panelEpNum:%d,motorDCode:%s,motorEpNum=%d\n",panelDCode,panelEpNum,motorDCode,motorEpNum);
		return SUCCESS_RETURN;
	}

	INFO_PRINT("kk_motor_bind_db_insert,panelDCode:%s,panelEpNum:%d,motorDCode:%s,motorEpNum=%d,dummyId=%d\n",panelDCode,panelEpNum,motorDCode,motorEpNum,dummyId);
	_kk_motor_bind_lock();
	sqlCmd = sqlite3_mprintf(insertCmd,panelDCode,panelEpNum,motorDCode,motorEpNum,dummyId);	
	res = sqlite3_exec(ctx->pDb, sqlCmd, NULL, NULL, &zErrMsg);
	if( res != SQLITE_OK ){
		ERROR_PRINT("SQL error: %s\n", zErrMsg);
		sqlite3_free(zErrMsg);
		sqlite3_free(sqlCmd);
		_kk_motor_bind_unlock();	
		return FAIL_RETURN;
	}
	sqlite3_free(sqlCmd);

	
	_kk_motor_bind_unlock();
	return SUCCESS_RETURN;
}

int kk_motor_bind_db_delete(const char* panelDCode,int panelEpNum,const char* motorDCode,int motorEpNum)
{
	const char *deleteCmd = "delete from PanelBindMotor where panelDCode = '%s' and panelEpNum = '%d' and motorDCode = '%s' and motorEpNum = '%d' ;";
	char *sqlCmd = NULL;
	int rc = 0;
	char *zErrMsg = 0;
	kk_motor_bind_ctx_t *ctx = _kk_motor_bind_get_ctx();

	_kk_motor_bind_lock();
	sqlCmd = sqlite3_mprintf(deleteCmd,panelDCode,panelEpNum,motorDCode,motorEpNum);

	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_motor_bind_unlock();
	return SUCCESS_RETURN;
}

int kk_motor_bind_db_delete_ex(const char* panelDCode)
{
	const char *deleteCmd = "delete from PanelBindMotor where panelDCode = '%s' ;";
	char *sqlCmd = NULL;
	int rc = 0;
	char *zErrMsg = 0;
	kk_motor_bind_ctx_t *ctx = _kk_motor_bind_get_ctx();

	_kk_motor_bind_lock();
	sqlCmd = sqlite3_mprintf(deleteCmd,panelDCode);

	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_motor_bind_unlock();
	return SUCCESS_RETURN;
}

int kk_motor_bind_db_find_byDeviceCode(const char* panelDCode,struct kk_motor_bind_info* info,int max)
{
	int listSize = 0;
	sqlite3_stmt *stmt;
	char *sqlCmd = NULL;
	char *motorDeviceCode = NULL;
	int motor_ep = 0;
	int dummyId = -1;

	struct kk_motor_bind_info* pInfo = info;
	kk_motor_bind_ctx_t *ctx = _kk_motor_bind_get_ctx();
	const char *searchCmd = "select * from PanelBindMotor where panelDCode = '%s';";	
	_kk_motor_bind_lock();
	sqlCmd = sqlite3_mprintf(searchCmd,panelDCode);
	INFO_PRINT("Table searchCmd:%s\n",sqlCmd);
	sqlite3_prepare_v2(ctx->pDb, sqlCmd, strlen(sqlCmd), &stmt, NULL);
	while(sqlite3_step(stmt) == SQLITE_ROW){
		motorDeviceCode = (char*)sqlite3_column_text(stmt, MOTOR_BIND_DB_MOTOR_DEVICECODE);
		motor_ep = sqlite3_column_int(stmt, MOTOR_BIND_DB_MOTOR_EP);
		dummyId = sqlite3_column_int(stmt, MOTOR_BIND_DB_DUMMYID);
		memcpy(pInfo->deviceCode,motorDeviceCode,strlen(motorDeviceCode));
		pInfo->epNum = motor_ep;
		pInfo->dummyId = dummyId;
		INFO_PRINT("listSize=%d,motorDeviceCode=%s,motor_ep=%d,dummyId=%d\n",listSize,motorDeviceCode,motor_ep,dummyId);
		if(++listSize>=max){
			break;
		}
		pInfo++;
	}

	sqlite3_finalize(stmt);
	sqlite3_free(sqlCmd);
	_kk_motor_bind_unlock();
	return listSize;
}
int kk_motor_bind_db_find_byMotorDeviceCode(const char* motorCode,struct kk_motor_bind_info* info,int max)
{
	int listSize = 0;
	sqlite3_stmt *stmt;
	char *sqlCmd = NULL;
	char *panelDeviceCode = NULL;
	int motor_ep = 0;
	int dummyId = -1;

	struct kk_motor_bind_info* pInfo = info;
	kk_motor_bind_ctx_t *ctx = _kk_motor_bind_get_ctx();
	const char *searchCmd = "select * from PanelBindMotor where motorDCode = '%s';";	
	_kk_motor_bind_lock();
	sqlCmd = sqlite3_mprintf(searchCmd,motorCode);
	INFO_PRINT("Table searchCmd:%s\n",sqlCmd);
	sqlite3_prepare_v2(ctx->pDb, sqlCmd, strlen(sqlCmd), &stmt, NULL);
	

	while(sqlite3_step(stmt) == SQLITE_ROW){
		panelDeviceCode = (char *)sqlite3_column_text(stmt, MOTOR_BIND_DB_PANEL_DEVICECODE);
		motor_ep = sqlite3_column_int(stmt, MOTOR_BIND_DB_MOTOR_EP);
		dummyId = sqlite3_column_int(stmt, MOTOR_BIND_DB_DUMMYID);
		memcpy(pInfo->deviceCode,panelDeviceCode,strlen(panelDeviceCode));
		pInfo->epNum = motor_ep;
		pInfo->dummyId = dummyId;
		INFO_PRINT("listSize=%d,panelDeviceCode=%s,motor_ep=%d,dummyId=%d\n",listSize,panelDeviceCode,motor_ep,dummyId);
		if(++listSize>=max){
			break;
		}
		pInfo++;
	}
	sqlite3_free(sqlCmd);
	sqlite3_finalize(stmt);
	_kk_motor_bind_unlock();
	return listSize;
}
int kk_motor_bind_db_find(const char* panelDCode,int panelEpNum,struct kk_motor_bind_info* info,int max)
{
	int listSize = 0;
	sqlite3_stmt *stmt;
	char *sqlCmd = NULL;
	char *motorDeviceCode = NULL;
	int motor_ep = 0;
	int dummyId = -1;

	struct kk_motor_bind_info* pInfo = info;
	kk_motor_bind_ctx_t *ctx = _kk_motor_bind_get_ctx();

	const char *searchCmd = "select * from PanelBindMotor where panelDCode = '%s' and panelEpNum = '%d' ;";	
	_kk_motor_bind_lock();
	sqlCmd = sqlite3_mprintf(searchCmd,panelDCode,panelEpNum);
	INFO_PRINT("Table searchCmd:%s\n",sqlCmd);
	sqlite3_prepare_v2(ctx->pDb, sqlCmd, strlen(sqlCmd), &stmt, NULL);

	while(sqlite3_step(stmt) == SQLITE_ROW){
		motorDeviceCode = (char *)sqlite3_column_text(stmt, MOTOR_BIND_DB_MOTOR_DEVICECODE);
		motor_ep = sqlite3_column_int(stmt, MOTOR_BIND_DB_MOTOR_EP);
		dummyId = sqlite3_column_int(stmt, MOTOR_BIND_DB_DUMMYID);
		memcpy(pInfo->deviceCode,motorDeviceCode,strlen(motorDeviceCode));
		pInfo->epNum = motor_ep;
		pInfo->dummyId = dummyId;
		INFO_PRINT("listSize=%d,motorDeviceCode=%s,motor_ep=%d,dummyId=%d\n",listSize,motorDeviceCode,motor_ep,dummyId);

		if(++listSize>=max){
			break;
		}
		pInfo++;
	}
	sqlite3_free(sqlCmd);
	sqlite3_finalize(stmt);
	_kk_motor_bind_unlock();
	return listSize;
}


int kk_motor_bind_db_find_ex(int dummyId,struct kk_motor_bind_info* info,int max)
{
	int listSize = 0;
	sqlite3_stmt *stmt;
	char *sqlCmd = NULL;
	char *motorDeviceCode = NULL;
	int motor_ep = 0;

	struct kk_motor_bind_info* pInfo = info;
	kk_motor_bind_ctx_t *ctx = _kk_motor_bind_get_ctx();

	const char *searchCmd = "select * from PanelBindMotor where dummyId = '%d' ;";	
	_kk_motor_bind_lock();
	sqlCmd = sqlite3_mprintf(searchCmd,dummyId);
	INFO_PRINT("Table searchCmd:%s\n",sqlCmd);
	sqlite3_prepare_v2(ctx->pDb, sqlCmd, strlen(sqlCmd), &stmt, NULL);
	

	while(sqlite3_step(stmt) == SQLITE_ROW){	
		motorDeviceCode = (char *)sqlite3_column_text(stmt, MOTOR_BIND_DB_MOTOR_DEVICECODE);
		motor_ep = sqlite3_column_int(stmt, MOTOR_BIND_DB_MOTOR_EP);
		memcpy(pInfo->deviceCode,motorDeviceCode,strlen(motorDeviceCode));
		pInfo->epNum = motor_ep;
		INFO_PRINT("listSize=%d,motorDeviceCode=%s,motor_ep=%d\n",listSize,motorDeviceCode,motor_ep);

		if(++listSize>=max){
			break;
		}
		pInfo++;
	}
	sqlite3_free(sqlCmd);
	sqlite3_finalize(stmt);
	_kk_motor_bind_unlock();
	return listSize;
}

int kk_motor_bind_db_find_dummyId(const char* panelDCode,int panelEpNum,const char* motorDCode,int motorEpNum)
{
	sqlite3_stmt *stmt;
	char *sqlCmd = NULL;

	int dummyId = -1;

	kk_motor_bind_ctx_t *ctx = _kk_motor_bind_get_ctx();

	const char *searchCmd = "select * from PanelBindMotor where panelDCode = '%s' and panelEpNum = '%d' and motorDCode = '%s' and motorEpNum = '%d' "; 

	_kk_motor_bind_lock();
	sqlCmd = sqlite3_mprintf(searchCmd,panelDCode,panelEpNum,motorDCode,motorEpNum);
	INFO_PRINT("Table searchCmd:%s\n",sqlCmd);
	sqlite3_prepare_v2(ctx->pDb, sqlCmd, strlen(sqlCmd), &stmt, NULL);
	

	while(sqlite3_step(stmt) == SQLITE_ROW){
		dummyId = sqlite3_column_int(stmt, MOTOR_BIND_DB_DUMMYID);
		INFO_PRINT("dummyId=%d\n",dummyId);
	}
	sqlite3_free(sqlCmd);
	sqlite3_finalize(stmt);
	_kk_motor_bind_unlock();
	return dummyId;
}


extern int kk_service_delete_bind_2gw(char *deviceCode,int type);//type 0:panel;1:motor
int kk_motor_bind_db_delete_by_deviceCode(const char* deviceCode)
{
	const char *deleteCmd = "delete from PanelBindMotor where motorDCode = '%s' ;";
	char *sqlCmd = NULL;
	int rc = 0;
	char *zErrMsg = 0;
	kk_motor_bind_ctx_t *ctx = _kk_motor_bind_get_ctx();
	//printf("---------------------------->[%s][%d]\n",__FUNCTION__,__LINE__);
	kk_service_delete_bind_2gw((char*)deviceCode,1);
	_kk_motor_bind_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_motor_bind_unlock();
	//printf("---------------------------->[%s][%d]\n",__FUNCTION__,__LINE__);
	kk_service_delete_bind_2gw((char*)deviceCode,0);
	kk_motor_bind_db_delete_ex(deviceCode);
	
	return SUCCESS_RETURN;
}





