#include "ospTypes.h"
#include "ospSwTimer.h"
#include "ospSem.h"
#include "ucp_printf.h"
#include <string.h>

#define OSP_TMR_TIME_SET    (1000)

OspSwTimer_t gOspSwTmrList[OSP_SW_TIMER_NUM];
lx_sem_t *   gOspSwTmrSem = NULL;

static void OspCheckTimer(OspSwTimer_t *pOspSwTimer)
{
    if (NULL == pOspSwTimer)
    {
        UCP_PRINT_ERROR("OspCheckTimer input parameter is NULL.\r\n");
        return ;
    }

    if (OSP_TMR_FREE == pOspSwTimer->u8Using)
    {
        return ;
    }

    /* 判定定时时间  */
    if (OSP_TMR_TIME_SET <= pOspSwTimer->u32RealTime)
    {
        /* 时间未到 */
        pOspSwTimer->u32RealTime = pOspSwTimer->u32RealTime - OSP_TMR_TIME_SET;
    }
    else
    {
        /* 根据定时器类型，修改定时器状态 */
        if (OSP_TMR_ONESHOT == pOspSwTimer->emTmrType)
        {
            /* 一次性定时器，则修改定时器状态 */
            pOspSwTimer->emTmrStatus = OSP_TMR_STOPED;
            pOspSwTimer->u32RealTime = 0;
        }
        else
        {
            /* 周期性定时器，则修改定时器的时间 */
            pOspSwTimer->u32RealTime = pOspSwTimer->u32TimeOut;
        }

        /* 定时到，调用注册时的定时器回调函数 */
        return pOspSwTimer->pfnTmrCallBack(pOspSwTimer->pArg);
    }
    return ;
}

static void OspTmrProc(void)
{
    uint8_t u8Loop = 0;
    for (u8Loop = 0; u8Loop < OSP_SW_TIMER_NUM; u8Loop++)
    {
        OspCheckTimer(&gOspSwTmrList[u8Loop]);
    }
}

uint64_t OspTimerTask(void)
{
    if (NULL == gOspSwTmrSem)
    {
        UCP_PRINT_ERROR("OspTimerTask gOspSwTmrSem is NULL.\r\n");
        return -OSP_ERROR;
    }
    osp_sem_take(gOspSwTmrSem, OSP_TMR_TIME_SET);
    //UCP_PRINT_ERROR("OspTimerTask osp_sem_take return %d\r\n", ret);
    OspTmrProc();
    return OSP_OK;
}

/* 定时器初始化函数：先初始化定时模块，后创建任务 */
int8_t OspTmrInit()
{
    /* 创建定时点链表 */
    memset(gOspSwTmrList, 0, sizeof(gOspSwTmrList));

    /* 创建定时点信号量 */
    gOspSwTmrSem = osp_semc_create(0);
    if (NULL == gOspSwTmrSem)
    {
        UCP_PRINT_ERROR("OspTmrInit call osp_semc_create return NULL.\r\n");
        return OSP_ERROR;
    }
    return OSP_OK;
}

/* 创建定时器 */
int8_t OspTmrCreate(const char*      pu8Name,
                        uint32_t        u32TimeOut,
                        OspTmrType      emTmrType,
                        OSP_CALLBACK    pfnTmrCallBack,
                        void*           pArg)
{
    uint8_t  u8Loop = 0;
    uint32_t u32TimerLen = 0;

    /* 找是否有空闲定时器 */
    for (u8Loop = 0; u8Loop < OSP_SW_TIMER_NUM; u8Loop++)
    {
        if (OSP_TMR_FREE == gOspSwTmrList[u8Loop].u8Using)
        {
            u32TimerLen = (uint32_t)strlen(pu8Name);
            u32TimerLen = OSP_GET_MIN(u32TimerLen, (OSP_SW_TIMER_NAME_LEN-1));
            memcpy(gOspSwTmrList[u8Loop].u8TmrName, pu8Name, u32TimerLen);

            gOspSwTmrList[u8Loop].u32RealTime = u32TimeOut;     /* 剩余时间=超时时间 */
            gOspSwTmrList[u8Loop].u32TimeOut  = u32TimeOut;     /* 超时时间 */
            gOspSwTmrList[u8Loop].emTmrStatus = emTmrType;
            gOspSwTmrList[u8Loop].pfnTmrCallBack = pfnTmrCallBack;
            gOspSwTmrList[u8Loop].pArg        = pArg;
            gOspSwTmrList[u8Loop].emTmrStatus = OSP_TMR_STOPED;
            gOspSwTmrList[u8Loop].u8Using     = OSP_TMR_BUSY;

            return (u8Loop);
        }
    }
    UCP_PRINT_DEBUG("OspTmrCreate no timer free.\r\n");
    return OSP_ERROR;
}

/* 删除定时器 */
int8_t OspTmrDelete(uint8_t u8TmrIndex)
{
    if (u8TmrIndex > OSP_SW_TIMER_NUM)
    {
        UCP_PRINT_ERROR("OspTmrDelete input parameter is error(%d).\r\n", u8TmrIndex);
        return OSP_ERROR;
    }

    if (OSP_TMR_FREE == gOspSwTmrList[u8TmrIndex].u8Using)
    {
        UCP_PRINT_ERROR("OspTmrDelete TmrIndex(%d) is free. Can't delete.\r\n", u8TmrIndex);
        return OSP_ERROR;
    }

    memset(&(gOspSwTmrList[u8TmrIndex]), 0, sizeof(OspSwTimer_t));
    return OSP_OK;
}

/* 启动定时器 */
int8_t OspTmrStart(uint8_t u8TmrIndex)
{
    if (u8TmrIndex > OSP_SW_TIMER_NUM)
    {
        UCP_PRINT_ERROR("OspTmrStart input parameter is error(%d).\r\n", u8TmrIndex);
        return OSP_ERROR;
    }

    /* 如果定时器已经运行，直接返回 */
    if (OSP_TMR_RUNING == gOspSwTmrList[u8TmrIndex].emTmrStatus)
    {
        return OSP_OK;
    }

    /* 更新定时器定时时间 */
    gOspSwTmrList[u8TmrIndex].u32RealTime = gOspSwTmrList[u8TmrIndex].u32TimeOut;

    /* 更新定时器状态 */
    gOspSwTmrList[u8TmrIndex].emTmrStatus = OSP_TMR_RUNING;
    return OSP_OK;
}

/* 停止定时器 */
int8_t OspTmrStop(uint8_t u8TmrIndex)
{
    if (u8TmrIndex > OSP_SW_TIMER_NUM)
    {
        UCP_PRINT_ERROR("OspTmrStop input parameter is error(%d).\r\n", u8TmrIndex);
        return OSP_ERROR;
    }

    /* 如果定时器已经运行，直接返回 */
    if (OSP_TMR_STOPED == gOspSwTmrList[u8TmrIndex].emTmrStatus)
    {
        return OSP_OK;
    }

    /* 更新定时器定时时间 */
    gOspSwTmrList[u8TmrIndex].u32RealTime = gOspSwTmrList[u8TmrIndex].u32TimeOut;

    /* 更新定时器状态 */
    gOspSwTmrList[u8TmrIndex].emTmrStatus = OSP_TMR_STOPED;
    return OSP_OK;
}


