#include "app_ota.h"
#include "nrf_gpio.h"
#include "usr_config.h"
#include "bsp_time.h"
#include "system.h"
#include "hal_mt.h"
#include "app_host.h"
#include "app_charge.h"
#include "hal_ble_client.h"
#include "hal_ble_host.h"
#include "nrf_delay.h"
#include "app_flash.h"
#include "ble_comm.h"
#include "exception.h"
#include "hal_led.h"

static uint32_t isOTA=0;
static uint8_t  isHostOTA=0;
static volatile uint8_t m_ready_for_reset = 0;
static uint8_t ResRightFlag = 0; 

static bool app_shutdown_handler(nrf_pwr_mgmt_evt_t event)
{
    switch (event){
        case NRF_PWR_MGMT_EVT_PREPARE_DFU:
					   switch(m_ready_for_reset){
							  case 0:m_ready_for_reset =1;return false;
							  case 1:return false;
							  default: break;
			       }
            break;
        default:return true;
    }
    DEBUG_LOG("Into bootloader\n");
    return true;
}

static void app_ota_clear_flash(void)
{
	if(1 == m_ready_for_reset){
		LED_Close_Enforce();
		if(Flash_SaveStep() != ZONE_OP_SUCCESS)Except_TxError(EXCEPT_DFU,"ota save step fail");
			
		extern battercb_t battery_record;
		extern void printbatter_cb(battercb_t *c,battercb_t *C_flash);
		
		memcpy(&mFlash.mbattercb_t,&battery_record,sizeof(battercb_t));
		printbatter_cb(&battery_record,&mFlash.mbattercb_t);
		mBackup.RestartCnt =0;	
		if(Flash_SaveInfomation() != ZONE_OP_SUCCESS)Except_TxError(EXCEPT_DFU,"ota save information fail");
		
		if(Flash_SaveBackup() != ZONE_OP_SUCCESS)Except_TxError(EXCEPT_DFU,"ota save back fail");
		
		DEBUG_LOG("------>save flash\n");
		m_ready_for_reset =2;
	}
	else if(2 == m_ready_for_reset){
		nrf_pwr_mgmt_shutdown(NRF_PWR_MGMT_SHUTDOWN_CONTINUE);
	} 
}

NRF_PWR_MGMT_HANDLER_REGISTER(app_shutdown_handler, 0);

static void app_ota_Process(void)
{
	static uint8_t state = 0;
	char buf[16];

	uint8_t responhost =0;
	switch(state){
		case 0:{
			if(mFlash.isHost > 0){//左鞋
				 if(1 == isHostOTA){
					 DEBUG_LOG("------>isHostOTA\n");
					 state = 1;
					 host_disconnect();
					 nrf_ble_scan_stop();
					 Process_UpdatePeroid(app_ota_Process,10000);
					 BLE_Client_Tx_Send(0,BLE_DFU,&responhost,1);
				 }
			}
			else{
					if(1== isOTA && 1 == ResRightFlag){ isOTA = 0;ResRightFlag =0;
						if(slave_isconnect()) slave_disconnect();
						else advertising_stop();
						uint8_t mymac[6];
		        Get_MACaddr(mymac);
						
						memset(buf,0,16);
						sprintf(buf,"SH_%02X%02X%02X%02X%02X%02X",mymac[0],mymac[1],mymac[2],mymac[3],mymac[4],mymac[5]);
						DEBUG_LOG("OTA name(%d):%s\n",strlen(buf),buf);
						slave_set_adv_name(buf,strlen(buf));
						slave_adv_init();
						state = 1;
						Process_UpdatePeroid(app_ota_Process,2000);
					}
			}
			break;}
		case 1:{
			if(mFlash.isHost > 0){//左鞋
				isHostOTA =0;
				state =0;
				DEBUG_LOG("------>left out to dfu\n");
			}
			else{
				if(slave_isconnect()==0){
					DEBUG_LOG("app_ota_Process advertising_start\r\n");
					advertising_start();
					Process_UpdatePeroid(app_ota_Process,10000);
					state = 2;
				}
				else slave_disconnect();
			}
			break;}
		case 2:{
			if(slave_isconnect()) state = 0;
			Process_UpdatePeroid(app_ota_Process,0);
			advertising_stop();
			memset(buf,0,16);
			
			#if BleNameHoldOn_ENANBLE 
			slave_set_adv_name((char *)RIGHT_NAME,sizeof(RIGHT_NAME));
			DEBUG_LOG("AdvName(%d):%s\n",sizeof(RIGHT_NAME),RIGHT_NAME);
		  #else
			sprintf(buf,"%02X%02X%02X%02X%02X%02X",mFlash.mClient.macAddr[0],mFlash.mClient.macAddr[1],mFlash.mClient.macAddr[2],mFlash.macHost[3],mFlash.macHost[4],mFlash.macHost[5]);
			
			DEBUG_LOG("ADV name(%d):%s\n",strlen(buf),buf);
			slave_set_adv_name(buf,strlen(buf));
			#endif
			
			Except_TxError(EXCEPT_DFU,"adv disconnted over time");
			slave_adv_init();
			advertising_start();
			state = 0;
			break;}
		 default:state = 0;Process_UpdatePeroid(app_ota_Process,0);break;
	}
	
	
}

