/*********************************************************************************
 * Copyright(C),Dalian Joynext Technology Co., Ltd.
 * FileName:    CAN_Sig.h
 * Author:      huo_h1
 * Version :    Ver0.1
 * Date:        2020-10-15
 * Description:
 *
 *********************************************************************************/
/*********************************************************************************
 *                      Include                                                  *
**********************************************************************************/
#include "CAN_API.h"
#include "CAN_Sig.h"
#include "ccl_inc.h"

/*********************************************************************************
 *                      Macro                                                    *
**********************************************************************************/

#define SizeOf(x)                   (sizeof(x) / sizeof(x[0]))

/*********************************************************************************
 *                      Define                                                   *
**********************************************************************************/
#define SIGNAL_MODE_RX              0x01
#define SIGNAL_MODE_TX              0x02

/*********************************************************************************
 *                      Typedef/Struct                                           *
**********************************************************************************/
typedef SignalErrCode (*SignalProc)(uint8_t* signal_value, uint8_t* signal_size);
typedef void (*DefaultProc)();

typedef struct
{
	SignalProc  signal_proc;
	uint8_t	mode;
	uint8_t  module;
} Signal;

typedef struct
{
	uint16_t event_id;
	uint16_t group_id;
} MsgPair;

typedef struct
{
	MsgGroupId 	group_id;
	DefaultProc default_proc;
	uint8_t 	is_default;	
} DefaultMessage;

/*********************************************************************************
*                      Private variables                                         *
**********************************************************************************/
/* SA_01 */
static SignalErrCode EmgcCallTrigd_SA_Set_Proc(uint8_t* signal_value, uint8_t* signal_size)
{
	(void) signal_value;
	(void) signal_size;
	IlPutTxEmgcCallTrigd_SA(*signal_value);
	return SIGNAL_ERROR_OK;
}

static SignalErrCode EmgcCallFlrSts_SA_Set_Proc(uint8_t* signal_value, uint8_t* signal_size)
{
	(void) signal_value;
	(void) signal_size;
	IlPutTxEmgcCallFlrSts_SA(*signal_value);
	return SIGNAL_ERROR_OK;
}

/* CGW_03 */
static SignalErrCode CGW_03_CRC_Get_Proc(uint8_t* signal_value, uint8_t* signal_size)
{
	(void) signal_value;
	(void) signal_size;
	*signal_value = IlGetRxCGW_03_CRC();
	*signal_size = 1;
	return SIGNAL_ERROR_OK;
}

static SignalErrCode VehState_ASIL_Get_Proc(uint8_t* signal_value, uint8_t* signal_size)
{
	(void) signal_value;
	*signal_value = IlGetRxVehState_ASIL();
	*signal_size = 1;
	return SIGNAL_ERROR_OK;
}

static SignalErrCode CGW_03_MsgCntr_Get_Proc(uint8_t* signal_value, uint8_t* signal_size)
{
	(void) signal_value;
	*signal_value = IlGetRxCGW_03_MsgCntr();
	*signal_size = 1;
	return SIGNAL_ERROR_OK;
}

static SignalErrCode ComfEna_ASIL_Get_Proc(uint8_t* signal_value, uint8_t* signal_size)
{
	(void) signal_value;
	*signal_value = IlGetRxComfEna_ASIL();
	*signal_size = 1;
	return SIGNAL_ERROR_OK;
}

static SignalErrCode VehMode_Get_Proc(uint8_t* signal_value, uint8_t* signal_size)
{
	(void) signal_value;
	*signal_value = IlGetRxVehMode();
	*signal_size = 1;
	return SIGNAL_ERROR_OK;
}

static SignalErrCode NBSMovReq_Get_Proc(uint8_t* signal_value, uint8_t* signal_size)
{
	(void) signal_value;
	*signal_value = IlGetRxNBSMovReq();
	*signal_size = 1;
	return SIGNAL_ERROR_OK;
}

