/**
 * @file file_transfer.h
 *
 * @brief This file contains function prototypes and data definitions that
 * helps to handle file transfer sender and receiver operations
 *
 * @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.
 */

#ifndef _INC_FILE_TRANSFER_H_
#define _INC_FILE_TRANSFER_H_

#include "exo_osal_mem_management.h"
#include "exo_osal.h"
#include "unistd.h"

#include "ft_timer.h"
#include "ft_config.h"
#include "segmentation.h"
#include "ft_config_param.h"


/******************************************************************************/
/*                Definition of exported macros                 			  */
/******************************************************************************/
/* FT module test configurations (testing purpose)*/
//#define FT_SAT
//#define FT_OBC
//#define FT_DEBUG
//#define FT_DEBUG 0

/* Mode of Operation = FILE */
#define M_FILE 0

/* Mode of Operation = DATA */
#define M_DATA 1

/* FTM module configuration parameters */
#define FTM_MAX_MTU_SIZE (uint16)(1600)

/* Queue size of TCTM payload */
#define FTM_QUEUE_TCTM_PAYLOAD_BUFFER_SIZE FTM_MAX_MTU_SIZE

/* FTDS frame waiting timeout time in seconds */
#define FTDP_WAITING_TIME_INTERVAL 15

/* Enable/Disable Sequence Loss Detection */
#define SEQ_LOSS_DETECTION_OFF 0

#ifndef FT_OBC
/* FTDS time interval tick unit */
#define FTDS_TICK_TIME 1000 // 1 sec = 1000 millisecnds
#else
#define FTDS_TICK_TIME 5 // millisecnds
#endif


/******************************************************************************/
/*         Definition of exported types (typedef, enum, struct, union)        */
/******************************************************************************/


/**
 * @brief Framework mode of operation
 * Upload or Download
 */
typedef enum ft_current_process
{
	ft_upload,		///< set as sender node
	ft_download,	///< set as receiver node
	ft_process_na   ///< NA
}e_ft_current_process;


/**
 * @brief State of File transfer
 */
typedef enum
{
	FT_Inactive,                ///< Inactive
	FT_Init,                	///< Initialization
    FT_Idle_State,              ///< Idle state
	FT_Waitfor_FTSR,            ///< Sent FTCI and wait for Response (FTSR)
	FT_Send_Upload_Request,     ///< Sent FTCI request
	FT_Wait_for_2sec,           ///< 2 seconds delay
	FT_Segmentation,            ///< Segmentation
	FT_Sequence_Transmission,   ///< Data transmission
	FT_Receive_Sequence,        ///< Not used
	FT_Report_Sequence_loss,    ///< Sequence Loss observed by Receiver
	FT_Report_Head_Change,      ///< Request Head Change by Receiver
	FT_Suspended,               ///< Transmission suspended
	FT_Resumed,                 ///< Transmission resumed

} eSystemState;



/**
 * @brief Error codes
 */
typedef enum ft_err_cod
{
	ft_noerror,
	ft_framework_busy_error,
	ft_icd_tctm_pld_callback_error,
	ft_sender_app_not_reg_error,
	ft_input_file_open_error,
	ft_invalid_input_error,
	ft_receiver_app_not_reg_error,
	ft_receiver_side_undefined_error,
	ft_malloc_ram_error,
	ft_malloc_flash_error,
	ft_output_file_open_error,
	ft_sc_malloc_error,
	ft_rc_null_error,
	ft_rc_context_input_error,
    ft_rx_mem_ptr_null_error,
	ft_rx_invld_input_cfg,
	ft_rx_sys_error
}e_ft_error_sts;


/**
 * @brief Status of current operation
 */
typedef struct ft_status_update
{
	e_ft_error_sts error;           ///< Error type
	uint8_t upload_percentile;      ///< Upload percentage has completed
}ft_compl_and_error_status;


/**
 * Message queue which contains TCTM id, tctm payload, tctm lenth and source destination ID
 */
typedef struct ft_queue_tctm_info_
{
	uint16_t tc_tm_id;											 ///< TCTM id
	uint16_t Q_payload_len;         							 ///< Frame payload length
	uint8_t *Q_payload_ptr;                                      ///< frame paylod
	uint8_t src_dst_id; 										 ///< source and destination FTM node
}strFTM_queue_tctm_info;


/// Typedefs
typedef uint8_t (*ft_payload_tx_type)(uint16 tc_tm_id, uint8_t *payload_ptr, uint16_t payload_len);
typedef uint8_t (*ft_payload_obc_type)(uint64_t mem_addr, uint8_t *payload_ptr, uint16_t payload_len);
typedef uint8_t (*ft_payload_obc_busycheck_type)(void);
typedef uint8_t (*ft_data_write_cblk_type)(uint32_t mem_addr, uint8_t *payload_ptr, uint16_t payload_len);


/******************************************************************************/
/*                    Declaration of exported variables                       */
/******************************************************************************/

extern ft_data_write_cblk_type 				ft_ram_write_fp;
extern os_queue_handle_ptr 					ft_queue_hdle_sen;
extern os_queue_handle_ptr 					ft_queue_hdle_rcv;



/******************************************************************************/
/* GLOBAL FUNCTION PROTOTYPES                                                 */
/******************************************************************************/

/**
 * @brief This function used to register ram write callback function which is
 * to be used by FTM to maintain FTDS frame
 *
 *
 * @param[in]  fp  : callback to be stored
 *
 * @return none
 * @retval void
 */
