/**********************************************************************
 * INCLUDES
 */
#include "ikk-token.h"
#include "../../../../zigbee/zcl/zcl_include.h"
#include "ikk-common-utils.h"


extern addrExt_t g_Eui64GatewayAddr;

uint8_t Flash_Buffer_Data[USER_SIZE];

OPTTUNEL_TOKEN_ST sOptunnel_Token = {{1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6},{16,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26},{16,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46},{16,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66}};
/*********************************************************************
 * @fn      Get Gateway Addr
 *
 * @brief
 *
 * @param   None
 *
 * @return
 */
uint8_t* Gateway_IEEE_Addr_Get(void)
{
	nv_sts_t st = NV_SUCC;

	st = nv_flashReadNew(1, NV_MODULE_APP,  NV_GATEWAY_ADDR, sizeof(addrExt_t), (u8*)g_Eui64GatewayAddr);
	iKonkeAfSelfPrint("flashRead:::\r\n");
	DEBUG_ARRAY(1,g_Eui64GatewayAddr,sizeof(addrExt_t));
	if(st != NV_SUCC){
		memset(g_Eui64GatewayAddr,0xff,sizeof(addrExt_t));
	}
	return g_Eui64GatewayAddr;
}
/*********************************************************************
 * @fn      Save Gateway Addr
 *
 * @brief
 *
 * @param   None
 *
 * @return
 */
nv_sts_t Gateway_IEEE_Addr_Save(addrExt_t addr)
{
	nv_sts_t st = NV_SUCC;

	addrExt_t temp_addr;
	st = nv_flashReadNew(1, NV_MODULE_APP,  NV_GATEWAY_ADDR, sizeof(addrExt_t), (u8*)temp_addr);
	iKonkeAfSelfPrint("flashRead:::temp_addr\r\n");
	DEBUG_ARRAY(1,temp_addr,sizeof(addrExt_t));
	if(st == NV_SUCC){
		if(memcmp(temp_addr,addr,sizeof(addrExt_t)))
			st = nv_flashWriteNew(1, NV_MODULE_APP, NV_GATEWAY_ADDR, sizeof(addrExt_t), (u8*)addr);
	}else if(st == NV_ITEM_NOT_FOUND){
		st = nv_flashWriteNew(1, NV_MODULE_APP, NV_GATEWAY_ADDR, sizeof(addrExt_t), (u8*)addr);
	}
	iKonkeAfSelfPrint("Gateway_IEEE_Addr_Save result = %d\r\n",st);
	return st;
}
/*********************************************************************
 * @fn      Get MFG CODE
 *
 * @brief
 *
 * @param   None
 *
 * @return
 */
uint16_t MFG_Code_Get(void)
{
	nv_sts_t st = NV_SUCC;
	uint16_t mfg_code_temp;
	st = nv_flashReadNew(1, NV_MODULE_APP,  NV_MFG_CODE, sizeof(mfg_code_temp), (u8*)&mfg_code_temp);
	if(st != NV_SUCC){
		mfg_code_temp = 0;
	}
	return mfg_code_temp;
}
/*********************************************************************
 * @fn      Save mfg_code
 *
 * @brief
 *
 * @param   None
 *
 * @return
 */
nv_sts_t MFG_Code_Save(uint16_t mfgcode)
{
	nv_sts_t st = NV_SUCC;

	uint16_t mfg_code_temp;
	st = nv_flashReadNew(1, NV_MODULE_APP,  NV_MFG_CODE, sizeof(mfg_code_temp), (u8*)&mfg_code_temp);
	if(st == NV_SUCC){
		if(mfg_code_temp != mfgcode){
			st = nv_flashWriteNew(1, NV_MODULE_APP, NV_MFG_CODE, sizeof(uint16_t), (u8*)&mfgcode);
			iKonkeAfSelfPrint("MFG_CODE_Save result = %d\r\n",st);
		}
	}else if(st == NV_ITEM_NOT_FOUND){
		st = nv_flashWriteNew(1, NV_MODULE_APP, NV_MFG_CODE, sizeof(uint16_t), (u8*)&mfgcode);
	}

	return st;
}

bool kGetIndicatorNotDisturbModeFlg(void)
{
	nv_sts_t st = NV_SUCC;
	uint8_t temp;
	st = nv_flashReadNew(1, NV_MODULE_APP,  NV_NO_DISTURB_MODE, sizeof(temp), (u8*)&temp);
	if(st != NV_SUCC){
		temp = 0;
		//iKonkeAfSelfPrint("kGetIndicatorNotDisturbModeFlg failed!!\r\n");
	}
	//iKonkeAfSelfPrint("Read st =%d,data=%d\r\n",st,temp);

	return (temp == 1) ;
}

