/**
 * @file adcs_vapi_common.h
 *
 * @brief  This file contains abstracted Cube ADCS functions for testing
 * adcs functionalities
 *
 * @copyright Copyright 2023 Antaris, Inc.
 */

#ifndef ADCS_VSIM_COMMON_H_
#define ADCS_VSIM_COMMON_H_

#include <adcs_va.h>
#include <stddef.h>

#include "adcs_bootloader.h"
#include "adcs_common.h"
#include "adcs_cube_bypass.h"
#include "adcs_cubeacp.h"
#include "exo_osal_mem_management.h"
#include "exo_common.h"
#include "exo_osal.h"
#include "adcs_bsk_sim.h"

#ifdef __cplusplus
extern "C" {
#endif

#define CMD_TARGET_POINT       (55)
#define GET_SAT_POS_LLH       (150)

/**
 * @brief ADCS Beacon info structure
 */
typedef struct
{
    uint8_t fsm_state;          /*!< ADCS Current state */
    uint8_t mode;               /*!< ADCS Current mode */
    uint16_t sns_actr_pwr_sts; /*!< Sensor, actuators Power status*/
    uint8_t actrs_run_sts;      /*!< ADCS Actuator running status*/
}s_adcs_beacon_info;

/**
 * @brief  ADCS interface type enumeration
 */
typedef enum
{
    ADCS_INTF_NULL_PTR = -2,     ///< Null pointer
    ADCS_INTRFC_ERR = -1,        ///< Interface type error
    ADCS_UART = 0,               ///< UART interface
    ADCS_I2C = 1,                ///< I2C interface
    ADCS_CAN = 2                 ///< CAN interface
}e_intrfc_typ;

/**
 * @brief Function to handle set coarse momentum paramter command
 *
 * @return status of operation
 * @retval Always OPERATION_SUCCESS
 */
e_adcs_status vapi_adcs_set_coarse_momentum_params(void);

/**
 * @brief Function to handle adcs sensor init command
 *
 * @return status of operation
 * @retval Always OPERATION_SUCCESS
 */
e_adcs_status vapi_adcs_sensor_init(void);

/**
 * @brief Function to handle set fine momentum paramter command
 *
 * @return status of operation
 * @retval Always OPERATION_SUCCESS
 */
e_adcs_status vapi_adcs_set_fine_momentum_params(void);

/**
 * @brief Function to handle adcs log configuration command
 *
 * @return status of operation
 * @retval Always OPERATION_SUCCESS
 */
e_adcs_status vapi_adcs_cfg_log(void);

/**
 * @brief Function to handle adcs reset command
 *
 * @return status of operation
 * @retval Always OPERATION_SUCCESS
 */
e_adcs_status vapi_adcs_reset(void);

/**
 * @brief Function to handle adcs detumble command
 *
 * @return status of operation
 * @retval Always OPERATION_SUCCESS
 */
e_adcs_status vapi_adcs_detumble(void);

/**
 * @brief Function to handle ground tracking control command
 *
 * @param[in] longRef : longitude Reference
 * @param[in] latRef  : latitude Reference
 * @param[in] altRef  : altitude Reference
 *
 * @return status of operation
 * @retval Always OPERATION_SUCCESS
 */
e_adcs_status vapi_adcs_ground_tracking_control(float longRef,
                                                float latRef,
                                                float altRef);

/**
 * @brief Function to handle adcs boot command
 *
 * @return status of operation
 * @retval Always OPERATION_SUCCESS
 */
e_adcs_status vapi_adcs_boot(void);

/**
 * @brief Function to handle adcs bypass command
 *
 * @param[in] tx_data   : pointer to the data to be transmitted to adcs.
 * @param[out] rx_data   : pointer to the data received from adcs.
 * @param[in] tx_size   : pointer to size of transmitted data.
 * @param[out] rx_size   : pointer to size of received data.
 *
 * @return status of operation
 * @retval Always OPERATION_SUCCESS
 */
e_adcs_status vapi_adcs_bypass_mode(uint8 *tx_data, uint8 *rx_data,\
                                    uint16 tx_size, uint16* rx_size);

/*
 * @brief Function to Calculate the largest angular rate in each of the axis
 * @param[in] data      : Pointer to data to CUBEACP_AdcsMeasure_t
 * @param[out] sample   : number of samples
 * @param[out] max_rate : Pointer to data to CUBEACP_AdcsMeasure_t
 *
 * @return Return value of maximum rate in all 3 axis
 * @retval any double value
 */
double adcs_largest_rate(CUBEACP_AdcsMeasure_t *data, uint16 sample,
                    CUBEACP_AdcsMeasure_t *max_rate);

/*
 * @brief Function to select control mode based on sensor rate
 * @param[out] mode   : Pointer to data to CUBEACP_ConModeSelect_t
 * @param[out] max_rate_ptr : Pointer to max rate
 *
 * @return status of socket creation and connection with server
 * @retval -1 -> Error
 *         Other values -> Success
 */
e_adcs_status adcs_select_ctrl_mode(CUBEACP_ConModeSelect_t* mode,
                                double * max_rate_ptr);

/*
 * @brief Function to set multiplier for rate sensor
 * @param[in] mode   : maximum rate of all 3 axis
 *
 * @return status of socket creation and connection with server
 * @retval -1 -> Error
 *         Other values -> Success
 */
e_adcs_status adcs_set_rate_sens_mult(double max_rate);

/**
 * @brief Function to handle adcs coarse_momentum
 */
e_adcs_status vapi_adcs_coarse_momentum(void);

/**
 * @brief Function to handle adcs actuator init command
 */
e_adcs_status vapi_adcs_actuator_init(void);

/*
 * @brief Function to compare the difference of a and b with precision
 * @param[in] a         : First value of comparison
 * @param[in] b         : second value of comparison
 * @param[in] precision : value compared with the difference of a & b
 *
 * @return Return value of comparison status
 * @retval 0 -> Success
 *         -1 -> Error
 */
uint8 adcs_double_compare(double a, double b, double precision);

/**
 * @brief This API calculates and returns the size of the telemetry data
 *        based on the cubespace provided API
 *
 * @param[in] tlm   : Telemtry id
 *
 * @return size of tlm data
 * @retval Greater than zero -> Success
 *         Less than or equal to zero -> Error
 */
int16 adcs_get_tlm_size(uint8 tlm);

/*
 * @brief function to power on and commission the sun sensor
 *
 * @return Status of commission
 * @retval 0 -> Success
 *         Other values -> Error
 */
e_adcs_status adcs_commission_sun_sensor(void);

/*
 * @brief function to power on and commission the nadir sensor
 *
 * @return Status of commission
 * @retval 0 -> Success
 *         Other values -> Error
 */
e_adcs_status adcs_commission_nadir_sensor(void);

/*
 * @brief function to power on and commission the star sensor
 *
 * @return Status of commission
 * @retval 0 -> Success
 *         Other values -> Error
 */
e_adcs_status adcs_commission_star_sensor(void);

/*
 * @brief function to perform 3 reaction wheel test
 *
 * @return Status of the test
 * @retval 0 -> Success
 *         Other values -> Error
 */
e_adcs_status adcs_perform_r_wheel_test(void);

/*
 * @brief Function to handle adcs shutdown command
 *
 * @return Shutdown status
 * @retval 0 -> Success
 *         Other values -> Error
 */
e_adcs_status vapi_adcs_shutdown(void);

/*
 * @brief Function to handle adcs test command
 *
 * @return Shutdown status
 * @retval 0 -> Success
 *         Other values -> Error
 */
e_adcs_status vapi_adcs_test_mode(void);

/*
 * @brief Function to test reaction wheel
 * @param[in] setVal        : structure vaule of CUBEACP_WheelSpeedCmd_t
 * @param[in] expected_rate : structure vaule of CUBEACP_AdcsMeasure_t
 * @param[in] wheel : Axis of wheel that needs to be tested
 *
 * @return Return value of the interface send/receive api
 * @retval 0 -> Success
 *         Other values -> Error
 */
e_adcs_status vapi_adcs_r_wheel_ramp_up_test(CUBEACP_WheelSpeedCmd_t setVal,
        CUBEACP_AdcsMeasure_t expected_rate, e_rwheel_axis wheel);


/*
 * @brief Function to set Estimation Parameters
 * @param[in] use_sun   : boolean (0/1)
 * @param[in] use_nadir : boolean (0/1)
 * @param[in] use_css   : boolean (0/1)
 * @param[in] use_star  : boolean (0/1)
 *
 * @return Return value of the interface send/receive api
 * @retval 0 -> Success
 *         Other values -> Error
 */
e_adcs_status adcs_set_estim_sens_mask(uint8 use_sun, uint8 use_nadir,
        uint8 use_css, uint8 use_star);


/*
 * @brief Function to log adcs data to SD card
 * @param[in] param   : Parameters to log
 * @param[in] period : frequency of logging
 *
 * @return Return value of the interface send/receive api
 * @retval 0 -> Success
 *         Other values -> Error
 */
e_adcs_status adcs_log_sd_cube(uint8* param, uint16 period);

/*
 * @brief Function to handle adcs fine momentum command
 *
 * @return status of fine momentum
 * @retval 0 -> Success
 *         Other values -> Error
 */
e_adcs_status vapi_adcs_fine_momentum(void);

/*
 * @brief This API execute the ADCS sequences
 *
 * @param[in] seq : pointer to sequence
 * @param[in] size : size of the sequence
 *
 * @return status of send sequence.
 */
e_adcs_status adcs_execute_sequence(uint8* seq, uint16 size);

/*
 * @brief This function execute the Initial level ADCS sequence
 *
 * @return No return value as it is void api
 */
void adcs_init_sequence(void);

/**
 * @brief This function executes the fallback mechanism
 *
 * @return No return value as it is a void api
 * @retval void
 */
void adcs_execute_fallback(void);

/*
 * @brief Function to request Boot And Running Program Status tlm
 * @param[out] prog_sts : Pointer to COMMON_ExtendedIdentification_t
 *
 * @return Return value of the interface send/receive api
 * @retval 0 -> Success
 *         Other values -> Error
 */
int8 adcs_request_boot_prog_status_tlm(COMMON_ExtendedIdentification_t\
        *prog_sts);

/*
 * @brief Function to request identification tlm
 * @param[out] id_stat : Pointer to COMMON_Identification_t
 *
 * @return Return value of the interface send/receive api
 * @retval 0 -> Success
 *         Other values -> Error
 */
int8 adcs_request_identification_tlm(COMMON_Identification_t *id_stat);

/**
 * @brief Function to get ADCS beacon data
 *
 * @param[out] beacon_data : pointer to store ADCS beacon dats's
 */
void adcs_get_beacon_data(uint8_t* beacon_data);

#ifdef __cplusplus
}
#endif
#endif /* ADCS_VSIM_COMMON_H_ */
