#include "code.h"
static _st_Init FaultCodeInit;
static uint16_t u16FaultCodeDtcCount = 0;
static uint16_t u16FaultCodeDtcCountBack = 0;
static uint16_t u16FaultCodeDtcCounttemp = 0;
static _st_FaultCode stFaultCode[MaxFaultCode] = {0};
static _st_FaultCode stFaultCodeBack[MaxFaultCode] = {0};
static _st_FaultCode stFaultCodetemp[MaxFaultCode] = {0};
static uint8_t u8FaultCodeValid = 0;
uint32_t Get_FaultCodeDtc1(void)
{
    uint32_t u16FaultCode = 0x0000;
    uint8_t DTCH1 = 0;
    uint8_t DTCM1 = 0;

    uint32_t DTC1 = 0;

    DTCH1 = Get_CAN_CH0_ID_402_Sig_ECU_DTCH1();
    DTCM1 = Get_CAN_CH0_ID_402_Sig_ECU_DTCM1();

    if (((DTCH1 & 0xF0) >> 4) >= 0xA)
    {
        DTC1 |= ((DTCH1 & 0xF0) >> 4) + 3;
    }
    else
    {
        DTC1 |= (DTCH1 & 0xF0) >> 4;
    }
    DTC1 <<= 8;
    if ((DTCH1 & 0xF) >= 0xA)
    {
        DTC1 |= (DTCH1 & 0xF) + 3;
    }
    else
    {
        DTC1 |= DTCH1 & 0xF;
    }
    DTC1 <<= 8;

    if (((DTCM1 & 0xF0) >> 4) >= 0xA)
    {
        DTC1 |= ((DTCM1 & 0xF0) >> 4) + 3;
    }
    else
    {
        DTC1 |= (DTCM1 & 0xF0) >> 4;
    }
    DTC1 <<= 8;
    if ((DTCM1 & 0xF) >= 0xA)
    {
        DTC1 |= (DTCM1 & 0xF) + 3;
    }
    else
    {
        DTC1 |= DTCM1 & 0xF;
    }

    if (DTC1 == 0)
    {
        return 0XFFFF;
    }

    u16FaultCode = DTC1;

    return u16FaultCode;
}

uint32_t Get_FaultCodeDtc2(void)
{
    uint32_t u16FaultCode = 0x0000;
    uint8_t DTCH2 = 0;
    uint8_t DTCM2 = 0;
    uint32_t DTC2 = 0;

    DTCH2 = Get_CAN_CH0_ID_402_Sig_ECU_DTCH2();
    DTCM2 = Get_CAN_CH0_ID_402_Sig_ECU_DTCM2();
    if (((DTCH2 & 0xF0) >> 4) >= 0xA)
    {
        DTC2 |= ((DTCH2 & 0xF0) >> 4) + 3;
    }
    else
    {
        DTC2 |= (DTCH2 & 0xF0) >> 4;
    }
    DTC2 <<= 8;
    if ((DTCH2 & 0xF) >= 0xA)
    {
        DTC2 |= (DTCH2 & 0xF) + 3;
    }
    else
    {
        DTC2 |= DTCH2 & 0xF;
    }
    DTC2 <<= 8;

    if (((DTCM2 & 0xF0) >> 4) >= 0xA)
    {
        DTC2 |= ((DTCM2 & 0xF0) >> 4) + 3;
    }
    else
    {
        DTC2 |= (DTCM2 & 0xF0) >> 4;
    }
    DTC2 <<= 8;
    if ((DTCM2 & 0xF) >= 0xA)
    {
        DTC2 |= (DTCM2 & 0xF) + 3;
    }
    else
    {
        DTC2 |= DTCM2 & 0xF;
    }

    if (DTC2 == 0)
    {
        return 0XFFFF;
    }

    u16FaultCode = DTC2;

    return u16FaultCode;
}

