#include "WLScreenDataPrepare.h"
#include <stdarg.h>
#include "2oo2InterfaceDataManage.h"
#include "SystemParameterManage.h"
#include "DeviceDataManage.h"
#include "../Transmit/TransmitStateDataManage.h"
#include "EnvelopeManageAPI.h"
#include "AxisAssertManageAPI.h"
#include "ELMDataPrepare.h"
#include "AxisSectionConfigDataManage.h"


/* ================================静态函数=================================== */
static UINT8 wls_JudgeAChasUT(UINT16 acid);    /** 判断计轴上是否存在隐藏车 */


/**
 * @brief 静态函数：判断计轴上是否存在隐藏车
 * @param[in] UINT16 acid 计轴ID
 * @param[out] 无
 * @return CI_ERROR:存在隐藏车； CI_SUCCESS:不存在隐藏车
 * @note 无
 */
static UINT8 wls_JudgeAChasUT(UINT16 acid)
{
	UINT8 ret = CI_ERROR;
	UINT32 errorCode = 0u;
	UINT8 cycleELM = 0u;
	UINT8 acRedunStatus = AAM_API_AC_UT;
	const EnvelopeStruct* pELMInfo = NULL;
	UINT8 envelopeCnt = CI_ERROR;
	UINT16 envelopeIDs[SECTION_REL_ENVELOPE_SUM_MAX] = {0u};

	/** 获取计轴关联的包络信息 */
	envelopeCnt = elm_GetEnvelopeIDsInAC(acid,envelopeIDs);
	ASSER_ERROR(SECTION_REL_ENVELOPE_SUM_MAX <= envelopeCnt,errorCode,0x80000000u);

	/** 获取计轴冗余状态 */
	acRedunStatus = aam_GetACAssertStatus(acid);

	if ((0u == envelopeCnt) && ((AAM_API_AC_ARB == acRedunStatus) || (AAM_API_AC_REDUNARB == acRedunStatus)))
	{
		/** 计轴无包络，无需处理 */
	}
	else if (0u == envelopeCnt)
	{
		/** 计轴为非ARB和ARB冗余占用，导向安全侧 */
		errorCode += 0x40000000u;
	}
	else
	{
		for (cycleELM = 0u; cycleELM < envelopeCnt;cycleELM++)
		{
			pELMInfo = elm_GetEnvelopeInfoByID(envelopeIDs[cycleELM]);

			if ((NULL != pELMInfo) && 
				(TYPE_CT_ENVELOPE == pELMInfo->envelopeType) && 
				(0u == pELMInfo->headTrainID) && (0u == pELMInfo->tailTrainID))
			{
				/** 未有隐藏车进入 */
			}
			else
			{
				break;
			}
		}

		/** 计轴为非ARB和ARB冗余占用，导向安全侧 */
		ASSER_ERROR(envelopeCnt != cycleELM,errorCode,0x10000000u);
	}

	/** 设置函数返回值 */
	ASSERT_SETRET(0u == errorCode,ret,CI_SUCCESS,CI_ERROR);
	return ret;
}

/**
 * @brief 打印Debug信息
 * @param[in] UINT8 level 日志级别
 * @param[in] const char *fmt 打印信息
 * @return 无
 * @note 通过调用外部接口，实现本模块的打印
 */
void wls_PrintDebugInfo(UINT8 level,const char *fmt, ...)
{
	va_list para;
	CHAR tmpPrintBuf[WLS_PRINT_LEN] = {'\0'};

	if (WLS_LOG_LEVEL >= level)
	{
		va_start(para,fmt);
		(void)vsnprintf(tmpPrintBuf,WLS_PRINT_LEN,fmt,para);
		va_end(para);

		debug_infor_printf((const)"%s",tmpPrintBuf);
	}
	else
	{
		/** 日志级别不够*/
	}	
}


/**
 * @brief 获取全线免筛功能开关
 * @param[in] 无
 * @param[out] 无
 * @return CI_SUCCESS 功能打开；CI_ERROR 功能关闭
 * @note 
 */
UINT8 wls_PrepareWLSFunSwitch(void)
{
	UINT8 ret = CI_ERROR;
	UINT8 funRtn = GetWLSFunSwitch();
	
	if (0xaaU == funRtn)
	{
		ret = CI_SUCCESS;
	}
	else
	{
		/** 免筛功能关闭 */
	}

	return ret;
}