nv_sts_t kSetIndicatorNotDisturbModeFlg(uint8_t value)
{
	nv_sts_t st = NV_SUCC;
	uint8_t temp;
	st = nv_flashReadNew(1, NV_MODULE_APP,  NV_NO_DISTURB_MODE, sizeof(temp), (u8*)&temp);
	if(st == NV_SUCC){
		if(temp != value)
			st = nv_flashWriteNew(1, NV_MODULE_APP, NV_NO_DISTURB_MODE, sizeof(uint8_t), (u8*)&value);
	}else if(st == NV_ITEM_NOT_FOUND){
		st = nv_flashWriteNew(1, NV_MODULE_APP, NV_NO_DISTURB_MODE, sizeof(uint8_t), (u8*)&value);
	}
	if(st != NV_SUCC)
	{
		iKonkeAfSelfPrint("kSetIndicatorNotDisturbModeFlg failed!!\r\n");
	}

	return st;
}

bool kGetInterpanEnableFlg(void)
{
	nv_sts_t st = NV_SUCC;
	uint8_t temp;
	st = nv_flashReadNew(1, NV_MODULE_APP,  NV_INTERPAN_ENABLE_FLG, sizeof(temp), (u8*)&temp);
	if(st != NV_SUCC){
		temp = 1;
		iKonkeAfSelfPrint("kGetInterpanEnableFlg failed!!\r\n");
	}

	return (temp == 1) ;
}

nv_sts_t kSetInterpanEnableFlg(uint8_t value)
{
	nv_sts_t st = NV_SUCC;

	st = nv_flashWriteNew(1, NV_MODULE_APP, NV_INTERPAN_ENABLE_FLG, sizeof(uint8_t), (u8*)&value);
	if(st != NV_SUCC)
	{
		iKonkeAfSelfPrint("kSetIndicatorNotDisturbModeFlg failed!!\r\n");
	}

	return st;
}

uint16_t kNwkgetNodeIdFromFlash(void)
{
	nv_sts_t st = NV_SUCC;
	uint16_t temp;
	st = nv_flashReadNew(1, NV_MODULE_APP,  NV_NODE_ID_FLG, sizeof(temp), (u8*)&temp);
	if(st != NV_SUCC){
		temp = 0xFFFF;
	}
	return temp ;
}

nv_sts_t kNwksaveNodeIdToFlash(uint16_t node_id)
{
	nv_sts_t st = NV_SUCC;
	uint16_t temp;
	st = nv_flashReadNew(1, NV_MODULE_APP,  NV_NODE_ID_FLG, sizeof(temp), (u8*)&temp);
	if(st == NV_SUCC){
		if(temp != node_id){
			st = nv_flashWriteNew(1, NV_MODULE_APP, NV_NODE_ID_FLG, sizeof(uint16_t), (u8*)&node_id);
			iKonkeAfSelfPrint("NodeId_Save result = %d\r\n",st);
		}
	}else if(st == NV_ITEM_NOT_FOUND){
		st = nv_flashWriteNew(1, NV_MODULE_APP, NV_NODE_ID_FLG, sizeof(uint16_t), (u8*)&node_id);
	}

	return st;
}

void Flash_Test_Save(uint8_t value)
{
	uint8_t data = Flash_Test_Get();
	if(value != data)
	{
		flash_read(TOKEN_USER_LOCATION,USER_SIZE,Flash_Buffer_Data);
		iKonkeAfSelfPrintBuffer(Flash_Buffer_Data,USER_SIZE);
		iKonkeAfSelfPrint("Erase Sector!!\r\n");
		Flash_Buffer_Data[0] = value;
		flash_erase(TOKEN_USER_LOCATION);
		flash_write(TOKEN_USER_LOCATION,1,&value);
	}
}

uint8_t Flash_Test_Get(void)
{
	uint8_t value;
	flash_read(TOKEN_USER_LOCATION,1,&value);
	return value;
}

