/**
 * @file comms_uhf_tmr.c
 *
 * @brief This file has the UHF driver FSM implemenation and the relevant functions
 *
 * @copyright Copyright 2023 Antaris, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */
/*********************************************************************/

#include "comms_uhf_tmr.h"
#include "comms_uhf_intf.h"
#include "sdr_app_main.h"
#include "exo_common.h"
#include "comms_uhf_ipc.h"
#include "exo_io_al_sos_timer.h"
#include "comms_uhf_init.h"
#include "exo_tctm_ipc.h"
#include "logger.h"
#include "err_handler.h"


extern s_sdr_tmr_cfg PLACE_IN_EXT_RAM_MEM uhf_tmr_cfg;
uint32_t  uhf_rep_cnt = 0;
uint8_t	  uhf_cmd_rsp_cnt = 0;

/** Flag denotes the scheduler based ground pass window status */
extern uint8_t PLACE_IN_EXT_RAM_MEM uhf_sch_gs_contact ;
extern s_sdr_gpass_beacon_cfg uhf_gpass_cfg;



extern uint8_t PLACE_IN_EXT_RAM_MEM comms_uhf_otsu_gs_contact;
extern uint8_t PLACE_IN_EXT_RAM_MEM comms_uhf_first_gs_contact ;

/** Timer used for tm store Periodicity Timer */
os_timer_handle_ptr uhf_tm_periodic_read;

/** Timer used for periodic transmission of Beacon signal */
os_timer_handle_ptr uhf_beacon_timer;

/** Timer used for enable transmission of Beacon signal */
os_timer_handle_ptr uhf_beacon_enb_timer;

/** Timer used for enable repition of Beacon signal */
os_timer_handle_ptr uhf_beacon_rep_timer;

/** Timer used for transmit ON duration */
os_timer_handle_ptr uhf_tx_tm_on;

/** UHF CMD trigger timer */
os_timer_handle_ptr uhf_cmd_wait_timer;

extern uint8_t PLACE_IN_EXT_RAM_MEM beacon_en;
os_timer_handle_ptr uhf_cmd_timeout;
os_timer_handle_ptr uhf_rsp_timeout_recovery_tmr;

/**
 * @brief Initialize UHF communication timers
 * 
 * This function initializes the timers required for UHF communication.
 * 
 * @return Result of timer initialization (0 = success)
 */
int8_t comms_uhf_timer_init(void)
{
    uint64_t time_diff = 0, epoch_time = 0;
    time_diff=time_diff;
    epoch_time=epoch_time;


    /** Timer creation for Beacon enable and periodic beacon transmission **/
    os_timer_create(&uhf_beacon_timer ,"uhf_beacon_timer",ONESHOT,(ral_timer_cbfunc_t)uhf_beacon_timer_exp_cb,NULL);

    /** Timer creation for Beacon enable and periodic beacon transmission **/
    os_timer_create(&uhf_beacon_rep_timer ,"uhf_beacon_rep_timer",ONESHOT,(ral_timer_cbfunc_t)uhf_beacon_rep_timer_cb,NULL);

    /** Timer creation for Beacon enable and periodic beacon transmission **/
    os_timer_create(&uhf_beacon_enb_timer ,"uhf_beacon_enb_timer",ONESHOT,(ral_timer_cbfunc_t)uhf_beacon_enb_timer_cb,NULL);

    /** Timer creation for UHF Periodic read of telemetry or house keeping information for RSSI tracking and TM storage */
    os_timer_create(&uhf_tm_periodic_read ,"uhf_tm_periodic_read",ONESHOT,(ral_timer_cbfunc_t)uhf_tm_periodic_read_cb,NULL);

    /** Timer creation for UHF stored TM transmission duration, upon expire, the received TM gets to storage mode*/
    os_timer_create(&uhf_tx_tm_on,"uhf_tx_tm_on",ONESHOT,(ral_timer_cbfunc_t)uhf_tx_tm_on_cb,NULL);

    /** Timer creation for UHF stored TM transmission duration, upon expire, the received TM gets to storage mode*/
    os_timer_create(&uhf_cmd_timeout,"uhf_cmd_timeout",ONESHOT,(ral_timer_cbfunc_t)uhf_cmd_timeout_cb,NULL);
    
    /** Timer creation for UHF cmd response recovery handling */
    os_timer_create(&uhf_rsp_timeout_recovery_tmr,"uhf_rsp_timeout_recovery_tmr",ONESHOT,(ral_timer_cbfunc_t)uhf_rsp_timeout_recovery_cb,NULL);
    
    /** Timer creation for UHF command trigger */
    os_timer_create(&uhf_cmd_wait_timer,"uhf_cmd_wait_timer",ONESHOT,(ral_timer_cbfunc_t)uhf_cmd_wait_tmr_exp_cb,NULL);
    /*
#if 0

    //if((!comms_uhf_first_gs_contact)&&(!comms_uhf_otsu_gs_contact))
    if(beacon_en)
    {
    time_diff = get_crnt_time_date_in_epoch();

    epoch_time = uhf_permanant_timer_read();

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wformat"
DEBUG_CPRINT(("UHF current time:%llu",time_diff));

time_1sthalf = time_diff & 0xFFFFFFFF;
time_2ndhalf |= time_diff >> 32;

log_id_with_one_arg(LOG_INFO_L2,LOG_COMMS,UHF_CURRENT_TIME_u32_,time_1sthalf);
log_id_with_one_arg(LOG_INFO_L2,LOG_COMMS,UHF_CURRENT_TIME_u32_,time_2sthalf);
#pragma GCC diagnostic pop
time_diff = time_diff - epoch_time;
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wformat"
DEBUG_CPRINT(("UHF time diff: %llu, epoch: %llu, current time:%llu",time_diff,epoch_time,time_diff));
#pragma GCC diagnostic pop

if(time_diff < (uhf_tmr_cfg.beacon_enb_tmr>>1))
{
os_timer_start(uhf_beacon_timer,uhf_tmr_cfg.beacon_enb_tmr);
DEBUG_CPRINT(("UHF timer started for 60 mins"));
log_id(LOG_INFO_L1,LOG_COMMS,UHF_TIMER_STARTED_FOR_60_MINS);
}
else
{
os_timer_start(uhf_beacon_timer,uhf_tmr_cfg.beacon_prd_tmr);
DEBUG_CPRINT(("UHF timer started for 4 mins"));
log_id(LOG_INFO_L1,LOG_COMMS,SBAND_TIMER_STARTED_FOR_4_MINS);
}
}
else
{
os_timer_start(uhf_beacon_enb_timer,uhf_tmr_cfg.beacon_enb_tmr);
}
#endif
*/
    //    #ifdef UHF_BEACON_ENB

    os_timer_start(uhf_beacon_enb_timer,uhf_tmr_cfg.beacon_enb_tmr);
    //    #endif

    return 0;
    }