/**
 * @brief 判断本OC是否为具有免筛属性的TIOC 
 * @param[in] 无
 * @param[out] 无
 * @return CI_SUCCESS 具有免筛属性；CI_ERROR 不具有免筛属性
 * @note 无
 */
UINT8 wls_PrepareisWLSTioc(void)
{
	/** 获取本OCid */
	UINT8 localOCid = GetSystemParaLocalCiId();
	UINT8 flag = GetWLScreenTypeById(localOCid);

	return (TIOC_WLSCTEEN_VALID == flag) ? CI_SUCCESS : CI_ERROR;
}

/**
 * @brief 获取本OC是否上电解封解锁
 * @param[in] 无
 * @param[out] 无
 * @return CI_SUCCESS 已上电解封解锁；CI_ERROR 未上电解封解锁
 * @note 
 */
UINT8 wls_PrepareTIOCWorkStatus(void)
{
	UINT8 ret = CI_ERROR;
	UINT8 flockFlag = CI_START_FLOCK_NO;
	UINT8 lockFlag = CI_START_LOCK_NO;

	flockFlag = GetStartFLockFlag();
	lockFlag = GetStartLockFlag();

	if ((CI_START_FLOCK_NO == flockFlag) && (CI_START_LOCK_NO == lockFlag))
	{
		ret = CI_SUCCESS;
	}
	else
	{
		/** 不处理 */
	}

	return ret;
}


/**
 * @brief 获取入口检测计轴状态
 * @param[in] 无
 * @param[out] 无
 * @return CI_SUCCESS 入口检测正常；CI_ERROR 入口检测异常
 * @note 
 */
UINT8 wls_PrepareEnterACStatus(void)
{
	UINT8 ret = CI_ERROR;
	UINT32 errorCode = 0u;
	UINT8 isHaveUT = CI_ERROR;
	UINT16* pACIdBuff = NULL;
	UINT16 tempACCnt = 0u;
	UINT16 cycle = 0u;
	UINT8 localOCid = 0u;
	UINT8 acBelongOcid = 0u;
	UINT8 enterACFlag = 0u;
	UINT8 acOCCStatus = ELM_AC_OCC;

	/** 获取本集中区计轴区段 */
	tempACCnt = GetLocalCiAxisSectionIdBuf(&pACIdBuff);

	if ((0u == tempACCnt) || (AXIS_SECTION_SUM_MAX <= tempACCnt))
	{
		/** 查询错误 */
	}
	else
	{
		for (cycle = 0u; cycle < tempACCnt;cycle++)
		{
			/** 获取本OCid */
			localOCid = GetSystemParaLocalCiId();

			/** 获取计轴所属OC id 不超过255*/
			acBelongOcid = (UINT8)GetAxisBelongTioc(pACIdBuff[cycle]);
			ASSERT_BREAK((0u == localOCid) || (0u == acBelongOcid),errorCode,0x80000000u);

			acOCCStatus = elm_PrepareACStatus(pACIdBuff[cycle]);

			/** 获取计轴入口检测属性*/
			enterACFlag = GetAxisSecEntranceFlag(pACIdBuff[cycle]);

			if ((localOCid == acBelongOcid) && (AXIS_SEC_ENTRANCE_YES == enterACFlag) && (ELM_AC_OCC == acOCCStatus))
			{
				isHaveUT = wls_JudgeAChasUT(pACIdBuff[cycle]);
				ASSERT_BREAK(CI_ERROR == isHaveUT,errorCode,0x40000000u);
			}
			else
			{
				/** 计轴空闲无需处理 */
			}
		}

		/** 设置函数返回值 */
		ASSERT_SETRET(cycle == tempACCnt,ret,CI_SUCCESS,CI_ERROR);
	}

	return ret;
}

/**
 * @brief 获取当前周期
 * @param[in] 无
 * @param[out] 无
 * @return 当前周期
 * @note 无
 */
UINT32 wls_PrePareCurCycle(void)
{
	return Get2oo2CurCycleNum();
}