uint16_t Get_FaultCodeNum(void)
{
    uint16_t u16FaultCode = 0x0000;

    u16FaultCode = Get_CAN_CH0_ID_402_Sig_ECU_DTCAmnt();
    return u16FaultCode;
}

uint16_t Get_FaultCodeValid(void)
{
    return 1;
}

/**
 * @brief 故障码初始化函数
 */
void FaultCode_Init(void)
{
    uint16_t i = 0;
    for (i = 0; i < MaxFaultCode; i++)
    {
        stFaultCode[i].u16FaultCode = 0;
        stFaultCode[i].u16FaultCodeCount = 0;
        stFaultCodeBack[i].u16FaultCode = 0;
        stFaultCodeBack[i].u16FaultCodeCount = 0;
        stFaultCodetemp[i].u16FaultCode = 0;
        stFaultCodetemp[i].u16FaultCodeCount = 0;
    }

    FaultCodeInit.callbacks[DTC_1] = Get_FaultCodeDtc1;
    FaultCodeInit.callbacks[DTC_2] = Get_FaultCodeDtc2;
    FaultCodeInit.callbacks[DTC_3] = NULL;
    FaultCodeInit.FaultCodeVaildCbk = Get_FaultCodeValid;
    FaultCodeInit.FaultCodeNumCbk = Get_FaultCodeNum;

    u16FaultCodeDtcCountBack = 0;
    u8FaultCodeValid = 0;
}

/**
 * @brief 查询当前故障码是否存在
 * @param u32FaultCode 故障码
 * @param FaultCodeGrpup 故障码组
 * @param len 故障码组长度
 * @return 0:存在 1:不存在 2:无效故障码不存储
 */
uint8_t FaultCode_Check(const uint32_t u32FaultCode, const _st_FaultCode *FaultCodeGrpup, const uint16_t len)
{
    uint16_t i = 0;
    uint8_t Result = 1;

    if ((u32FaultCode == 0XFFFF) || (u32FaultCode == 0))
    {
        return 2;
    }

    if (len == 1)
    {
        return 1;
    }

    for (i = 0; i < len; i++)
    {
        if (u32FaultCode == FaultCodeGrpup[i].u16FaultCode)
        {
            Result = 0;
            return Result;
        }
    }

    return Result;
}

/**
 * 添加新的故障码到故障码数组中。
 * @param faultCodes 指向故障码数组的指针。
 * @param count 指向当前已添加故障码数量的指针。
 * @param faultCode 要添加的故障码。
 * @param len 实际故障码数量,用于检测数组中是否存在当前故障码
 * @note 如果故障码数组已满或者新的故障码已存在,则不添加。
 */
void AddNewFaultCode(_st_FaultCode *faultCodes, uint16_t *count, uint32_t faultCode, uint16_t len)
{
    if (*count >= MaxFaultCode || FaultCode_Check(faultCode, faultCodes, len) != 1)
    {
        return; // 数组已满或故障码已存在,不进行添加
    }
    faultCodes[*count].u16FaultCode = faultCode;
    (*count)++;
}

/**
 * @brief 故障码服务函数
 * @param Cycle 建议10ms调用 防止故障码数量过多 接收缓慢
 */