/**
 * @brief call back function at short duration expiry
 * pass fsm state via IPC
 *
 * Callback function for UHF RX on timer expiration
 * 
 * This function is called when the timer for UHF RX expires.
 * It would likely handle stopping UHF RX and any associated cleanup.
 */
void uhf_rx_on_timer_cb(void)
{
    //uhf_send_ipc(UHF_RX_ON_TIMER_EXP,COMMS_UHF_CTLR);
}


/**
 * @brief Callback function for UHF command timeout  
 * 
 * This function is called when a UHF command times out before
 * receiving a response. It would handle any failure processing
 * like retransmitting the command.
 */
void uhf_cmd_timeout_cb(void)
{
    uint8_t tim_out_cnt = 3;

    if (uhf_cmd_rsp_cnt < tim_out_cnt)
    {
        //	uhf_send_ipc(UHF_UART_CMD_RSP_TIMEOUT,COMMS_UHF_CTLR);
        DEBUG_CPRINT(("\n\r TIME EXP - UPD IND "));
        uhf_cmd_rsp_cnt++;
    }
    else if (uhf_cmd_rsp_cnt >= tim_out_cnt)
    {
#if 0
        uint32_t eps_req[2];

        uhf_cmd_rsp_cnt = 0;
        eps_req[0] = HW_UHF;
        eps_req[1] = PWR_RSTRT;

        //os_timer_stop(uhf_cmd_timeout);
        DEBUG_CPRINT(("\nUHF CMD FAIL - RESTART_COMMENCED\n %d", uhf_cmd_rsp_cnt));
        //		uhf_send_ipc_pld(EPS_SET_CHNL_STATE,EPS_TASK,sizeof(eps_req),(uint8_t *)eps_req); //ERR_NOTI_RESTART_UHF
        //			err_detected(ERR_GROUP_COMMS, ERR_COMMS_RESTART_UHF);
#endif
    }
}


//#ifdef UHF_BEACON_ENB
/**
 * @brief This function handle the timer expiry of initial LEOP synchronization timer
 * Callback function for UHF beacon timer expiration
 * 
 * This function is called when the periodic timer for sending 
 * UHF beacons expires. It would handle sending the next beacon
 * message.
 */
void uhf_beacon_timer_exp_cb(void)
{
    //	#ifdef UHF_BEACON_ENB
    uhf_send_ipc(UHF_TX_PERIODIC_BEACON_TMR_EXP,COMMS_UHF_CTLR);

    uint64_t time_diff = 0, epoch_time = 0;
    uint32_t time_1sthalf=0;
    uint32_t time_2ndhalf=0;

    time_diff = get_crnt_time_date_in_epoch();

    epoch_time = uhf_permanant_timer_read();

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wformat"
    DEBUG_CPRINT(("UHF current time:%llu",time_diff));
    time_1sthalf = time_diff & 0xFFFFFFFF;
    time_2ndhalf |= time_diff >> 32;

    log_id_with_one_arg(LOG_INFO_L2,LOG_COMMS,UHF_CURRENT_TIME_u32_,time_1sthalf);
    log_id_with_one_arg(LOG_INFO_L2,LOG_COMMS,UHF_CURRENT_TIME_u32_,time_2ndhalf);
#pragma GCC diagnostic pop
    time_diff = time_diff - epoch_time;
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wformat"
    DEBUG_CPRINT(("UHF time diff: %llu, epoch: %llu",time_diff,epoch_time ));
#pragma GCC diagnostic pop

    os_timer_start(uhf_beacon_timer,uhf_tmr_cfg.beacon_prd_tmr);
    DEBUG_CPRINT(("UHF: Beacon timer %d started",uhf_tmr_cfg.beacon_prd_tmr));
    //#endif
}