/**
 * @brief 获取与TMC通信状态
 * @param[in] 
 * @param[out]
 * @return CI_SUCCESS 通信正常；CI_ERROR 通信异常
 * @note 
 */
UINT8 wls_PrepareCommStatusWithTMC(void)
{
	UINT8 ret = CI_ERROR;
	UINT8 comstatus = TRANSMIT_STATE_BAD;
	UINT8 deviceSum = 0u;
	UINT8* deviceIdBuf = NULL;

	deviceSum = GetCiTransmitSpecifySysDevSum(CI_SYSTEM_TYPE_TMC); /*获取通信TMC设备总数*/
	deviceIdBuf = GetCiTransmitSpecifySysDevBuf(CI_SYSTEM_TYPE_TMC); /*获取通信TMC设备ID数组*/

	if (1u == deviceSum)
	{
		comstatus = GetCiTransmitState(CI_SYSTEM_TYPE_TMC,deviceIdBuf[0u]);

		if (TRANSMIT_STATE_GOOD == comstatus)
		{
			ret = CI_SUCCESS;
		}
		else
		{
			/** 通信异常 */
		}
	}
	else
	{
		/** 不支持TIOC对应多个TMC */
	}

	return ret;
}

/**
* @brief 获取本OC及公管区内的UT或者UT冗余计轴区段
* @param[in] 无
* @param[out] UINT16 acID[MAX_UT_AC_CNT] UT计轴ID
* @return 0~MAX_UT_AC_CNT-1 合法值；MAX_UT_AC_CNT 非法值
* @note 无
*/
UINT8 wls_PrepareUTACInOCArea(UINT16 acID[MAX_UT_AC_CNT])
{
	/*- 局部变量定义 */
	UINT8 ret = MAX_UT_AC_CNT;
	UINT32 errorCode = 0u;                         /*错误码*/
	UINT8 UTACCnt = 0u;
	UINT8 isHaveUT = CI_ERROR;
	UINT16 cycle = 0u;
	UINT16 acCnt = 0u;                             /*OC范围内所有的计轴区段数量*/
	UINT8 acStatus = ELM_AC_OCC;
	const UINT16 *pACIdbuff = NULL;        /** 计轴ID数值缓存 */
	UINT8 localOCid = 0u;
	UINT8 acBelongOcid = 0u;
	UINT8 cycleELM = 0u;
	UINT8 acRedunStatus = AAM_API_AC_UT;
	const EnvelopeStruct* pELMInfo = NULL;
	UINT8 envelopeCnt = CI_ERROR;
	UINT8 AxisLinXian = 0U;
	UINT16 envelopeIDs[SECTION_REL_ENVELOPE_SUM_MAX] = {0u};
	UINT8 cStorageLineProperty = AXIS_SEC_STORAGE_LINE_NO;  /*存车线属性，初始化为非存车线*/

	/** 入口参数校验 */
	ASSERT_RET_VALUE(NULL == acID,ret,0x80000000u);

	/** 获取OC范围内所有的计轴区段数组索引 */
	acCnt = elm_PrepareACBuffIndexs(&pACIdbuff);

	/** 判断是否查询成功 */
	if ((0u == acCnt) || (acCnt >= AXIS_SECTION_SUM_MAX) || (NULL == pACIdbuff))
	{
		/** 查询错误 */
	}
	else
	{

		/** 获取本OCid */
		localOCid = GetSystemParaLocalCiId();

		/** 遍历OC集中区所有的计轴区段索引*/
		for (cycle = 0u; cycle < acCnt; cycle++)
		{
			/** 本集中区计轴判断是否为UT或者UT冗余计轴，相邻TIOC判断是否计轴上存在UKT或者存在未完成筛选的包络*/
			acStatus = elm_PrepareACStatus(pACIdbuff[cycle]);
			AxisLinXian = GetAxisSecLinXianFlag(pACIdbuff[cycle]);  /*检查计轴是否具有临线属性(非本线路)*/
			cStorageLineProperty = GetAxisSecStorageLineProperty(pACIdbuff[cycle]);   /*检查计轴区段是否具有存车线属性*/
			if ((ELM_AC_OCC == acStatus) && (AXIS_SEC_LINXIAN_NO == AxisLinXian) && (AXIS_SEC_STORAGE_LINE_YES != cStorageLineProperty))		/*本线路的占压才需要检查设置*/
			{
				/** 获取计轴所属OC id 不超过255*/
				acBelongOcid = (UINT8)GetAxisBelongTioc(pACIdbuff[cycle]);
				ASSERT_BREAK((0u == localOCid) || (0u == acBelongOcid), errorCode, 0x80000000u);

				/** 获取计轴关联的包络信息 */
				envelopeCnt = elm_GetEnvelopeIDsInAC(pACIdbuff[cycle], envelopeIDs);
				ASSERT_BREAK(SECTION_REL_ENVELOPE_SUM_MAX <= envelopeCnt, errorCode, 0x40000000u);

				/** 获取计轴冗余状态 */
				acRedunStatus = aam_GetACAssertStatus(pACIdbuff[cycle]);

				if (localOCid == acBelongOcid)
				{
					if ((0u == envelopeCnt) && ((AAM_API_AC_ARB == acRedunStatus) || (AAM_API_AC_REDUNARB == acRedunStatus)))
					{
						/** 计轴无包络，无需处理 */
					}
					else if (0u == envelopeCnt)
					{
						/** 计轴为非ARB和ARB冗余占用，导向安全侧 */
						if (UTACCnt < (MAX_UT_AC_CNT - 1u))
						{
							acID[UTACCnt++] = pACIdbuff[cycle];
						}
						else
						{
							UTACCnt = MAX_UT_AC_CNT;
						}
					}
					else
					{
						for (cycleELM = 0u; cycleELM < envelopeCnt; cycleELM++)
						{
							pELMInfo = elm_GetEnvelopeInfoByID(envelopeIDs[cycleELM]);

							if ((NULL != pELMInfo) &&
								(TYPE_UKT_ENVELOPE == pELMInfo->envelopeType))
							{
								break;
							}
							else
							{
								/** 无需处理 */
							}
						}

						/** 存在纯UT计轴 */
						if (cycleELM != envelopeCnt)
						{
							/** 计轴为非ARB和ARB冗余占用，导向安全侧 */
							if (UTACCnt < (MAX_UT_AC_CNT - 1u))
							{
								acID[UTACCnt++] = pACIdbuff[cycle];
							}
							else
							{
								UTACCnt = MAX_UT_AC_CNT;
							}
						}
						else
						{
							/** 不存在UT，不需要处理 */
						}
					}
				}
				else
				{
					for (cycleELM = 0u; cycleELM < envelopeCnt; cycleELM++)
					{
						pELMInfo = elm_GetEnvelopeInfoByID(envelopeIDs[cycleELM]);

						if ((NULL != pELMInfo) &&
							(TYPE_UKT_ENVELOPE != pELMInfo->envelopeType) &&
							(0u == pELMInfo->headTrainID) && (0u == pELMInfo->tailTrainID))
						{
							/** 未有隐藏车进入 */
						}
						else
						{
							break;
						}
					}

					/** 相邻公共区存在UT计轴 */
					if (cycleELM != envelopeCnt)
					{
						/** 计轴为非ARB和ARB冗余占用，导向安全侧 */
						if (UTACCnt < (MAX_UT_AC_CNT - 1u))
						{
							acID[UTACCnt++] = pACIdbuff[cycle];
						}
						else
						{
							UTACCnt = MAX_UT_AC_CNT;
						}
					}
					else
					{
						/** 不存在UT，不需要处理 */
					}
				}
			}
			else
			{
				/** 无需处理 */
			}
		}

		/** 设置返回值 */
		ret = UTACCnt;
	}

	return ret;
}

