/*
 * ft_debug.c
 *
 *  Created on: 31-Dec-2022
 *      Author: Invcuser52
 */


/*
 *
 *  Get FTM status  >> e_ft_debug_status
1	FT process = upload / download   = get_file_transfer_state(); 2 bit
2	FT fsm    = ft_fsm_read_state()             2 bit
3	Node type = master/ receiver
4	Sus / Resume status    = ft_get_suspend_resume_sts();   2 bit
5	Sequence loss status  = ft_get_seq_loss_status();    2 bit
6   Head position =  ft_get_receiver_head_seq_id();     32 bit
 *
 *
 */

#include "ft_debug.h"
#include "file_transfer.h"
#include "ftds_decode.h"
#include "suspend_resume.h"
#include "tc_tm_sample.h"
#include "ftm_version.h"


ft_debug_sel ft_ftdb = e_ft_none;
ft_debug_gen_sts ft_db_gen_sts;
s_string_info ftdb_frame;

extern tc_tm_id_e_ft tc_response;

static void debug_print_fsm(eSystemState fsm)
{
	printf("FSM: ");
	switch(fsm)
	{
	    case FT_Inactive: printf("FT_Inactive\n"); break;

	    case FT_Init: printf("FT_Init\n"); break;

	    case FT_Idle_State: printf("FT_Idle_State\n"); break;

	    case FT_Waitfor_FTSR: printf("FT_Waitfor_FTSR\n"); break;

	    case FT_Send_Upload_Request: printf("FT_Send_Upload_Request\n"); break;

	    case FT_Wait_for_2sec: printf("FT_Wait_for_2sec\n"); break;

	    case FT_Segmentation: printf("FT_Segmentation\n"); break;

	    case FT_Sequence_Transmission: printf("FT_Sequence_Transmission\n"); break;

	    case FT_Receive_Sequence: printf("FT_Receive_Sequence\n"); break;

	    case FT_Report_Sequence_loss: printf("FT_Report_Sequence_loss\n"); break;

	    case FT_Report_Head_Change: printf("FT_Report_Head_Change\n"); break;

	    case FT_Suspended: printf("FT_Suspended\n"); break;

	    case FT_Resumed: printf("FT_Resumed\n"); break;

	    default : printf("INVALID"); break;

    }
 }


static void debug_print_operation(e_ft_current_process opera)
{
   printf("Operation:");
   switch(opera)
   {
   case ft_upload: printf("ft_upload\n"); break;

   case ft_download: printf("ft_download\n"); break;

   case ft_process_na: printf("ft_process_na\n"); break;

   default : printf("INVALID"); break;

   }

}

static void debug_print_suspend(e_sus_res_state susp)
{
	printf("Suspend:");
	switch(susp)
	{
	   case state_suspend: printf("state_suspend\n"); break;

	   case state_suspend_ack: printf("state_suspend_ack\n"); break;

	   case state_resume: printf("state_resume\n"); break;

	   case state_resume_ack: printf("state_resume_ack\n"); break;

	   case no_suspend_reusume: printf("no_suspend_reusume\n"); break;

	   default : printf("INVALID"); break;

	}

}


/* Receive debug request */
void ft_decode_debug_request_frame(uint8_t *ftdb_data, uint16_t ftdb_data_length)
{
	ftdb_frame.str_ptr = malloc(ftdb_data_length);
	if(ftdb_frame.str_ptr != NULL)
	{
		if(*ftdb_data < e_ft_debug_max)
		{
			ft_ftdb = (ft_debug_sel)*ftdb_data;
			printf("FTDB Request received.\n");
	//	    os_sem_give(ft_debug_hdlr_sem);
			memcpy(ftdb_frame.str_ptr, ftdb_data, ftdb_data_length);
		}
		else
		{
			printf("FTDB input invalid\n");
			free(ftdb_frame.str_ptr);
		}
	}
	else
	{
		printf("FTM malloc fail\n");
	}

}


