#include "WLBrakeDataManage.h"
#include "ParsePackGateWayData.h"

static UINT8 g_WlbState = 0u;	/* 全线列车紧急制动状态 */

/**
* @brief 全线列车紧急制动首次命令处理函数
* @param 无
* @return 无
*/
static void WlbAtsCmdFst(void);

/**
* @brief 全线列车紧急制动二次命令处理函数
* @param 无
* @return 无
*/
static void WlbAtsCmdSnd(void);

/**
* @brief 设置全线列车紧急制动状态
* @param const UINT8 chState 全线列车紧急制动状态
* @return 无
* @note 当输入参数不合法时，设置全线列车紧急制动
*/
static void WlbSetState(const UINT8 chState);

/**
* @brief 全线列车紧急制动初始化函数
* @param 无
* @return 无
*/
void WlbInit(void)
{
	g_WlbState = WLB_UNSET;
}

/**
* @brief 获取全线列车紧急制动状态
* @param 无
* @return WLB_SET:全线列车紧急制动；WLB_UNSET:全线列车紧急制动未设置
*/
UINT8 WlbGetState(void)
{
	return g_WlbState;
}

/**
* @brief 设置全线列车紧急制动状态
* @param const UINT8 chState 全线列车紧急制动状态
* @return 无
* @note 当输入参数不合法时，设置全线列车紧急制动
*/
static void WlbSetState(const UINT8 chState)
{
	if (WLB_UNSET == chState)
	{
		g_WlbState = chState;
	}
	else
	{
		g_WlbState = WLB_SET;
	}
}

/**
* @brief 全线列车紧急制动主处理函数
* @param 无
* @return 无
*/
void WlbAtsCmdProc(void)
{
	AtsWlbMsgStru * strMsgFst = NULL;
	AtsWlbMsgStru * strMsgSnd = NULL;
	/*以下消息获取不会返回NULL*/
	strMsgFst = GetAtsWlbMsgFst();
	strMsgSnd = GetAtsWlbMsgSnd();

	if ((strMsgFst->chFlag != FLAG_SET) && (strMsgSnd->chFlag != FLAG_SET))
	{
		; /* 没有消息，什么也不做 */
	}
	else if ((strMsgFst->chFlag == FLAG_SET) && (strMsgSnd->chFlag != FLAG_SET))
	{/* 一次消息 */
		WlbAtsCmdFst();
	}
	else
	{/* 二次消息 */
		WlbAtsCmdSnd();
	}
}