/**
 * @brief 获取免筛处理建立冗余时间
 * @param[in] 无
 * @param[out] 无
 * @return 无
 * @note 无
 */
UINT32 wls_PrepareRedunTime(void)
{
	return GetTiocAndTmcTransBadEnsureCnt();
}

/**
* @brief 查找指定计轴上列车是否前端可疑
* @param[in] UINT16 envelopeID 包络ID
* @param[out] 无
* @return FLAG_SET 无前端可疑
          FLAG_UNSET 有前端可疑
* edit cgh 20241009
*/
UINT8 elm_CheckTrainheadTrain(UINT16 axisId, UINT16 trainId)
{
	UINT8 flag = 0U;
	UINT8 u8Ret = FLAG_UNSET;
	UINT16 cycIndex = 0U;
	UINT16 Val = 0U;
	const EnvelopeStruct* pEnvelope = NULL;
	UINT8 envelopeCnt = CI_ERROR;
	UINT16 envelopeIDs[SECTION_REL_ENVELOPE_SUM_MAX] = { 0u };
	UINT8 chVirHeadScreenPassFlag = 0U;/*虚拟前筛标志*/

	/** 获取计轴关联的包络信息 */
	envelopeCnt = elm_GetEnvelopeIDsInAC(axisId, envelopeIDs);

	for (cycIndex = 0U; cycIndex < envelopeCnt; cycIndex++)
	{
		/*获取包络*/
		pEnvelope = elm_GetEnvelopeInfoByID(envelopeIDs[cycIndex]);
		if (NULL != pEnvelope)
		{
			/**在所有包络中根据ID查找CT车包络**/
			if ((TYPE_CT_ENVELOPE == pEnvelope->envelopeType) && (trainId == pEnvelope->trainID[0]))
			{
				chVirHeadScreenPassFlag = GetTrainVirHeadScreenPassFlag(trainId);

				if (TRAIN_VIR_SCREEN_PASS_FLAG_VALID != chVirHeadScreenPassFlag)
				{
					/* 虚拟筛选标志无效，则包络有可疑输出实际可疑 */
					Val = pEnvelope->headTrainID;
				}
				else
				{
					/* 虚拟筛选标志有效，输出无可疑 */
					Val = 0U;
				}
				break;
			}
			else
			{
				;
			}
		}
	}
	if (LINE_MAX_TRAIN != Val)
	{
		u8Ret = FLAG_SET;
	}
	else
	{
		u8Ret = FLAG_UNSET;
	}

	/*- 返回头筛状态*/
	return u8Ret;
}