/* Receive debug response */
void ft_decode_debug_response_frame(uint8_t *ftdr_data, uint16_t ftdr_data_length)
{
	ft_debug_gen_sts  *ft_db_gen_sts_ptr;
//	uint8_t u8ctr;


	if(*ftdr_data <= e_ft_reset)
	{

/*		printf("FTDR Response received of size:%d.\n",ftdr_data_length);

		for(u8ctr =0; u8ctr < ftdr_data_length; u8ctr++)
		{
			printf("%d,",ftdr_data[u8ctr]);
		}*/
		printf("\n");

		switch(*ftdr_data)
		{
			case e_ft_none:
				break;

			case e_ft_debug_gen_status:
				ft_db_gen_sts_ptr = (ft_debug_gen_sts*)&ftdr_data[1];
				printf("FT_Debug - Get gen status\n");
                                debug_print_fsm(ft_db_gen_sts_ptr->fsm_st);
				debug_print_operation(ft_db_gen_sts_ptr->ft_proc_st);
				debug_print_suspend(ft_db_gen_sts_ptr->sus_res_st);
				if(ft_db_gen_sts_ptr->seq_loss_st == 0)
				{
					printf("No Sequence Loss\n");
				}
				else if (ft_db_gen_sts_ptr->seq_loss_st != 0)
				{
					printf("Sequence Loss Observed\n");
				}
				printf("Head position: %d\n",ft_db_gen_sts_ptr->head_pos);
				if(ft_db_gen_sts_ptr->service_run_sts == 0)
                {
                    printf("FT Timer OFF\n");
			    }
                else if (ft_db_gen_sts_ptr->service_run_sts == 1)
                {
                    printf("FT Timer ON\n");
                }
                else 
                {
                    printf("Invalid ID recived\n");
                }
				
                if(ft_db_gen_sts_ptr->prev_tctm_id == 100)
                {
               	    printf("Previous TCTM ID: FTCI\n");
                }
                else if(ft_db_gen_sts_ptr->prev_tctm_id == 102)
                {
                    printf("Previous TCTM ID: FTDS\n");
                }
                else if(ft_db_gen_sts_ptr->prev_tctm_id == 103)
                {
                    printf("Previous TCTM ID: FTFCI\n");
                }
  
				printf("Previous TCTM Command: %d\n",ft_db_gen_sts_ptr->prev_tctm_response);
                                
				break;

			case e_ft_debug_sct_status:
				printf("FT_Debug - SCT-OTSU\n");
				break;

			case e_ft_debug_terminate:
				printf("FT_Debug - Terminate FTM\n");
				break;

			case e_ft_reset:
				printf("FT_Debug - FT Reset\n");
				break;
            case e_ft_get_version:
                printf("FTM Library Version %hhu:%hhu\n",ftdr_data[1],ftdr_data[2]);
                break;

			default :
				break;
		}

	}
	else
	{
		printf("FTDR input invalid\n");
	}
}



static void prepare_ftdp_response_frame(uint8_t response_code, uint8_t *data, uint8_t data_len)
{
	s_string_info ftdp_tctm_data;
	ftdp_tctm_data.str_ptr = malloc(data_len+1);
	if(ftdp_tctm_data.str_ptr != NULL)
	{
		*ftdp_tctm_data.str_ptr = response_code;
		if(data_len != 0)
		{
			memcpy(ftdp_tctm_data.str_ptr+1, data, data_len);
		}
		ftdp_tctm_data.size = data_len+1;

	#ifndef FT_SAT
		ft_save_tc_request(FT_TC_FTDR);
		ft_send_tctm(FT_TC_FTDR,ftdp_tctm_data.str_ptr, ftdp_tctm_data.size);
	#else
		ft_save_tm_request(FT_TM_FTDR);
		ft_send_tctm(FT_TM_FTDR,ftdp_tctm_data.str_ptr,ftdp_tctm_data.size);
	#endif
		free(ftdp_tctm_data.str_ptr);
	}
	else
	{
		printf("FTM: malloc error\n");
	}

}