/**
* @brief 全线列车紧急制动首次命令处理函数
* @param 无
* @return 无
*/
static void WlbAtsCmdFst(void)
{
	AtsWlbMsgStru * strMsgFst = NULL;
	AtsMsgCfmStru * strCfmFst = NULL;
	UINT32 dwCycle = 0u;
	UINT8 chLocalId = 0u;
	UINT8 szCrcTmp[1024] = { 0u };
	UINT32 ii = 0u;
	UINT8 chFunRtn = CI_TIME_OUT;
	UINT8 chState = 0U;  /*全线紧急制动状态*/
	UINT8 cAreaUrgentState = 0U;  /*物理区段区域紧急制动状态*/

	chLocalId = GetSystemParaLocalCiId();
	dwCycle = Get2oo2CurCycleNum();
	/*以下消息获取不会返回NULL*/
	strMsgFst = GetAtsWlbMsgFst();
	strCfmFst = GetAtsWlbCfmFst();

	if (strMsgFst->dwCycle == dwCycle)
	{
		strCfmFst->chFlag = FLAG_SET;
		strCfmFst->chTiocId = chLocalId;
		strCfmFst->chStation = strMsgFst->chStation;
		strCfmFst->wIndex = strMsgFst->wIndex;
		strCfmFst->dwTime = dwCycle;

		switch (strMsgFst->chBrakeType)
		{
		case WLB_TYPE_RC:
			/* 按控区紧急：获取当前全线列车紧急制动 */
			chState = WlbGetState();

			if (MSG_TYPE_WLB_CANCEL == strMsgFst->chType)
			{/* 取消全线列车紧急制动 */
				if (WLB_UNSET == chState)
				{/* 当前未设置 */
					strCfmFst->chOpStatus = CONFIRM_WLB_FST_UNSET;
				}
				else
				{
					strCfmFst->chOpStatus = CONFIRM_WLB_FST_SUCCESS;
				}
			}
			else
			{/* 设置全线列车紧急制动 */
				if (WLB_SET == chState)
				{/* 当前已设置，重复设置 */
					strCfmFst->chOpStatus = CONFIRM_WLB_FST_REPEAT;
				}
				else
				{
					strCfmFst->chOpStatus = CONFIRM_WLB_FST_SUCCESS;
					WlbSetState(WLB_SET);
				}
			}
			break;
		case WLB_TYPE_PHYSEC:
			/* 按物理区段紧急：获取当前区段区域紧急制动状态 */
			cAreaUrgentState = GetPhySecAreaUrgentState(strMsgFst->wBrakeIndex);

			if (MSG_TYPE_WLB_CANCEL == strMsgFst->chType)
			{
				if (PHYSEC_AREA_URGENT_NO == cAreaUrgentState)
				{
					strCfmFst->chOpStatus = CONFIRM_WLB_FST_UNSET;  /* 当前未设置区域紧急，回复未设置 */
				}
				else
				{
					strCfmFst->chOpStatus = CONFIRM_WLB_FST_SUCCESS;
				}
			}
			else
			{
				if (PHYSEC_AREA_URGENT_YES == cAreaUrgentState)
				{
					strCfmFst->chOpStatus = CONFIRM_WLB_FST_REPEAT;/* 当前已设置区域紧急，回复重复设置 */
				}
				else
				{
					strCfmFst->chOpStatus = CONFIRM_WLB_FST_SUCCESS;
					SetPhySecAreaUrgentState(strMsgFst->wBrakeIndex, PHYSEC_AREA_URGENT_YES);
				}
			}
			break;
		default:
			strCfmFst->chOpStatus = CONFIRM_WLB_FST_UNKNOWN;  /*紧急类型错误，返回未知*/
			break;
		}

		szCrcTmp[ii] = strMsgFst->chAtsId;
		ii++;
		szCrcTmp[ii] = strMsgFst->chStation;
		ii++;
		ShortToChar(strMsgFst->wIndex, &szCrcTmp[ii]);
		ii += 2U;
		szCrcTmp[ii] = strMsgFst->chBrakeType;
		ii++;
		szCrcTmp[ii] = strMsgFst->chBrakeCount;
		ii++;
		ShortToChar(strMsgFst->wBrakeIndex, &szCrcTmp[ii]);
		ii += 2u;
		LongToChar(strMsgFst->dwTime, &szCrcTmp[ii]);
		ii += 4u;
		szCrcTmp[ii] = strMsgFst->chType;
		ii++;
		strCfmFst->dwCrc32 = Tioc_CommonCrc32(szCrcTmp, ii);	/* ATS编号、车站编号、操作站编号、下发时间、命令类型计算CRC */

		if ((MSG_TYPE_WLB_SET == strMsgFst->chType) || (CONFIRM_WLB_FST_SUCCESS != strCfmFst->chOpStatus))
		{
			ClearAtsWlbMsgFirst();  /* 设置为一次命令或处理不成功，需清除一次命令 */
		}
		else
		{
			;
		}
	}
	else
	{/* 接收到ATS取消区间疏散一次消息非本周期，超时判断 */
		chFunRtn = SystemOverTimeCheck(strMsgFst->dwCycle, CONFIRM_TIMEOUT_CC);
		if (CI_TIME_OUT == chFunRtn)
		{
			ClearAtsWlbMsgFirst();
		}
		else
		{
			;
		}
	}
}