void FaultCode_Service(uint16_t Cycle)
{
    uint32_t Dtc1 = 0XFFFF;
    uint32_t Dtc2 = 0XFFFF;
    uint32_t Dtc3 = 0XFFFF;
    uint16_t FaultCodeSum = 0;
    uint16_t i = 0;
    uint32_t tempFaultCode = 0;
    uint16_t Vaild = 0;

    if (FaultCodeInit.callbacks[DTC_1] != NULL)
    {
        Dtc1 = FaultCodeInit.callbacks[DTC_1]();
    }

    if (FaultCodeInit.callbacks[DTC_2] != NULL)
    {
        Dtc2 = FaultCodeInit.callbacks[DTC_2]();
    }

    if (FaultCodeInit.callbacks[DTC_3] != NULL)
    {
        Dtc3 = FaultCodeInit.callbacks[DTC_3]();
    }

    if (FaultCodeInit.FaultCodeVaildCbk != NULL)
    {
        Vaild = FaultCodeInit.FaultCodeVaildCbk();
    }

    if (FaultCodeInit.FaultCodeNumCbk != NULL)
    {
        FaultCodeSum = FaultCodeInit.FaultCodeNumCbk();
    }

    if (FaultCodeSum > MaxFaultCode)
    {
        FaultCodeSum = MaxFaultCode;
    }

    if ((Vaild) && (FaultCodeSum > 0))
    {
        if (u16FaultCodeDtcCountBack < FaultCodeSum) /* 当前存储故障码是否小于实际故障码数量 */
        {
            /* 存储故障码并检查数组中是否存在 */
            AddNewFaultCode(stFaultCodeBack, &u16FaultCodeDtcCountBack, Dtc1, FaultCodeSum);
            AddNewFaultCode(stFaultCodeBack, &u16FaultCodeDtcCountBack, Dtc2, FaultCodeSum);
        }

        /* 接收故障码大于0后进行显示 */
        if (u16FaultCodeDtcCountBack > 0)
        {
            /* 当前存储故障码等于实际故障码数量 用于实时更新故障码*/
            if (u16FaultCodeDtcCountBack == FaultCodeSum)
            {
                u16FaultCodeDtcCountBack = 0;
            }
            /* 更新故障码显示 */
            for (i = 0; i < FaultCodeSum; i++)
            {
                if (stFaultCodetemp[i].u16FaultCode != stFaultCodeBack[i].u16FaultCode)
                {
                    stFaultCodetemp[i].u16FaultCode = stFaultCodeBack[i].u16FaultCode;
                    stFaultCode[i].u16FaultCode = stFaultCodetemp[i].u16FaultCode;
                }
            }
            u8FaultCodeValid = 1;

            /* 大于故障码数量的数组进行清0处理 */
            for (i = FaultCodeSum; i < MaxFaultCode; i++)
            {
                stFaultCode[i].u16FaultCode = 0;
                stFaultCodetemp[i].u16FaultCode = 0;
                stFaultCodeBack[i].u16FaultCode = 0;
            }
        }

        if (stFaultCode[0].u16FaultCode != 0XFFFF)
        {
            /* 故障码计时 */
            if (stFaultCode[0].u16FaultCodeCount < FaultCodeCount)
            {
                stFaultCode[0].u16FaultCodeCount += Cycle;
            }
            else
            {
                /* 计时结束 更新位置 */
                stFaultCode[0].u16FaultCodeCount = 0;
                tempFaultCode = stFaultCode[0].u16FaultCode;

                if (FaultCodeSum > 1)
                {
                    for (i = 0; i < FaultCodeSum - 1; i++)
                    {
                        stFaultCode[i].u16FaultCode = stFaultCode[i + 1].u16FaultCode;
                    }
                    stFaultCode[FaultCodeSum - 1].u16FaultCode = tempFaultCode;
                }
            }
        }
    }
    else
    {
        u8FaultCodeValid = 0;
        for (i = 0; i < MaxFaultCode; i++)
        {
            stFaultCode[i].u16FaultCode = 0;
            stFaultCode[i].u16FaultCodeCount = 0;
            stFaultCodeBack[i].u16FaultCode = 0;
            stFaultCodeBack[i].u16FaultCodeCount = 0;
            stFaultCodetemp[i].u16FaultCode = 0;
            stFaultCodetemp[i].u16FaultCodeCount = 0;
        }
        u16FaultCodeDtcCountBack = 0;
    }
}

/**
 * @brief 获取当前故障码
 */
uint32_t Get_Current_FaultCode(void)
{
    return stFaultCode[0].u16FaultCode;
}

uint8_t Get_FaultCode_Valid(void)
{
    return u8FaultCodeValid;
}