/******************************************************************************
** 文件名:  UKTEnvelopeTrack.c
** 描 述:   实现UKT包络的追踪处理
*******************************************************************************/
#include "EnvelopeLogicProcess.h"

/**
 * @brief 隐藏车包络跟踪管理
 * @note 
 *   1、从EnvelopeManageAPI.c拆分到此文件中，代码未修改
 */
void elm_UKTEnvelopeTrack(void)
{
	/*- 局部变量定义 */
	UINT8 funFlag = CI_ERROR;                      /*函数执行返回值*/
	UINT16 cycle = 0u;
	UINT32 errorCode = 0u;                         /*错误码*/
	UINT16 acCnt = 0u;                             /*OC范围内所有的计轴区段数量*/
	UINT8 OCId = 0u;
	UINT8 acStatus = ELM_AC_OCC;
	UINT8 acAssertStatus = AAM_API_AC_UT;
	const UINT16 *pACIdbuff = NULL;        /** 计轴ID数值缓存 */

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

	/** 判断是否查询成功 */
	if (0u == acCnt)
	{
		/** 查询失败，OC范围内不可能不存在计轴区段 */
		elm_SetELMWorkFlag(ELM_WORK_ERROR);
		errorCode = errorCode + 0x80000000u;
		ELM_LOG_LOC(ELM_LOG_ERROR,"errno:0x%08x info:Get ACID Buff error!",errorCode)
	}
	else
	{
		/** 遍历OC集中区所有的计轴区段索引*/
		for (cycle = 0u; cycle < acCnt; cycle++)
		{
			/** 判断计轴区段是否属于本OC */
			funFlag = elm_PrepareACIsSelf(pACIdbuff[cycle],&OCId);

			if (ELM_BELONG_OTHER == funFlag)
			{
				/** 不属于本OC，不处理 */
			}
			else
			{
				/** 获取计轴占用状态 */
				acStatus = elm_PrepareACStatus(pACIdbuff[cycle]);

				if (ELM_AC_OCC == acStatus)
				{
					/** 获取冗余时间 */
					acAssertStatus = elm_PrepareACAssertStatus(pACIdbuff[cycle]);

					if ((AAM_API_AC_ARB == acAssertStatus) || (AAM_API_AC_REDUNARB == acAssertStatus) || (AAM_API_AC_REDUNUT == acAssertStatus))
					{
						/** 计轴冗余期间，不添加故障包络*/
						ELM_LOG(ELM_LOG_FATAL,"info:ac%d no add UKT because AssertStatus:%d.\n",pACIdbuff[cycle],acAssertStatus);
					}
					else
					{
						/*- 在占用无其他包络的计轴上添加UKT包络 */
						funFlag = elm_AddUKTEnvelopeInAC(pACIdbuff[cycle]);

						/** 判断是否执行正确 */
						if (CI_ERROR == funFlag)
						{
							/** 函数执行错误，需要设置该模块无法正常处理标志位 */
							elm_SetELMWorkFlag(ELM_WORK_ERROR);
							ASSER_ERROR(CI_ERROR == funFlag,errorCode,0x40000000u)
								ASSER_DEBUG(0u != errorCode,ELM_LOG_LOC(ELM_LOG_ERROR,"errno:0x%08x info:ac%d add UKT error.",errorCode,pACIdbuff[cycle]))
						}
						else
						{
							/** 处理正确，继续处理*/
						}
					}
				}
				else
				{
					/** 空闲不处理 */
				}
			}
		}
	}
}

/**
 * @brief 根据计轴占用空闲状态清UKT包络
 * @note 
 *   1、从EnvelopeManageAPI.c拆分到此文件中，代码未修改
 */
void elm_ProcessFreeAC(void)
{
	/*- 局部变量定义 */
	UINT8 funRtn = CI_ERROR;
	UINT8 OCId = 0u;
	UINT16 cycle = 0u;
	UINT32 errorCode = 0u;                         /*错误码*/
	UINT16 acCnt = 0u;                             /*OC范围内所有的计轴区段数量*/
	const UINT16 *pACIdbuff = NULL;        /** 计轴ID数值缓存 */
	UINT16 tmpAcIndex = 0u; 
	UINT8 tmpStatus = ELM_AC_OCC;
	UINT8 cycleELM = 0u; 
	UINT8 acRelEnvelopeCnt = 0u;
	UINT16 acRelEnvelopeID[SECTION_REL_ENVELOPE_SUM_MAX] = {0u};
	const EnvelopeStruct* pEnvelope = NULL;

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

	/** 判断是否查询成功 */
	if (0u == acCnt)
	{
		/** 查询失败，OC范围内不可能不存在计轴区段 */
		errorCode = errorCode + 0x80000000u;
		elm_SetELMWorkFlag(ELM_WORK_ERROR);
		ELM_LOG_LOC(ELM_LOG_ERROR,"errno:0x%08x info:Get ACID Buff error!",errorCode)
	}
	else
	{
		/** 遍历OC集中区所有的计轴区段索引*/
		for (cycle = 0u; cycle < acCnt; cycle++)
		{
			/** 判断计轴区段是否属于本OC */
			funRtn = elm_PrepareACIsSelf(pACIdbuff[cycle],&OCId);

			if (ELM_BELONG_OWNER == funRtn)
			{
				/** 通过计轴数组索引查找计轴索引*/
				tmpAcIndex = elm_PrepareACIndex(pACIdbuff[cycle]);

				/** 通过计轴区段ID获取计轴状态*/
				tmpStatus = elm_PrepareACStatus(pACIdbuff[cycle]);

				/** 通过计轴数组索引获取关联的包络个数 */
				acRelEnvelopeCnt = elm_GetACRelEnvelopeCnt(tmpAcIndex, acRelEnvelopeID);
				ASSERT_BREAK(SECTION_REL_ENVELOPE_SUM_MAX == acRelEnvelopeCnt,errorCode,0x40000000u);

				/** 如果计轴空闲且包络只有一个，则判断是否为UKT包络，如果是，则清除*/
				if (ELM_AC_FREE== tmpStatus)
				{
					/** 删除空闲计轴上的UKT包络，一个计轴肯定只存在一个UKT包络，但是此处如果真的有两个，进行容忍*/
					for (cycleELM = 0u; cycleELM < acRelEnvelopeCnt; cycleELM++)
					{
						/** 获取包络指针*/
						pEnvelope = elm_GetEnvelopeInfoPtr(acRelEnvelopeID[0]);
						ASSERT_BREAK(NULL == pEnvelope,errorCode,0x20000000u);

						if (TYPE_UKT_ENVELOPE == pEnvelope->envelopeType)
						{
							(void)elm_DeleteUKTEnvelope(pEnvelope);
						}
						else
						{
							/** 无需处理*/
						}
					}

					/** 判断处理是否成功 */
					ASSERT_BREAK(cycleELM != acRelEnvelopeCnt,errorCode,0x10000000u);
				}
				else
				{
					/** 无需处理*/
				}
			}
			else
			{
				/** 非本OC计轴，不处理*/
			}			
		}

		if (cycle == acCnt)
		{
			/** 处理无问题*/
		}
		else
		{
			elm_SetELMWorkFlag(ELM_WORK_ERROR);
			ELM_LOG_LOC(ELM_LOG_ERROR,"errno:0x%08x info:Clear AC%d ELM error!",errorCode,pACIdbuff[cycle]);
		}
	}
}