/*********************** 接收从机命令 ************************/
void cb_BLE_Host_R_DFU(void* handle)
{
  uint8_t left_dfu_state =0;
	BLE_Host_Rx_t* target = handle;
	left_dfu_state = target->pDat[0];
	
	BLE_Client_Tx_Send(0,BLE_DFU,&left_dfu_state,1);
}

static void cb_Client_BLE_DFU(void* handle)
{
   Process_SetHoldOn(app_ota_Process,0);
	 ResRightFlag =1;
}

static BLE_Client_Tx_t m_Client_BLE_DFU = {
	.n = 15,
	.t = 200,
	.cb = cb_Client_BLE_DFU,
};

/*********************** 接收手机命令 ************************/
void cb_BLE_Client_R_DFU(void* handle)
{
	  DEBUG_LOG(">>>>>>>>>>BLE_Client_R_DFU\n");
		BLE_Client_Rx_t* target = handle;
		if(mFlash.isHost>0){
			 if(target->pDat[0] == 0){isHostOTA = 1;
				  return; //左鞋不需要理会
			 }
			 else if(target->pDat[0] == 1){
				  BLE_Host_Tx_Send(0,BLE_DFU,target->pDat,1);	//发给从机
			 }
		}
		else {
			static uint8_t responhost =1;
			BLE_Client_Tx_Send(&m_Client_BLE_DFU,BLE_DFU,&responhost,1);
			isOTA = 1;
			Process_SetHoldOn(app_ota_Process,1);
		  DEBUG_LOG(">>>>>>>>>>DFU start....\n");
		}
}

uint8_t app_ota_host_state(void)
{
	  return isHostOTA;
}

#if BleNameHoldOn_ENANBLE
extern uint8_t SaveFlashFlag_holdOn;
static void app_ota_SaveFlash(void){
	if(1 ==SaveFlashFlag_holdOn ){
		 SaveFlashFlag_holdOn =0;
		 if(Flash_SaveInfomation() != ZONE_OP_SUCCESS)Except_TxError(EXCEPT_DFU,"save information fail");
		 uint8_t i =0;
		 DEBUG_LOG("mac host addr:");for(i=0;i<RecordMacAddrL;i++){DEBUG_LOG("%02X ",mFlash.macHost[i]);}DEBUG_LOG("\n");
		 DEBUG_LOG("mClient addr:");for(i=0;i<RecordMacAddrL;i++){DEBUG_LOG("%02X ",mFlash.mClient.macAddr[i]);}DEBUG_LOG("\n");
	}
}
#endif


void app_ota_Init(void)
{
	Process_Start(0,"ota",app_ota_Process);
	BLE_Client_Rx_Regist(BLE_DFU,cb_BLE_Client_R_DFU);
  BLE_Host_Rx_Regist(BLE_DFU,cb_BLE_Host_R_DFU);
	Process_Start(500,"ota_flash",app_ota_clear_flash);
	
	#if BleNameHoldOn_ENANBLE
	uint8_t mymac[RecordMacAddrL]={0};
	memset(mymac,0,sizeof(mymac));
	Get_MACaddr(mymac);
	DEBUG_LOG("mac addr:");for(int i=0;i<6;i++){DEBUG_LOG("%02X ",mymac[i]);}DEBUG_LOG("\n");
	uint8_t i=0;
	for(i=0;i<RecordMacAddrL;i++)if(mFlash.macHost[i] !=0xff)break;
	if(RecordMacAddrL ==i){
		 for(uint8_t a=0;a<RecordMacAddrL;a++){
			   mFlash.macHost[a] = mymac[a];
		 }
		 SaveFlashFlag_holdOn =1;
	}
	
	Process_Start(1000,"app_ota_SaveFlash",app_ota_SaveFlash);
	#endif
	
	
}