static SignalErrCode NBSSideDetectionReq_Get_Proc(uint8_t* signal_value, uint8_t* signal_size)
{
	(void) signal_value;
	*signal_value = IlGetRxNBSSideDetectionReq();
	*signal_size = 1;
	return SIGNAL_ERROR_OK;
}

static SignalErrCode NBSReq_Get_Proc(uint8_t* signal_value, uint8_t* signal_size)
{
	(void) signal_value;
	*signal_value = IlGetRxNBSReq();
	*signal_size = 1;
	return SIGNAL_ERROR_OK;
}

const Signal SA_01_SIGNALS[SIG_ID_SA_01_COUNT] =
{
	{	EmgcCallTrigd_SA_Set_Proc,	SIGNAL_MODE_TX,	RX_MODULE_SOC	},
	{	EmgcCallFlrSts_SA_Set_Proc,	SIGNAL_MODE_TX,	RX_MODULE_SOC	},
};

const Signal CGW_03_SIGNALS[SIG_ID_CGW_03_COUNT] =
{
	{	CGW_03_CRC_Get_Proc,	SIGNAL_MODE_RX,	RX_MODULE_SOC	},
	{	VehState_ASIL_Get_Proc,	SIGNAL_MODE_RX,	RX_MODULE_SOC	},
	{	CGW_03_MsgCntr_Get_Proc,	SIGNAL_MODE_RX,	RX_MODULE_SOC	},
	{	ComfEna_ASIL_Get_Proc,	SIGNAL_MODE_RX,	RX_MODULE_SOC	},
	{	VehMode_Get_Proc,	SIGNAL_MODE_RX,	RX_MODULE_SOC	},
	{	NBSMovReq_Get_Proc,	SIGNAL_MODE_RX,	RX_MODULE_SOC	},
	{	NBSSideDetectionReq_Get_Proc,	SIGNAL_MODE_RX,	RX_MODULE_SOC	},
	{	NBSReq_Get_Proc,	SIGNAL_MODE_RX,	RX_MODULE_SOC	},
};

const MsgPair CAN_RX_MESSAGES[] = {
	{	CGW_03_CHG_INDICATION, MSG_GROUP_01	},
 };

//const Signal* CAN_TX_MESSAGES[] = {  };

uint8_t SA_01_FLAGS[SIG_ID_SA_01_COUNT] = {0};
uint8_t CGW_03_FLAGS[SIG_ID_CGW_03_COUNT] = {0};

uint8_t* MESSAGES_FLAG[MSG_GROUP_COUNT] = { SA_01_FLAGS, CGW_03_FLAGS };
const Signal* MESSAGES[MSG_GROUP_COUNT] = { SA_01_SIGNALS, CGW_03_SIGNALS };
uint8_t MESSAGE_COUNT[MSG_GROUP_COUNT] = { SIG_ID_SA_01_COUNT, SIG_ID_CGW_03_COUNT };

DefaultMessage DEFAULT_MESSAGE[] =
{
    0
};

/*********************************************************************************
 * Function:        SetDefaultValue
 * Description:
 * Input:           exinf - inlet parameter
 * Output:          -
 * Return:          void
 *********************************************************************************
 * History:         No.     Date        Author          Modification
 *--------------------------------------------------------------------------------
 *                  0001    2019-11-26  HuoHong      New
 *
 **********************************************************************************/
void SetDefaultValue(MsgGroupId group_id)
{
	for(uint8_t i = 0; i < SizeOf(DEFAULT_MESSAGE); ++i)
	{
		if(DEFAULT_MESSAGE[i].group_id == group_id)
		{
			if(!DEFAULT_MESSAGE[i].is_default)
			{
				DEFAULT_MESSAGE[i].default_proc();
				DEFAULT_MESSAGE[i].is_default = 1;
			}
		}
	}
}

void ResetDefaultMessage()
{
	for(uint8_t i = 0; i < SizeOf(DEFAULT_MESSAGE); ++i)
	{
		DEFAULT_MESSAGE[i].is_default = 0;
	}
}

