#include "sr_config.h"


#include "sr_gpio.h"
#include "sr_key.h"

#include "sr_stddef.h"

#include "sr_osal.h"
#include "sr_shell.h"

#include "sr_utest.h"

static char keyArgs[] = "key args.";
static uint32_t startTick, endTick, i;
static float TotalTime, totalTimeSummary = 0;

char *getErrorString(int errorCode)
{
    switch (errorCode)
    {
    case SR_OK:
        return "SR_OK";
        break;
    case SR_FAIL:
        return "SR_FAIL";
        break;
    case SR_TIMEOUT:
        return "SR_TIMEOUT";
        break;
    case SR_FULL:
        return "SR_FULL";
        break;
    case SR_EMPTY:
        return "SR_EMPTY";
        break;
    case SR_NOMEM:
        return "SR_NOMEM";
        break;
    case SR_NOIMPT:
        return "SR_NOIMPT";
        break;
    case SR_BUSY:
        return "SR_BUSY";
        break;
    case SR_EIO:
        return "SR_EIO";
        break;
    case SR_INTR:
        return "SR_INTR";
        break;
    case SR_INVALID:
        return "SR_INVALID";
        break;
    case SR_NOEXIST:
        return "SR_NOEXIST";
        break;
    case SR_OPT_DENIED:
        return "SR_OPT_DENIED";
        break;
    case SR_ILL_ADDR:
        return "SR_ILL_ADDR";
        break;
    case SR_EKERNEL:
        return "SR_EKERNEL";
        break;
    case SR_ENET:
        return "SR_ENET";
        break;
    case SR_EINIT:
        return "SR_EINIT";
        break;
    case SR_ECALL:
        return "SR_ECALL";
        break;
    case SR_EBOUND:
        return "SR_EBOUND";
        break;

    default:
        break;
    }

    return SR_NULL;
}

void keyEventCallback(SR_KEY_ID_E id, SR_KEY_EVT_E evt, uint16_t time, void *args)
{
    endTick = SR_GetTickUs();
    TotalTime = SR_TICK_TO_US(endTick - startTick);
    totalTimeSummary += TotalTime;
    SR_LOG(INFO, "[keyTime]startTick:%u, endTick:%u, totalTime:%f us", startTick, endTick, TotalTime);
    if (i >= 9)
        SR_LOG(INFO, "[keyTime]average response = %f us", totalTimeSummary / 10.0f);

    if (id == KEY0)
    {
        switch (evt)
        {
        case SR_KEY_SHORT_PRESS:
            SR_LOG(INFO, "[keyEventCallback]: short pressed");
            break;

        case SR_KEY_LONG_PRESS:
            SR_LOG(INFO, "[keyEventCallback]: long pressed");
            break;

        case SR_KEY_DOUBLE_PRESS:
            SR_LOG(INFO, "[keyEventCallback]: double pressed");
            break;

        default:
            break;
        }
    }
}

static int keyInit(void)
{
    return 0;
}

static int keyCleanup(void)
{
    return 0;
}

static void keyOnOff_Testcase(void)
{
    SR_KeySetEvtCb(keyEventCallback, keyArgs);
}
UTEST_TC_EXPORT(key_register,
                keyOnOff_Testcase,
                keyInit,
                keyCleanup,
                TC_PRIORITY_HIGH);

static int keyBlinkInit(void)
{
    return 0;
}

static int keyBlinkCleanup(void)
{
    return 0;
}

static void keyBlinkInvalid_Testcase(void)
{
    int ret = -1;

    ret = SR_KeySetEvtCb(SR_NULL, keyArgs);
    SR_LOG(INFO, "[KeyInvalid]: return = %s", getErrorString(ret));
}
UTEST_TC_EXPORT(key_invalid,
                keyBlinkInvalid_Testcase,
                keyBlinkInit,
                keyBlinkCleanup,
                TC_PRIORITY_HIGH);

static int KeyTimeInit(void)
{
    SR_GPIO_CFG_T config = {0};

    config.gpioMode = SR_GPIO_OUTPUT;   // 输出
    config.pull = SR_GPIO_NP;           // 无上下拉
    config.initLvl = SR_GPIO_HIGH;      // 初始高电平
    SR_HalGpioInit(SR_GPIO19, &config); // 初始化

    return SR_KeySetEvtCb(keyEventCallback, SR_NULL);
}

static int KeyTimeCleanup(void)
{
    return 0;
}

static void KeyTime_Testcase(void)
{
    /* 测试短按响应时长 */
    for (i = 0; i < 10; i++)
    {
        SR_HalGpioWrite(SR_GPIO19, SR_GPIO_LOW);
        osDelay(11);
        startTick = SR_GetTickUs();
        SR_HalGpioWrite(SR_GPIO19, SR_GPIO_HIGH);
        osDelay(1000);
    }

    /* 测试长按响应时长 */
    for (i = 0; i < 10; i++)
    {
        SR_HalGpioWrite(SR_GPIO19, SR_GPIO_LOW);
        osDelay(2100);
        startTick = SR_GetTickUs();
        SR_HalGpioWrite(SR_GPIO19, SR_GPIO_HIGH);
        osDelay(1000);
    }

    /* 测试长按响应时长 */
    for (i = 0; i < 10; i++)
    {
        SR_HalGpioWrite(SR_GPIO19, SR_GPIO_LOW);
        osDelay(20);
        SR_HalGpioWrite(SR_GPIO19, SR_GPIO_HIGH);

        osDelay(20);
        SR_HalGpioWrite(SR_GPIO19, SR_GPIO_LOW);
        osDelay(20);
        startTick = SR_GetTickUs();
        SR_HalGpioWrite(SR_GPIO19, SR_GPIO_HIGH);

        osDelay(1000);
    }
}
UTEST_TC_EXPORT(key_time,
                KeyTime_Testcase,
                KeyTimeInit,
                KeyTimeCleanup,
                TC_PRIORITY_HIGH);