/**
* @brief 全线列车紧急制动二次命令处理函数
* @param 无
* @return 无
*/
static void WlbAtsCmdSnd(void)
{
	AtsWlbMsgStru * strMsgFst = NULL;
	AtsWlbMsgStru * strMsgSnd = NULL;
	AtsMsgCfmStru * strCfmFst = NULL;
	AtsMsgCfmStru * strCfmSnd = NULL;
	UINT32 dwCycle = 0u;
	UINT8 chLocalId = 0u;
	UINT8 chFlag = FLAG_UNSET;
	UINT8 szCrcTmp[1024] = { 0u };
	UINT32 ii = 0u;
	UINT32 dwCrc = 0u;

	chLocalId = GetSystemParaLocalCiId();
	dwCycle = Get2oo2CurCycleNum();
	strMsgFst = GetAtsWlbMsgFst();
	strMsgSnd = GetAtsWlbMsgSnd();
	strCfmFst = GetAtsWlbCfmFst();
	strCfmSnd = GetAtsWlbCfmSnd();

	if ((NULL != strMsgFst)
		&& (NULL != strMsgSnd)
		&& (NULL != strCfmFst)
		&& (NULL != strCfmSnd))
	{
		if (strMsgSnd->dwCycle == dwCycle)
		{
			strCfmSnd->chFlag = FLAG_SET;
			strCfmSnd->chTiocId = chLocalId;
			strCfmSnd->chStation = strMsgSnd->chStation;
			strCfmSnd->wIndex = strMsgSnd->wIndex;
			strCfmSnd->dwTime = dwCycle;

			if (FLAG_SET != strMsgFst->chFlag)
			{
				strCfmSnd->chOpStatus = CONFIRM_WLB_SND_FIRST;  /* 一次命令未执行，返回未执行首次取消 */
				chFlag = FLAG_SET;
			}
			else if ((strMsgSnd->chAtsId != strMsgFst->chAtsId)
				|| (strMsgSnd->chStation != strMsgFst->chStation)
				|| (strMsgSnd->wIndex != strMsgFst->wIndex))
			{
				strCfmSnd->chOpStatus = CONFIRM_WLB_SND_UNKNOWN;  /* ATS一二次命令帧头输入不一致，返回未知 */
				chFlag = FLAG_SET;
			}
			else if ((strMsgSnd->chBrakeType != strMsgFst->chBrakeType) || (strMsgSnd->wBrakeIndex != strMsgFst->wBrakeIndex))
			{
				strCfmSnd->chOpStatus = CONFIRM_WLB_SND_INFO_DIFF;  /* ATS一二次命令输入不一致，返回命令信息不一致 */
				chFlag = FLAG_SET;
			}
			else
			{
				/*不处理*/
				;
			}

			if (FLAG_UNSET == chFlag)
			{
				szCrcTmp[ii] = strMsgSnd->chTiocId;
				ii++;
				szCrcTmp[ii] = strMsgSnd->chBrakeType;
				ii++;
				szCrcTmp[ii] = strMsgSnd->chBrakeCount;
				ii++;
				ShortToChar(strMsgSnd->wBrakeIndex, &szCrcTmp[ii]);
				ii += 2u;
				LongToChar(strCfmFst->dwTime, &szCrcTmp[ii]);
				ii += 4u;
				szCrcTmp[ii] = strMsgSnd->chType;
				ii++;
				dwCrc = Tioc_CommonCrc32(szCrcTmp, ii);

				if (dwCrc != strMsgSnd->dwCrc32)
				{					
					strCfmSnd->chOpStatus = CONFIRM_WLB_SND_CRC;  /* 计算的CRC32与ATS二次消息CRC32不一致 */
					chFlag = FLAG_SET;
				}
				else
				{
					;
				}
			}
			else
			{
				;
			}

			ii = 0u;
			szCrcTmp[ii++] = strMsgSnd->chAtsId;
			szCrcTmp[ii++] = strMsgSnd->chStation;
			ShortToChar(strMsgSnd->wIndex, &szCrcTmp[ii]);
			ii += 2U;
			szCrcTmp[ii] = strMsgSnd->chBrakeType;
			ii++;
			szCrcTmp[ii] = strMsgSnd->chBrakeCount;
			ii++;
			ShortToChar(strMsgSnd->wBrakeIndex, &szCrcTmp[ii]);
			ii += 2u;
			LongToChar(strMsgFst->dwTime, &szCrcTmp[ii]);
			ii += 4u;
			LongToChar(strMsgSnd->dwTime, &szCrcTmp[ii]);
			ii += 4u;
			szCrcTmp[ii++] = strMsgSnd->chType;
			strCfmSnd->dwCrc32 = Tioc_CommonCrc32(szCrcTmp, ii);

			if (FLAG_UNSET == chFlag)
			{
				switch (strMsgSnd->chBrakeType)
				{
				case WLB_TYPE_RC:
					strCfmSnd->chOpStatus = CONFIRM_WLB_SND_SUCCESS;  /* 检查通过，反馈确认成功 */
					WlbSetState(WLB_UNSET);  /*设置全线紧急制动无效*/
					break;
				case WLB_TYPE_PHYSEC:
					strCfmSnd->chOpStatus = CONFIRM_WLB_SND_SUCCESS;  /* 检查通过，反馈确认成功 */
					SetPhySecAreaUrgentState(strMsgSnd->wBrakeIndex, PHYSEC_AREA_URGENT_NO);  /*设置区域紧急制动无效*/
					break;
				default:
					strCfmSnd->chOpStatus = CONFIRM_WLB_SND_UNKNOWN;  /* 类型不正确，返回未知 */
					break;
				}				
			}
			else
			{
				;
			}
		}
		else
		{
			; /** 非本周期消息，不处理 */
		}
		ClearAtsWlbMsgFirst();
		ClearAtsWlbMsgSecond();
	}
	else
	{
		; /**不可能分支 不处理 */
	}
}