void Print_Flash_Data(void)
{
	flash_read(TOKEN_USER_LOCATION,USER_SIZE,(uint8_t*)&sOptunnel_Token);
	iKonkeAfSelfPrint("install code :\r\n");
	iKonkeAfSelfPrintBuffer(sOptunnel_Token.install_code.install_code_data,16);
	iKonkeAfSelfPrint("modeid :len = %d\r\n",sOptunnel_Token.modeid.modeid_len);
	iKonkeAfSelfPrintBuffer(sOptunnel_Token.modeid.modeid_data,32);
	iKonkeAfSelfPrint("cmei :len = %d\r\n",32);
	iKonkeAfSelfPrintBuffer(sOptunnel_Token.cmei.cmei_data,sOptunnel_Token.cmei.cmei_len);
	iKonkeAfSelfPrint("isn :len = %d\r\n",sOptunnel_Token.isn.isn_len);
	iKonkeAfSelfPrintBuffer(sOptunnel_Token.isn.isn_data,32);
	uint8_t addr[254] = {0};
	flash_read(CFG_MAC_ADDRESS,254,(uint8_t*)addr);
	iKonkeAfSelfPrint("mac data::::\r\n");
	iKonkeAfSelfPrintBuffer(addr,254);
}
uint8_t g_buffer[33] = {0};
uint8_t* General_Custom_Token_Get(uint8_t item)
{
	flash_read(TOKEN_USER_LOCATION,USER_SIZE,(uint8_t*)&sOptunnel_Token);
	switch(item)
	{
		case CUSTOM_ITEMS_INSTALL_CODE:
		{
			memcpy(g_buffer,sOptunnel_Token.install_code.install_code_data,16);
			break;
		}
		case CUSTOM_ITEMS_MODEL_ID:
		{
			if(sOptunnel_Token.modeid.modeid_len != 0xff)
				memcpy(g_buffer,(uint8_t*)&sOptunnel_Token.modeid,sOptunnel_Token.modeid.modeid_len+1);
			else{
				g_buffer[0] = 32;
				memset(g_buffer+1,0xff,32);
			}
			break;
		}
		case CUSTOM_ITEMS_CMEI_CODE:
		{
			if(sOptunnel_Token.cmei.cmei_len != 0xff)
				memcpy(g_buffer,(uint8_t*)&sOptunnel_Token.cmei,sOptunnel_Token.cmei.cmei_len+1);
			else{
				g_buffer[0] = 32;
				memset(g_buffer+1,0xff,32);
			}
			break;
		}
		case CUSTOM_ITEMS_ISN_CODE:
		{
			if(sOptunnel_Token.isn.isn_len != 0xff)
				memcpy(g_buffer,(uint8_t*)&sOptunnel_Token.isn,sOptunnel_Token.isn.isn_len+1);
			else{
				g_buffer[0] = 32;
				memset(g_buffer+1,0xff,32);
			}
			break;
		}
		default:
			break;
	}
	return g_buffer;
}
uint8_t General_Custom_Token_Save(uint8_t item,uint8_t *buff,uint8_t len)
{
	if((buff == NULL)||((len == 0)))
		return 0xff;
	if(len > 32)
		return 0xfe;
	OPTTUNEL_TOKEN_ST sOptunnel_Token_temp;
	uint8_t rewrite_flash  = 0;
	uint8_t valid_len = 0;
	iKonkeAfSelfPrint("will write data len =%d:\r\n",len);
	iKonkeAfSelfPrintBuffer(buff,len);
	flash_read(TOKEN_USER_LOCATION,USER_SIZE,(uint8_t*)&sOptunnel_Token_temp);
	switch(item)
	{
		case CUSTOM_ITEMS_INSTALL_CODE:
		{
			iKonkeAfSelfPrint("read install code:\r\n");
			iKonkeAfSelfPrintBuffer(sOptunnel_Token_temp.install_code.install_code_data,16);
			if(len >16)
				return 0xfe;
			if((!memcmp(sOptunnel_Token_temp.install_code.install_code_data,buff,len))
			   &&(All_Same_Data(&sOptunnel_Token_temp.install_code.install_code_data[len],0xff,16-len)))
			{
				//same data ,not need rewrite!
				return 0;
			}else if(All_Same_Data((uint8_t*)&sOptunnel_Token_temp.install_code.install_code_data,0xff,16)){
				flash_write(TOKEN_USER_LOCATION+INSTALL_CODE_LOC_OFFSET,len,buff);
				return 0;
			}else{
				memset(sOptunnel_Token_temp.install_code.install_code_data,0xff,16);
				memcpy(sOptunnel_Token_temp.install_code.install_code_data,buff,len);
				rewrite_flash = 1;
			}
			break;
		}
		case CUSTOM_ITEMS_MODEL_ID:
		{
			iKonkeAfSelfPrint("read modeid data len =%d:\r\n",sOptunnel_Token_temp.modeid.modeid_len);
			iKonkeAfSelfPrintBuffer(sOptunnel_Token_temp.modeid.modeid_data,32);
			valid_len = (sOptunnel_Token_temp.modeid.modeid_len > len)?sOptunnel_Token_temp.modeid.modeid_len :len;
			if((!memcmp(sOptunnel_Token_temp.modeid.modeid_data,buff,len))
				&&(All_Same_Data(&sOptunnel_Token_temp.modeid.modeid_data[len],0xff,32-len)))
			{
				//same data ,not need rewrite!
				return 0;
			}else if(All_Same_Data((uint8_t*)&sOptunnel_Token_temp.modeid,0xff,32)){
				//Auth: han_frc.20220105.
				u8 modelid_buff[35]={0};
				modelid_buff[0] = len;
				memcpy(modelid_buff+1,buff,len);
				flash_write(TOKEN_USER_LOCATION+MODEL_ID_LOC_OFFSET,len+1,modelid_buff);
				return 0;
			}else{
				sOptunnel_Token_temp.modeid.modeid_len  = len;
				memset(sOptunnel_Token_temp.modeid.modeid_data,0xff,valid_len);
				memcpy(sOptunnel_Token_temp.modeid.modeid_data,buff,len);
				rewrite_flash = 1;
			}
			break;
		}
		case CUSTOM_ITEMS_CMEI_CODE:
		{
			iKonkeAfSelfPrint("read cmei data len =%d:\r\n",sOptunnel_Token_temp.cmei.cmei_len);
			iKonkeAfSelfPrintBuffer(sOptunnel_Token_temp.cmei.cmei_data,32);
			valid_len = (sOptunnel_Token_temp.cmei.cmei_len > len)?sOptunnel_Token_temp.cmei.cmei_len :len;
			if((!memcmp(sOptunnel_Token_temp.cmei.cmei_data,buff,len))
				&&(All_Same_Data(&sOptunnel_Token_temp.cmei.cmei_data[len],0xff,32-len)))
			{
				//same data ,not need rewrite!
				return 0;
			}else if(All_Same_Data((uint8_t*)&sOptunnel_Token_temp.cmei,0xff,32)){
				//Auth: han_frc.20220105.
				u8 cmei_buff[35]={0};
				cmei_buff[0] = len;
				memcpy(cmei_buff+1,buff,len);
				flash_write(TOKEN_USER_LOCATION+CMEI_LOC_OFFSET,len+1,cmei_buff);
				return 0;
			}else{
				sOptunnel_Token_temp.cmei.cmei_len  = len;
				memset(sOptunnel_Token_temp.cmei.cmei_data,0xff,valid_len);
				memcpy(sOptunnel_Token_temp.cmei.cmei_data,buff,len);
				rewrite_flash = 1;
			}
			break;
		}
		case CUSTOM_ITEMS_ISN_CODE:
		{
			iKonkeAfSelfPrint("read isn data len =%d:\r\n",sOptunnel_Token_temp.isn.isn_len);
			iKonkeAfSelfPrintBuffer(sOptunnel_Token_temp.isn.isn_data,32);
			valid_len = (sOptunnel_Token_temp.isn.isn_len > len)?sOptunnel_Token_temp.isn.isn_len :len;
			if((!memcmp(sOptunnel_Token_temp.isn.isn_data,buff,len))
				&&(All_Same_Data(&sOptunnel_Token_temp.isn.isn_data[len],0xff,32-len)))
			{
				//same data ,not need rewrite!
				return 0;
			}else if(All_Same_Data((uint8_t*)&sOptunnel_Token_temp.isn,0xff,32)){
				//Auth: han_frc.20220105.
				u8 isn_buff[35]={0};
				isn_buff[0] = len;
				memcpy(isn_buff+1,buff,len);
				flash_write(TOKEN_USER_LOCATION+ISN_LOC_OFFSET,len+1,isn_buff);
				return 0;
			}else{
				sOptunnel_Token_temp.isn.isn_len  = len;
				memset(sOptunnel_Token_temp.isn.isn_data,0xff,valid_len);
				memcpy(sOptunnel_Token_temp.isn.isn_data,buff,len);
				rewrite_flash = 1;
			}
			break;
		}
		default:
			break;
	}
	if(rewrite_flash){
		flash_erase(TOKEN_USER_LOCATION);
		flash_write(TOKEN_USER_LOCATION,USER_SIZE,(uint8_t*)&sOptunnel_Token_temp);
		Print_Flash_Data();
		return 0;
	}
	return 0xfd;
}



void falsh_test(uint8_t count)
{

//	uint8_t install_code1[] = {1,2,3,4,5,6,7,8,9,0x0a};
//	uint8_t install_code2[] = {1,2,3,4,5,6,7,8,9,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10};
//	if(count%2)
//		General_Custom_Token_Save(CUSTOM_ITEMS_INSTALL_CODE,install_code1,sizeof(install_code1));
//	else
//		General_Custom_Token_Save(CUSTOM_ITEMS_INSTALL_CODE,install_code2,sizeof(install_code2));
//	uint8_t *p = MODEL_ID_TOKEN_GET();
	Print_Flash_Data();
//	iKonkeAfSelfPrint("len =%d:\r\n",p[0]);
//	iKonkeAfSelfPrintBuffer(p+1,32);
}


