/**
 * @file ft_receiver.c
 *
 * @brief This file contains functions that provides demonstration of
 *        usage of state machine APIs for receiver side
 *
 * The functions provided in the file provides demonstration on
 * usage of state machine APIs
 *
 * @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 <stdio.h>

/******************************************************************************/
/*                      Include headers of the component                      */
/******************************************************************************/

#include "download_def.h"
#include "file_transfer.h"
#include "ft_timer.h"
#include "ftci_decode.h"
#include "ftds_decode.h"
#include "ftsr.h"
#include "suspend_resume.h"
#include "ft_receiver.h"
#include "ft_sender.h"
#include "logger.h"


/******************************************************************************/
/*                       Definition of local variables                        */
/******************************************************************************/

static uint8_t rx_response_ping_cnt;
static uint8_t ft_appid_rx;


/******************************************************************************/
/*                  Declaration of local function prototypes                  */
/******************************************************************************/

/**
 * @brief This function used to monitor sequence loss and recovery mechanism
 *
 *
 * @param[in]  none
 *
 * @return none
 * @retval void
 */
static void sequence_loss_manager(void);

/**
 * @brief This function used to monitor periodic response comes from sender
 * It will enable Auto save context mode if response has stopped from sender node
 *
 *
 * @param[in]  none
 *
 * @return none
 * @retval void
 */
static void receiver_side_response_periodic_check(void);




/******************************************************************************/
/*                       Definition of local functions                        */
/******************************************************************************/

/**
 * @brief This function used to monitor periodic response comes from sender
 * It will enable Auto save context mode if response has stopped from sender node
 *
 */
static void receiver_side_response_periodic_check(void)
{
	rx_response_ping_cnt++;
	if(rx_response_ping_cnt >= (dwnld_rqst.rx_node_conn_fail_timeout/FTDP_WAITING_TIME_INTERVAL))
	{
		DEBUG_CPRINT(("Sender not responsive for past %d sec !!! Terminate transmission\n",dwnld_rqst.rx_node_conn_fail_timeout));
		// ft_transfer_request(T_Rxnode,0);

		DEBUG_CPRINT(("Auto savecontext activated.\n"));
		log_id(LOG_INFO_L1, LOG_FTM, AUTO_SAVECONTEXT_ACTIVATED);
		ft_set_master_slave(sus_res_slave);
		ft_suspend(Suspend_Savecontext_Mode_rqst,20,3);
		prepare_sts_and_notify_receiver_app(transfer_suspended_auto_savecontext);
		ft_service_disable();
	}
}


/**
 * @brief This function used to monitor sequence loss and recovery mechanism
 *
 * this function only called during download, so expected state can only be suspend
 * can not be executed during suspend
 */
static void sequence_loss_manager(void)
{
	uint8_t timer_flg;
	e_sus_res_state sus_res_sts;

	sus_res_sts = ft_get_suspend_resume_sts();
	if(sus_res_sts != state_suspend && s_sus_res_info.request_clear_flag != 1)
	{
		timer_flg = ft_get_flag();
		if(timer_flg == 1)
		{
			if(dwnld_rqst.seq_loss_detect_enable == SEQ_LOSS_DETECTION_OFF)
			{
				DEBUG_CPRINT(("FTM - xband connection fail "));
				log_id(LOG_ERROR, LOG_FTM, XBAND_CONNECTION_FAIL_TERMINATE_TRANSMISSION);
				DEBUG_CPRINT(("Terminate transmission\n"));
				ft_transfer_request(T_Rxnode,0);
			}
			else if(dwnld_rqst.data_loss.total_lost_segment_count != 0 || dwnld_rqst.receive_busy ==1)
			{
				ftsr_set_resend_flag(&dwnld_rqst);
				dwnld_rqst.data_loss.head_change_request = 1;
				ft_fsm_change_state(FT_Report_Sequence_loss);
				ft_reset_timer();
				/* auto cancel func */
				receiver_side_response_periodic_check();
			}
		}
	}
}





/******************************************************************************/
/*                      Definition of exported functions                      */
/******************************************************************************/




/**
 * @brief This function is used to clear the ping failure monitor counter
 *
 *
 */
void ft_receiver_ping_rest(void)
{
	rx_response_ping_cnt =0;
}


/**
 * @brief State Machine :Function that handles download operation
 * Function that handles data loss detection and recovery
 *
 */
void ft_statemachine_download(void)
{
	eSystemState currentState;
	tc_tm_id_e_ft tc_id = FT_TC_TM_MAX_ID;

	sequence_loss_manager();
	ft_sus_res_handler();
	ft_get_sband_link_status();

	sus_res_clear_pending_rqst();
	currentState = ft_fsm_read_state();
	switch (currentState)
	{

		case FT_Init:
			break;

		case FT_Idle_State:
			break;

		case FT_Receive_Sequence:
			break;

		case FT_Report_Sequence_loss:
			ftsr_prepare_packet_loss_notify_frame(&dwnld_rqst, ftsr_missing_pckts);
			break;

		case FT_Report_Head_Change:
			tc_id = ftsr_prepare_head_change_request_frame(&dwnld_rqst);
			tc_id = tc_id;
			break;

		case FT_Suspended:
		break;

		case FT_Resumed:
			break;

		default:
			break;
	}

}



/**
 * @brief This function is used to set the app id of receiver side
 *
 */
void ft_set_app_id_rx(uint16_t set)
{
	ft_appid_rx = set;
}


/**
 * @brief This function is used to get the app id of receiver side
 *
 *
 */
uint16_t ft_get_app_id_rx(void)
{
	return ft_appid_rx;
}

/**
 *@brief State Machine :Function that use to store session id
 *
 */
void ft_rx_session_id_store(uint8 sid)
{
	dwnld_rqst.session_id = sid;
}
/**
 *@brief State Machine :Function that use to read stored session id
 *
 */
uint8_t ft_rx_session_id_read(void)
{
  return dwnld_rqst.session_id;
}
