#include "WLScreenLogicProcess.h"
#include "WLScreenDataManage.h"
#include "WLScreenDataPrepare.h"
#include "EnvelopeManage.h"


/* ================================静态函数声明区==============================*/
static UINT8 wls_JudgeStatusChangeAndSus(void);      /* 判断列车状态是否发生改变需要刷新序列号 */
static UINT8 wls_JudgeNewUTACExist(void);            /* 判断新出现UT计轴需要刷新序列号*/


/**
 * @brief 判断列车状态是否发生改变需要刷新序列号
 * @param[in] 无
 * @param[out] 无
 * @return UNNEED_REFRESH 无需刷新序列号；NEED_REFRESH 需要刷新序列号；NEED_REFRESH_NOW 需要立刻刷新序列号
 * @note 无
 */
static UINT8 wls_JudgeStatusChangeAndSus(void)
{
	UINT8 ret = NEED_REFRESH_NOW;     /** 注意：此处返回值必须设置成UNNEED_REFRESH*/
	UINT32 errorCode = 0u;
	UINT16 cycle = 0u;
	const WLSreenInfoStruct *pTemp = NULL;
	const WLTrainStatusInfoStruct *pCurTrainInfo = NULL;
	const WLTrainStatusInfoStruct *pLastTrainInfo = NULL;

	pTemp = wls_GetWholeLineScreeInfo();

	/** 循环前设置为无需刷新序列号 */
	ret = UNNEED_REFRESH;
	for (cycle = 1u; cycle < LINE_MAX_TRAIN;cycle++)
	{
		pCurTrainInfo = wls_GetCurTrainStatusInfo(cycle);
		pLastTrainInfo = wls_GetLastTrainStatusInfo(cycle);
		ASSERT_BREAK((NULL == pCurTrainInfo) || (NULL == pLastTrainInfo),errorCode,0x40000000u);

		/** 前端状态监控 */
		if (OUT_CONTROL_STATUS != pCurTrainInfo->controlStatus)
		{
			/** 前端状态监控 */
			if ((UNNEED_SCREEN == pLastTrainInfo->headNeedScreen) && (NEED_SCREEN == pCurTrainInfo->headNeedScreen))
			{
				/** 状态发生变化 */
				ret = NEED_REFRESH_NOW;
				break;
			}
			else if (NEED_SCREEN == pCurTrainInfo->headNeedScreen)
			{
				ret = NEED_REFRESH;
			}
			else
			{
				/** 不需要筛选 */
			}

			/** 尾端状态监控 */
			if ((UNNEED_SCREEN == pLastTrainInfo->tailNeedScreen) && (NEED_SCREEN == pCurTrainInfo->tailNeedScreen))
			{
				/** 状态发生变化 */
				ret = NEED_REFRESH_NOW;
				break;
			}
			else if (NEED_SCREEN == pCurTrainInfo->tailNeedScreen)
			{
				ret = NEED_REFRESH;
			}
			else
			{
				/** 不需要筛选 */
			}

		}
		else
		{
			/** 非控区列车 */
		}

		/** 列车状态 */
		if (pLastTrainInfo->controlStatus != pCurTrainInfo->controlStatus)
		{
			ret = NEED_REFRESH_NOW;
			break;
		}
		else
		{
			/** 无需处理*/
		}
	}

	return ret;
}


/**
 * @brief 判断新出现UT计轴需要刷新序列号
 * @param[in] 无
 * @param[out] 无
 * @return UNNEED_REFRESH 无需刷新序列号；NEED_REFRESH 需要刷新序列号；NEED_REFRESH_NOW 需要立刻刷新序列号
 * @note 无
 */