uint8_t ft_register_ramwrite_cblk(ft_data_write_cblk_type fp);



/**
 * @brief This function used to set the current file transfer FSM state
 *
 *
 * @param[in]  set  : ft state machine state set
 *
 * @return none
 * @retval void
 */
void ft_fsm_change_state(eSystemState set);

/**
 * @brief This function used to return the current file transfer state machine state
 *
 *
 * @param[in]  void  : none
 *
 * @return file transfer state machine state
 * @retval eSystemState : different states of file transfer state machine
 */
eSystemState ft_fsm_read_state();

/**
 * @brief This function used to print the current file transfer state machine state
 *
 *
 * @param[in]  void  : none
 *
 * @return none
 * @retval void
 */
void print_current_fsmstate(void);




/**
 * @brief This API manages sender and receiver operation of file transfer
 *
 * @param[in]  void*  : unused
 *
 * @return none
 * @retval none
 */
void ft_handler(void*);


/**
 * @brief This API receives incoming IPC message
 *
 * @param[in]  void*  : unused
 *
 * @return none
 * @retval none
 */
void ft_rx_thread(void* params);


/* internal FT function */



/**
 * @brief This function used to return the current file transfer state
 *
 *
 * @param[in]  void  : none
 *
 * @return file transfer state
 * @retval ft_upload : performing upload process
 * @retval ft_download : performing download process
 * @retval ft_process_na : at idle
 */
e_ft_current_process get_file_transfer_state(void);


/**
 * @brief This function used to set the file transfer state
 *
 *
 * @param[in]  set  : state set
 *
 * @return none
 * @retval void
 */
void set_file_transfer_state(e_ft_current_process set);


/**
 * @brief This function used to receive tctm message frames from OBC module
 *
 * @param[in]  tc_tm_id  : telemetry\telecommand ID
 * @param[in]  payload_ptr  : pointer to telemetry data to receive
 * @param[in]  payload_len  : telemetry\telecommand data length to receive
 *
 * @return none
 * @retval none
 */
void ft_payload_parser(uint16 tc_tm_id, uint8_t *payload_ptr, uint16_t payload_len);


/**
 * @brief This function used to get the current error state
 *
 *
 * @param[in]  void  : none
 *
 * @return return the error state
 * @retval e_ft_error_sts returns different error state of FTM
 */
e_ft_error_sts ft_get_error_sts(void);


/**
 * @brief This function used to set the error state
 *
 *
 * @param[in]  err  : set the error state
 *
 * @return none
 * @retval void : none
 */
void ft_set_err_sts(e_ft_error_sts err);


/**
 * @brief This function used to set the percentage of file operation has completed
 *
 *
 * @param[in]  percent  : set the completion percentage
 *
 * @return none
 * @retval void : none
 */
void ft_set_percentile_sts(uint8_t percent);


uint8_t ft_get_upload_percentage_compl(void);

/**
 * @brief This function used to send tm message frames from FTM to OBC module
 *
 * @param[in]  tm_id  : telemetry ID
 * @param[in]  tm_data  : telemetry data to send
 * @param[in]  tm_data_len  : telemetry data length to send
 *
 * @return none
 * @retval none
 */
void ft_send_tm_to_obc(uint16 tm_id, uint8 *tm_data, uint16 tm_data_len);


/**
 * @brief This function used to trigger sband failure scenario for testing purpose
 *
 *
 * @param[in]  set  : set the sband failure
 *
 * @return none
 * @retval void : none
 */
void ft_sband_manual_failure(uint8_t set);


/**
 * @brief This function used to enable/disable ack response for transmission (testing purpose)
 *
 *
 * @param[in]  set  : enable/disable ack bit
 *
 * @return none
 * @retval void : none
 */
void ft_ftds_ack_enable_set(uint8_t set);


/**
 * @brief This function used to monitor sband link status
 * This will get get the status during FTM transmission, if comm is broken FTM will perform auto save context
 *
 *
 * @param[in]  void  : none
 *
 * @return none
 * @retval none
 */
void ft_get_sband_link_status(void);



/**
 * @brief This function used to Return queue buffer save pointer *
 *
 * @param[in]  void  : none
 *
 * @return buffer address
 * @retval bufer address
 */
uint8_t* ft_get_queue_rx_buffer_address(void);


/**
 * @brief This function used to initialize FTM *
 *
 * @param[in]  void  : none
 *
 * @return buffer address
 * @retval bufer address
 */

void ft_initialisation(void);



/*
 *
 *
 *
FTCI Download request 		- Service enable
Session Terminate request 	- Service disable
Session Auto terminate (link failure/ receiver not responsive) - Service disable
Download complete 		    - Service disable
Session auto save context 	- Service disable
Session manual save context - Service disable
Session resume context 		- Service enable

Upload request    		    - Service enable
Receiver not acceptance . Auto terminate - Disable service
Upload completed 		   - Service disable
 *
 *
 */

/**
 * @brief This function used to turn off FTM service*
 *
 * @param[in]  void  : none
 *
 * @return void

 */
void ft_service_disable(void);


/**
 * @brief This function used to turn on FTM service*
 *
 * @param[in]  void  : none
 *
 * @return void

 */

void ft_service_enable(void);


uint8_t ft_get_service_activity_status(void);

#endif /* _INC_FILE_TRANSFER_H_ */