void ft_encode_debug_request(ft_debug_sel response_code)
{
	s_string_info ftdp_tctm_data;
	ftdp_tctm_data.str_ptr = malloc(1);
	if(ftdp_tctm_data.str_ptr != NULL)
	{
		*ftdp_tctm_data.str_ptr = (uint8_t)response_code;
		ftdp_tctm_data.size = 1;

	#ifndef FT_SAT
		ft_save_tc_request(FT_TC_FTDB);
		ft_send_tctm(FT_TC_FTDB,ftdp_tctm_data.str_ptr, ftdp_tctm_data.size);
	#else
		ft_save_tm_request(FT_TM_FTDB);
		ft_send_tctm(FT_TM_FTDB,ftdp_tctm_data.str_ptr,ftdp_tctm_data.size);
	#endif
		free(ftdp_tctm_data.str_ptr);
	}
	else
	{
		printf("FTM: malloc error\n");
	}
}




void ft_debug_handle(void)
{
//    os_sem_take(ft_debug_hdlr_sem,os_wait_forever);
       uint16_t tctm_id,response;
       uint8_t ver_info[2];
	if(ft_ftdb != e_ft_none)
	{
		switch(ft_ftdb)
		{
			case e_ft_none:
				break;

			case e_ft_debug_gen_status:
				printf("FT_Debug - Get gen status\n");
				ft_db_gen_sts.head_pos = ft_get_receiver_head_seq_id();
				ft_db_gen_sts.fsm_st = ft_fsm_read_state();
				ft_db_gen_sts.ft_proc_st = get_file_transfer_state();
				ft_db_gen_sts.sus_res_st = ft_get_suspend_resume_sts();
				ft_db_gen_sts.seq_loss_st = ft_get_seq_loss_sts();
				ft_get_debug_last_tctm_and_response(&tctm_id, &response);
                ft_db_gen_sts.prev_tctm_id = tctm_id;
                ft_db_gen_sts.prev_tctm_response = response;
				prepare_ftdp_response_frame((uint8_t)e_ft_debug_gen_status, (uint8_t*)&ft_db_gen_sts, sizeof(ft_debug_gen_sts) );
				break;

			case e_ft_debug_sct_status:
				printf("FT_Debug - SCT-OTSU\n");
				break;

			case e_ft_debug_terminate:
				printf("FT_Debug - Terminate FTM\n");
				ft_transfer_request(Terminate_Transmission_rqst,0);
                prepare_ftdp_response_frame((uint8_t)e_ft_debug_terminate, NULL, 0);
				break;

			case e_ft_reset:
				printf("FT_Debug - FT Reset\n");
				ft_fsm_change_state(FT_Idle_State);
				set_file_transfer_state(ft_process_na);
				init_sus_res();
				prepare_ftdp_response_frame((uint8_t)e_ft_reset, NULL, 0);
				break;

            case e_ft_get_version:
                 printf("FT_Debug - FTM Version\n");
                 FTM_vidGetVersionInfo(ver_info);
                 prepare_ftdp_response_frame((uint8_t)e_ft_get_version, ver_info, 2);
                 break;
			default :
				break;
		}

		/* clear request */
		ft_ftdb = e_ft_none;
		free(ftdb_frame.str_ptr);
	}
}
/*
 * This function is used to save the previous frame information
 */
void ft_debug_save_prev_frame_info(uint16_t tctm_id , uint16_t response)
{
	ft_db_gen_sts.prev_tctm_id = tctm_id;
	ft_db_gen_sts.prev_tctm_response = response;
}
/*
 * This function is used to get the previous frame information
 */
void ft_get_debug_last_tctm_and_response(uint16_t* tctm_id , uint16_t* response)
{
	*tctm_id  = ft_db_gen_sts.prev_tctm_id;
	*response = ft_db_gen_sts.prev_tctm_response;
}