static UINT8 wls_JudgeNewUTACExist(void)
{
	UINT8 ret = NEED_REFRESH_NOW;
	UINT8 funRtn = CI_ERROR;
	UINT8 lastUTACCnt = 0u;
	UINT16 tmpACid = 0u;
	UINT8 cyclelast = 0u;
	UINT8 cyclecur = 0u;
	UINT8 acCnt = 0u;
	UINT16 acID[MAX_UT_AC_CNT] = {0u};

	/** OC集中区及共管区是否存在UT或者UT冗余计轴 */
	acCnt = wls_PrepareUTACInOCArea(acID);

	if (MAX_UT_AC_CNT == acCnt)
	{
		ret = NEED_REFRESH_NOW;
	}
	else if (0u == acCnt)
	{
		funRtn = wls_SetUTACCnt(0u);
		for (cyclecur = 0u; cyclecur < MAX_UT_AC_CNT; cyclecur++)
		{
			funRtn = wls_SetUTACId(cyclecur,0u);
		}
		ret = UNNEED_REFRESH;
	}
	else
	{
		/** 获取上周期UT计轴数量 */
		lastUTACCnt = wls_GetUTACCnt();

		if ((MAX_UT_AC_CNT == lastUTACCnt) || (0u == lastUTACCnt))
		{
			ret = NEED_REFRESH_NOW;
		}
		else
		{
			/** 判断是否新产生UT计轴 */
			for (cyclecur = 0u; cyclecur < acCnt;cyclecur++)
			{
				for (cyclelast = 0u; cyclelast < lastUTACCnt; cyclelast++)
				{
					tmpACid = wls_GetUTACId(cyclelast);
					if (acID[cyclecur] == tmpACid)
					{
						break;
					}
				}

				/** 判断当前周期UT是否为新产生的UT */
				if (cyclelast == lastUTACCnt)
				{
					ret = NEED_REFRESH_NOW;
					break;
				}
				else
				{
					ret = NEED_REFRESH;
				}
			}
		}

		/** 更新上周期UT计轴信息 */
		funRtn = wls_SetUTACCnt(0u);
		for (cyclecur = 0u; cyclecur < MAX_UT_AC_CNT; cyclecur++)
		{
			funRtn = wls_SetUTACId(cyclecur,0u);
		}
		funRtn = wls_SetUTACCnt(acCnt);
		for (cyclecur = 0u; cyclecur < acCnt;cyclecur++)
		{
			funRtn = wls_SetUTACId(cyclecur,acID[cyclecur]);
		}
	}

	return ret;
}


/**
 * @brief 判断当前周期是否需要刷新序列号
 * @param[in] 无
 * @param[out] 无
 * @return 无
 * @note 无
 */
void wls_JudgeWLScreenSeqChange(void)
{
	UINT32 tmpCycle = 0u;
	UINT8 isNormalWork = CI_ERROR;
	UINT8 isEnterCheck = CI_ERROR;
	UINT8 isStatusChange = CI_ERROR;
	UINT8 isHaveUT = CI_ERROR;
	UINT8 reFreshSeq = CI_ERROR;
	UINT8 cFunRetVal = CI_ERROR;
	const WLSreenInfoStruct *pTemp = NULL;
	UINT8 chTrainNvramPosCheck = 0U; /*列车NVRAM位置标识*/

	pTemp = wls_GetWholeLineScreeInfo();

	/** TIOC未上电时周期刷新序列号 */
	isNormalWork = wls_PrepareTIOCWorkStatus();
	if (CI_ERROR == isNormalWork)
	{
		reFreshSeq = CI_SUCCESS;
	}
	else
	{
		/** 无需处理 */
	}

	/** 如果序列号为默认值刷新序列号 */
	if ((NULL == pTemp) || ((NULL != pTemp) && (0u == pTemp->sendSeq)))
	{
		reFreshSeq = CI_SUCCESS;
	}
	else
	{
		/** 无需处理 */
	}

	/** 获取入口检测计轴状态*/
	isEnterCheck = wls_PrepareEnterACStatus();
	if (CI_ERROR == isEnterCheck)
	{
		reFreshSeq = CI_SUCCESS;
		cFunRetVal = wls_SetEnterCheckFlag(ENTER_ERROR_FLAG);
	}
	else if ((NULL != pTemp) && (ENTER_ERROR_FLAG == pTemp->enterCheckFlag))
	{
		reFreshSeq = CI_SUCCESS;
		cFunRetVal = wls_SetEnterCheckFlag(ENTER_OK_FLAG);
	}
	else
	{
		/* 入口检查正常或者正常状态未变化，不处理 */
	}


	/** OC集中区及共管区是否存在UT或者UT冗余计轴 */
	isHaveUT = wls_JudgeNewUTACExist();

	/** 获取列车状态是否发生改变（列车前后隐藏车由无变有、受控车数量增加或者减少）*/
	isStatusChange = wls_JudgeStatusChangeAndSus();

	chTrainNvramPosCheck = CheckInControlTrainNvramPos();

	if (CI_ERROR == chTrainNvramPosCheck)
	{
		ELM_LOG(ELM_LOG_FATAL, " wls_SetUTFlag,because use nvram pos");
		reFreshSeq = CI_SUCCESS;
		cFunRetVal = wls_SetUTFlag(UNKNOWN_TRAIN_EXIST);
	}
	else
	{
		if ((NEED_REFRESH_NOW == isStatusChange) || (NEED_REFRESH_NOW == isHaveUT))
		{
			reFreshSeq = CI_SUCCESS;
			cFunRetVal = wls_SetUTFlag(UNKNOWN_TRAIN_EXIST);
		}
		else if (((NEED_REFRESH == isStatusChange) || (NEED_REFRESH == isHaveUT)) &&
			((NULL != pTemp) && (UNKNOWN_TRAIN_EXIST != pTemp->UTFlag)))
		{
			/** 此分支为安全防护分支，正常跑车应该无法进入 */
			reFreshSeq = CI_SUCCESS;
			cFunRetVal = wls_SetUTFlag(UNKNOWN_TRAIN_EXIST);
		}
		else if ((UNNEED_REFRESH == isStatusChange) && (UNNEED_REFRESH == isHaveUT) &&
			(NULL != pTemp) && (UNKNOWN_TRAIN_EXIST == pTemp->UTFlag))
		{
			cFunRetVal = wls_SetUTFlag(UNKNOWN_TRAIN_UNEXIST);
		}
		else
		{
			/** 维持之前状态 */
		}
	}
	
	/** 更新免筛序列号 */
	if (CI_SUCCESS == reFreshSeq)
	{
		tmpCycle = wls_PrePareCurCycle();
		wls_SetSendSeq(tmpCycle);
	}
	else
	{
		/** 无需处理 */
	}
}