/**
* @brief 查找指定计轴上列车是否后端可疑
* @param[in] UINT16 envelopeID 包络ID
* @param[out] 无
* @return FLAG_SET 无后端可疑
		  FLAG_UNSET 有后端可疑
* edit cgh 20241009
*/
UINT8 elm_CheckTrainTailTrain(UINT16 axisId, UINT16 trainId)
{
	UINT8 flag = 0U;
	UINT8 u8Ret = FLAG_UNSET;
	UINT16 cycIndex = 0U;
	UINT16 Val = 0U;
	const EnvelopeStruct* pEnvelope = NULL;
	UINT8 envelopeCnt = CI_ERROR;
	UINT16 envelopeIDs[SECTION_REL_ENVELOPE_SUM_MAX] = { 0u };
	UINT8 chVirTailScreenPassFlag = 0U;/*虚拟后筛标志*/

	/** 获取计轴关联的包络信息 */
	envelopeCnt = elm_GetEnvelopeIDsInAC(axisId, envelopeIDs);

	for (cycIndex = 0U; cycIndex < envelopeCnt; cycIndex++)
	{
		/*获取包络*/
		pEnvelope = elm_GetEnvelopeInfoByID(envelopeIDs[cycIndex]);
		if (NULL != pEnvelope)
		{
			/**在所有包络中根据ID查找CT车包络**/
			if ((TYPE_CT_ENVELOPE == pEnvelope->envelopeType) && (trainId == pEnvelope->trainID[0]))
			{
				chVirTailScreenPassFlag = GetTrainVirTailScreenPassFlag(trainId);

				if (TRAIN_VIR_SCREEN_PASS_FLAG_VALID != chVirTailScreenPassFlag)
				{
					/* 虚拟筛选标志无效，则包络有可疑输出实际可疑 */
					Val = pEnvelope->tailTrainID;		
				}
				else
				{
					/* 虚拟筛选标志有效，输出无可疑 */
					Val = 0U;
				}
				break;
			}
			else
			{
				;
			}
		}
	}
	if (LINE_MAX_TRAIN != Val)
	{
		u8Ret = FLAG_SET;
	}
	else
	{
		u8Ret = FLAG_UNSET;
	}

	/*- 返回状态*/
	return u8Ret;
}