/**
 * @brief call back function at short duration expiry
 * pass fsm state via IPC
 *
 */
void uhf_beacon_rep_timer_cb(void)
{
    DEBUG_CPRINT(("UHF: Beacon enable timer %d started",uhf_tmr_cfg.beacon_rep_tmr));
    //   log_id_with_one_arg(LOG_INFO_L1,LOG_COMMS,UHF_BEACON_REP_TIMER_STARTED__u32_,uhf_tmr_cfg.beacon_rep_tmr);

    uhf_rep_cnt++;

    if((uhf_gpass_cfg.gpass_beacon_tx_enb)&&(uhf_sch_gs_contact))
    {
        if(uhf_rep_cnt <=uhf_gpass_cfg.beacon_tx_count)
        {
            uhf_send_ipc(UHF_REP_TMR_EXP,COMMS_UHF_CTLR);
        }
        else
        {
            uhf_rep_cnt = 0;
            uhf_gs_contact_status_upd_itc(UHF_TC_TM_ST_REQ,COMMS_UHF);

        }
    }    
    else
    {
        if(uhf_rep_cnt <= uhf_tmr_cfg.tx_data_rep_cnt)
        {
            uhf_send_ipc(UHF_REP_TMR_EXP,COMMS_UHF_CTLR);
        }
        else
        {
            uhf_rep_cnt = 0;
        }
    }
}


/**
 * @brief call back function at short duration expiry
 * pass fsm state via IPC
 *
 * Callback function for UHF beacon enable timer
 * 
 * This function is called when the timer for enabling UHF beacon
 * transmission expires. It would handle enabling periodic sending
 * of beacon messages. 
 * 
 */
void uhf_beacon_enb_timer_cb(void)
{
    os_timer_start(uhf_beacon_timer,uhf_tmr_cfg.beacon_prd_tmr);
    DEBUG_CPRINT(("UHF: Beacon enable timer %d started",uhf_tmr_cfg.beacon_prd_tmr));
    log_id_with_one_arg(LOG_INFO_L1,LOG_COMMS,UHF_BEACON_ENABLE_TIMER_STARTED__u32_,uhf_tmr_cfg.beacon_prd_tmr);
}



/**
 * @brief This function is the callback function for the UHF RX sync periodic timer
 *        This sync will be used to store parameter for every 2mins
 * Callback function for periodic UHF TM read
 * 
 * This function is called periodically to read UHF telemetry data.
 * It would handle collecting and processing telemetry data.
 */
void uhf_tm_periodic_read_cb(void)
{
    uhf_send_ipc(UHF_TM_PERIODIC_READ,COMMS_UHF_CTLR);
} 

/**
 * @brief This function is the callback for UHF TX on timer expiry
 *
 * Callback function for UHF TX on timer
 * 
 * This function is called when the UHF TX on timer expires.
 * It would handle starting the transmission of data over UHF.
 */
void uhf_tx_tm_on_cb(void)  
{
    if(!uhf_sch_gs_contact)
    {
        uhf_gs_contact_status_upd_itc(UHF_TC_TM_STOP_REQ,COMMS_UHF);
        DEBUG_CPRINT(("\nUHF_TX_TIMER_STOPPED TM send stopped \n"));
        log_id(LOG_INFO_L1,LOG_COMMS,UHF_TX_TIMER_STOPPED_TM_SEND_STOPPED);
    }
    else
    {
        DEBUG_CPRINT(("\nUHF_TX_TIMER_STOPPED TM send not stopped \n"));
        log_id(LOG_INFO_L1,LOG_COMMS,UHF_TX_TIMER_STOPPED_TM_SEND_NOT_STOPPED);
    }
}

/**
 * @brief This function is the callback for rsp timeout recovery
 *
 * Callback function for UHF TX on timer
 * 
 * This function is called when the rsp timeout recovery.
 * It would handle recovery for rsp timeout.
 */
void uhf_rsp_timeout_recovery_cb(void)
{
    uhf_send_ipc(COMMS_UHF_REINIT_TMR_EXP,COMMS_UHF_CTLR);
    DEBUG_CPRINT(("*******uhf_reinit_tmr_cb********"));
}

/**
 * @brief This function is the callback for cmd trigger
 *
 * Callback function for UHF cmd trigger delay
 * 
 */
void uhf_cmd_wait_tmr_exp_cb(void)
{
    uhf_send_ipc(UHF_CMD_TMR_EXP,COMMS_UHF_CTLR);
    DEBUG_CPRINT(("*******uhf_cmd_wait_timer_cb********"));
}