/**
 * @brief 判断当前周期是否具备全线免筛
 * @param[in] 无
 * @param[out] 无
 * @return 无
 * @note 无
 */
void wls_JudgeWLScreenPermit(void)
{
	const WLSreenInfoStruct *pTemp = NULL;
	UINT8 cTiocWorkStatus = CI_ERROR;
	UINT32 redunTime = 0u;

	pTemp = wls_GetWholeLineScreeInfo();

	/* 获取上电标志 */
	cTiocWorkStatus = wls_PrepareTIOCWorkStatus();

	/** 获取免筛建立冗余时间 */
	redunTime = wls_PrepareRedunTime();

	/** TIOC已上电、TMC回复可免筛或者*/
	if ((CI_SUCCESS == cTiocWorkStatus) && (NULL != pTemp)
		&& (0u != pTemp->sendSeq) 
		&& (pTemp->sendSeq == pTemp->recvSeq) 
		&& (TMC_WLS_VALID == pTemp->WLScreenVaildFlag))
	{
		if (pTemp->redunTime < redunTime)
		{
			wls_AddRedunTime(redunTime);
		}
		else
		{
			wls_SetWLScreenProcessFlag(WHOLE_LINE_SCREEN_VAILD);
		}

	}
	else
	{
		wls_SetRedunTime(0u,redunTime);
		wls_SetWLScreenProcessFlag(WHOLE_LINE_SCREEN_UNVAILD);
	}
}

/**
 * @brief 检查受控车NVRAM位置标识
 * @param[in] 无
 * @param[out] 无
 * @return CI_ERROR 存在列车使用NVRAM位置
 *         CI_SUCCESS 所有列车均未使用NVRAM位置
 * @note by cgh 20250704
 */
UINT8 CheckInControlTrainNvramPos(void)
{
	UINT8 chReval = CI_ERROR;
	UINT16 wCycle = 0U;
	UINT8 chTrainNvramPosFlag = 0U; /*列车NVRAM位置标识*/
	UINT8 relEnvelopeCnt = TRAIN_REL_ENVELOPE_SUM_MAX;    /*列车关联的包络数量*/
	UINT16 relEnvelopeID[TRAIN_REL_ENVELOPE_SUM_MAX] = { 0u };  /*列车关联的包络索引*/
	const EnvelopeStruct* pEnvelopeInfo = NULL;

	for (wCycle = 1U; wCycle < LINE_MAX_TRAIN; wCycle++)
	{
		chReval = CI_SUCCESS;
		relEnvelopeCnt = elm_GetRelELIdByTrainID(wCycle, relEnvelopeID);

		if (1U == relEnvelopeCnt)
		{
			pEnvelopeInfo = elm_GetEnvelopeInfoPtr(relEnvelopeID[0u]);

			if ((NULL != pEnvelopeInfo) &&
				((TYPE_CT_ENVELOPE == pEnvelopeInfo->envelopeType) || (TYPE_UCT_ENVELOPE == pEnvelopeInfo->envelopeType)))
			{
				chTrainNvramPosFlag = GetTrainNvramPosFlag(wCycle);

				if (TRAIN_NVRAM_POS_FLAG_NO == chTrainNvramPosFlag)
				{
					; /*不使用NVRAM位置继续检查*/
				}
				else
				{
					chReval = CI_ERROR;
					break;
				}
			}
		}
		else
		{
			/* 无需处理 */
		}
	}

	return chReval;
}