/*
 * SFM_4x2.c
 *
 *  Created on: 2025年12月20日
 *      Author: 14284
 */

#include "SFM_4x2.h"
#include "CM_MQ.h"
#include "CM_Types.h"
#include "SFM_2x2.h"

#if 0
ENUM_CM_RETURN SFM_4x2_Get_2xStat(STRU_4x_CTRL_T *pCtrl);

#define SFM_LOG_SIZE (1024u * 5u) //状态汇总模块日志大小
ENUM_4x2_STATE_T s_4x2_State = ENUM_4x2_SHUTDOWN;	
static CM_UINT8 g_SendAppFollowType = 0u; //应用跟随类型





/**
* @brief 获取其他三系热备状态
* @param 无
* @details
* 通过其他三系的地的状态 判断是否为备或者宕机
* @ return  0 其他但系存在离线系  1 其三系都是备系
*/
static CM_UINT8 SFM_GetAreaPartnerState(void);
/**
 * @brief 初始化区域日志消息队列
 * @param 无
 * @details
 * 初始化用于4x2状态管理模块的日志消息队列，分配指定大小的内存空间
 * 队列大小由SFM_LOG_SIZE宏定义确定
 * @return ENUM_CM_RETURN 操作结果
 *         - ENUM_CM_TRUE: 初始化成功
 *         - ENUM_CM_FALSE: 初始化失败
 */
 ENUM_CM_RETURN Area_LogMQ_Init(void)
 {
	 return CM_MQ_Init(&s_4x2_LogMsgQ, (CM_UINT16)SFM_LOG_SIZE, (CM_UINT16)(SFM_LOG_SIZE));
 }

/**
 * @brief 处理并转发4x2模块日志
 * @param 无
 * @details
 * 从日志消息队列中读取日志数据，并通过基础日志发送接口进行输出
 * 循环处理直到队列为空为止
 * @return 无
 */
void SFM_4x2_LOG_Transition(void)
{
	ENUM_CM_RETURN rt = ENUM_CM_FALSE;
	CM_UINT8 buf[1024] = {0};
	CM_UINT16 len = 1024;
	while(1)
	{
		len = 1024;
		rt = CM_MQ_Read(&s_4x2_LogMsgQ, buf, (CM_UINT16*)&len);
		if(ENUM_CM_TRUE == rt)
		{
		    /*- 输出日志信息 */
		    (void)CFM_BaseLog_Send((CM_UINT8*)buf, len);
		}
		else
		{
			/*无处理*/
			break;
		}
	}
}
/**
 * @brief 更新4x2状态
 * @param 无
 * @details
 * 执行状态更新流程：
 * 1. 调用2x2状态变更处理
 * 2. 获取本地2x2状态
 * 3. 获取区域状态
 * 4. 进行状态决策计算
 * 5. 获取伙伴区域状态
 * @return 无
 */
void SFM_4x2_ChangeState(void)
{
	ENUM_AREA_STATE State_Area = 0; //区域状态
	ENUM_4x2_STATE_T State_2x2 = 0; //2x2状态

	SFM_2x2_ChangeState();
	/*获取2乘状态*/
	State_2x2 = SFM_GetLocal4x2State();
	/*获取地的状态*/
	State_Area = Area_Get_State();

	/*状态决策*/
	s_4x2_State = SFM_4x2_StateDecision(State_Area, State_2x2);

	SFM_GetAreaPartnerState();


}

/**
 * @brief 决策4x2状态
 * @details 根据区域状态和2x2临时状态，决定最终的4x2状态。
 *          如果区域为主且2x2临时状态为主，则为4x2主；
 *          如果区域为主且2x2临时状态为备，则为4x2备；
 *          如果区域为备且2x2临时状态为主或备，则为4x2备；
 *          如果区域为初始化或2x2临时状态为宕机，则为4x2宕机；
 *          其他情况，如果2x2临时状态为离线且区域状态高于离线，则将区域状态设为离线，并返回4x2离线。
 * @param[in] Area 区域状态
 * @param[in] State_2x2 2x2临时状态
 * @return 最终的4x2状态(主线程状态)
 *         - ENUM_4x2_MASTER: 主系状态
 *         - ENUM_4x2_SLAVE: 备系状态
 *         - ENUM_4x2_PRE_MASTER: 预主系状态
 *         - ENUM_4x2_SHUTDOWN: 关闭状态
 *         - ENUM_4x2_OFFLINE: 离线状态
 */
ENUM_4x2_STATE_T SFM_4x2_StateDecision(ENUM_AREA_STATE Area, ENUM_4x2_STATE_T State_2x2)
{
    ENUM_4x2_STATE_T rtn_state = ENUM_4x2_SHUTDOWN;  /* 默认返回关闭状态 */

    /* 如果区域为主且2x2临时状态为主，则返回4x2主 */
    if ((ENUM_AREA_MASTER == Area) && (ENUM_2x2_TEMP_MASTER == State_2x2))
    {
        rtn_state = ENUM_4x2_MASTER;
    }
    /* 如果区域为主且2x2临时状态为备，则返回4x2备 */
    else if ((ENUM_AREA_MASTER == Area) && (ENUM_4x2_SLAVE == State_2x2))
    {
        rtn_state = ENUM_4x2_SLAVE;
    }
    /* 如果区域为备且2x2临时状态为主或备，则返回4x2备 */
    else if ((ENUM_AREA_SLAVE == Area) && ((ENUM_2x2_TEMP_MASTER == State_2x2) || (ENUM_2x2_TEMP_SLAVE == State_2x2)))
    {
        rtn_state = ENUM_4x2_SLAVE;
    }
    /* 如果区域为初始化或2x2临时状态为宕机，则返回4x2宕机 */
    else if ((ENUM_AREA_SHUTDOWN == Area) || (ENUM_2x2_TEMP_SHUTDOWN == State_2x2))
    {
        rtn_state = ENUM_4x2_SHUTDOWN;
    }
    else if(ENUM_2x2_TEMP_PRE_MASTER == State_2x2)
    {
        rtn_state = ENUM_4x2_PRE_MASTER;
    }
    else
    {
        /* 返回4x2离线状态 */
        rtn_state = ENUM_4x2_OFFLINE;
    }

    MSCP_LOG_MSG("Local Area state = %d  2x = %d Final = %d\n",Area, State_2x2,rtn_state);
    return rtn_state;
}
#endif