/**
* @brief 获取全线列车紧急制动跟随数据
* @param UINT8 *pDataBuff 跟随数据存储缓冲区
* @param UINT32 curIndex 当前索引
* @return 计算后的索引
*/
UINT32 WlbGetTransferData(OUT UINT8 *pDataBuff, IN UINT32 curIndex)
{
	UINT32 ret = curIndex;
	
	if (NULL != pDataBuff)
	{
		pDataBuff[curIndex] = g_WlbState;
		ret++;
	}
	else
	{
		;
	}

	return ret;
}

/**
* @brief 设置全线列车紧急制动跟随数据
* @param UINT8 *pDataBuff 跟随数据存储缓冲区
* @param UINT32 curIndex 当前索引
* @return 计算后的索引
*/
UINT32 WlbSetTransferData(OUT UINT8 *pDataBuff, IN UINT32 curIndex)
{
	UINT32 ret = curIndex;

	if (NULL != pDataBuff)
	{
		g_WlbState = pDataBuff[curIndex];
		ret++;
	}
	else
	{
		;
	}

	return ret;
}

/**
* @brief ZC发送紧急制动处理
* @param  UINT8 wlbValidFlag;	全线紧急有效标志 aa有效
* @param  UINT8 secEbSum; 区间紧急制动数量
* @param  UINT16* ebPhySecId 区间紧急制动区段数组
* @return 无
*/
void WlbZcCmdProc(UINT8 wlbValidFlag, UINT8 secEbSum, UINT16* ebPhySecId)
{
	UINT8 ii = 0U;
	UINT8 cTiocId = 0u;
	UINT16 wPhySecSum = 0u; /*物理区段总数*/
	UINT8 belongCiId = 0U;
	UINT16 wPhySecId = 0U;
	if (NULL != ebPhySecId)
	{
		if ((WLB_UNSET == wlbValidFlag) || (WLB_SET == wlbValidFlag))
		{
			WlbSetState(wlbValidFlag);  /*设置全线紧急制动状态用于组包给车*/
		}
		/*仅通信有效会调用 清空区域紧急制动*/
		cTiocId = GetSystemParaLocalCiId();
		wPhySecSum = GetPhySecCurSum(); /*获取物理区段总数*/
		for (ii = 0u; ii < wPhySecSum; ii++)
		{
			wPhySecId = GetPhySecId(ii);
			belongCiId = GetPhySecBelongCiId(wPhySecId);
			if ((0u != wPhySecId) && (UINT16_MAX != wPhySecId) && (belongCiId == cTiocId))
			{
				(void)SetPhySecAreaUrgentState(wPhySecId, PHYSEC_AREA_URGENT_NO);  /*设置区域紧急制动无效*/
			}
		}
		/*根据ZC设置区域紧急制动信息*/
		if ((0U < secEbSum) && (ZC_TO_CI_EB_MAX >=secEbSum))
		{
			for (ii = 0U; ii < secEbSum; ii++)
			{
				SetPhySecAreaUrgentState(ebPhySecId[ii], PHYSEC_AREA_URGENT_YES);
			}
		}
	}
}