void SetChange(uint16_t signal_id)
{
	MsgGroupId group = GROUP_ID(signal_id);
	uint8_t index = SIGNAL_INDEX(signal_id);

	if(group < MSG_GROUP_COUNT && index < MESSAGE_COUNT[group])
	{
		MESSAGES_FLAG[group][index] = true;
	}
}

uint8_t IsSignalChange(uint16_t signal_id)
{
	MsgGroupId group = GROUP_ID(signal_id);
	uint8_t index = SIGNAL_INDEX(signal_id);

	if(group < MSG_GROUP_COUNT && index < MESSAGE_COUNT[group])
	{
		return MESSAGES_FLAG[group][index];
	}

	return false;
}

uint16_t GetGroupByEvent(uint16_t event)
{
	for(size_t i = 0; i < SizeOf(CAN_RX_MESSAGES); ++i)
	{
		if(CAN_RX_MESSAGES[i].event_id == event)
		{
			return CAN_RX_MESSAGES[i].group_id;
		}
	}

	return 0xFFFF;
}

void SignalSetting_Obtain(SignalSetting* signal_setting, uint16_t group_id, uint8_t signal_index)
{
    if(NULL != signal_setting)
    {
		if(group_id < MSG_GROUP_COUNT && signal_index < MESSAGE_COUNT[group_id])
		{
			if(MESSAGES[group_id][signal_index].signal_proc != NULL)
			{
				MESSAGES[group_id][signal_index].signal_proc(signal_setting->value, &signal_setting->size);
				signal_setting->module = MESSAGES[group_id][signal_index].module;
			}
		}
    }
}

void RefreshSignal(uint8_t module, RefreshSignalProc on_response_proc, RefreshFinishProc on_finish_proc)
{
	uint8_t  signal_value[MAX_SIGNAL_SIZE] = {0};
    uint8_t  signal_size = 0;

	for(uint8_t group = 0; group < MSG_GROUP_COUNT; ++group)
	{
		for(uint8_t index = 0; index < MESSAGE_COUNT[group]; ++index)
		{
			if(MESSAGES[group][index].mode & SIGNAL_MODE_RX)
			{
				if(MESSAGES[group][index].module & module)
				{
					MESSAGES[group][index].signal_proc(signal_value, &signal_size);
					on_response_proc(module, MAKE_ID(group, index), signal_value, signal_size);
				}
			}
		}
	}

	on_finish_proc(module);
}

SignalErrCode SignalRxControl(uint16_t signal_id, uint8_t* signal_value, uint8_t* signal_size)
{
    if(NULL != signal_value && NULL != signal_size)
    {
		MsgGroupId group = GROUP_ID(signal_id);
		uint8_t index = SIGNAL_INDEX(signal_id);

		if(group < MSG_GROUP_COUNT && index < MESSAGE_COUNT[group])
		{
			if(MESSAGES[group][index].signal_proc != NULL)
			{
				return MESSAGES[group][index].signal_proc(signal_value, signal_size);
			}
			else
			{
				return SIGNAL_ERROR_UNKNOWN;
			}
		}
    }

    return SIGNAL_ERROR_FAIL;
}

SignalErrCode SignalTxControl(uint16_t signal_id, uint8_t* signal_value, uint8_t* signal_size)
{
    if(NULL != signal_value && NULL != signal_size)
    {
		MsgGroupId group = GROUP_ID(signal_id);
		uint8_t index = SIGNAL_INDEX(signal_id);

		if(group < MSG_GROUP_COUNT && index < MESSAGE_COUNT[group])
		{
			if(MESSAGES[group][index].signal_proc != NULL)
			{
				//SetDefaultValue(group);
				return MESSAGES[group][index].signal_proc(signal_value, signal_size);
			}
			else
			{
				return SIGNAL_ERROR_UNKNOWN;
			}
		}
    }

    return SIGNAL_ERROR_FAIL;
}
