/*
 * Copyright 2018-2019 NXP
 * All rights reserved.
 *
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

#include "fsl_common.h"
#include "gpio.h"
#include "timer_manager.h"

#include "button.h"
/*
 * The OSA_USED macro can only be defined when the OSA component is used.
 * If the source code of the OSA component does not exist, the OSA_USED cannot be defined.
 * OR, If OSA component is not added into project event the OSA source code exists, the OSA_USED
 * also cannot be defined.
 * The source code path of the OSA component is <MCUXpresso_SDK>/components/osa.
 *
 */
#if defined(OSA_USED)
#include "fsl_os_abstraction.h"
#if (defined(BUTTON_USE_COMMON_TASK) && (BUTTON_USE_COMMON_TASK > 0U))
#include "common_task.h"
#endif
#endif

/*******************************************************************************
 * Definitions
 ******************************************************************************/

#define BUTTON_SR_ALLOC()       uint32_t buttonPrimask;
#define BUTTON_ENTER_CRITICAL() buttonPrimask = DisableGlobalIRQ();
#define BUTTON_EXIT_CRITICAL()  EnableGlobalIRQ(buttonPrimask);

typedef enum _button_press_status
{
    kStatus_BUTTON_PressIdle          = 0, /*!< Idle */
    kStatus_BUTTON_Pressed            = 1, /*!< Pressed */
    kStatus_BUTTON_PressDoubleStart   = 2, /*!< Start double click */
    kStatus_BUTTON_PressDoublePressed = 3, /*!< Second press for double click */
} button_press_status_t;

typedef struct _button_state
{
    struct _button_state *next;
    button_callback_t callback;
    void *callbackParam;
    GPIO_HANDLE_DEFINE(gpioHandle);
    volatile uint32_t pushPeriodCount;
    volatile uint32_t pushPeriodCountLast;
    struct
    {
        uint16_t port : 3U;
        uint16_t reserved : 1U;
        uint16_t pin : 5U;
        uint16_t pinStateDefault : 1U;
        uint16_t reserved2 : 6U;
    } config;
    struct
    {
        volatile uint8_t pressed;
        volatile uint8_t msg;
    } state;
} button_state_t;

typedef struct _button_list
{
    volatile uint32_t periodCount;
    TIMER_MANAGER_HANDLE_DEFINE(timerHandle);
#if defined(OSA_USED)

#if (defined(BUTTON_USE_COMMON_TASK) && (BUTTON_USE_COMMON_TASK > 0U))
    common_task_message_t commonTaskMsg;
#else
    OSA_EVENT_HANDLE_DEFINE(eventHandle);
    OSA_TASK_HANDLE_DEFINE(taskHandle);
#endif

#endif
    button_state_t *button;
    volatile uint8_t timerOpenedNesting;
} button_list_t;

/*******************************************************************************
 * Prototypes
 ******************************************************************************/

static void BUTTON_Task(void *param);

/*******************************************************************************
 * Variables
 ******************************************************************************/

static button_list_t s_buttonList;

#if defined(OSA_USED)
extern const uint8_t gUseRtos_c;
#endif

#if (defined(BUTTON_USE_COMMON_TASK) && (BUTTON_USE_COMMON_TASK > 0U))

#else
/*
 * \brief Defines the button task's stack
 */
OSA_TASK_DEFINE(BUTTON_Task, BUTTON_TASK_PRIORITY, 1, BUTTON_TASK_STACK_SIZE, false);
#endif

/*******************************************************************************
 * Code
 ******************************************************************************/

static void BUTTON_NotificationUpdate(button_state_t *buttonState, button_event_t event)
{
    buttonState->state.pressed = (uint8_t)kStatus_BUTTON_PressIdle;
    buttonState->state.msg     = (uint8_t)event;
#if defined(OSA_USED)

#if (defined(BUTTON_USE_COMMON_TASK) && (BUTTON_USE_COMMON_TASK > 0U))
    s_buttonList.commonTaskMsg.callback      = BUTTON_Task;
    s_buttonList.commonTaskMsg.callbackParam = buttonState;
    COMMON_TASK_post_message(&s_buttonList.commonTaskMsg);
#else
    (void)OSA_EventSet((osa_event_handle_t)s_buttonList.eventHandle, BUTTON_EVENT_BUTTON);
#endif

#else
    BUTTON_Task(&s_buttonList);
#endif
}

static void BUTTON_Event(void *param)
{
    button_state_t *buttonState = (button_state_t *)param;
    uint8_t pinState            = 0U;

    assert(param);

    (void)HAL_GpioGetInput(buttonState->gpioHandle, &pinState);
    pinState = (0U != pinState) ? 1U : 0U;
    if (((uint8_t)kStatus_BUTTON_PressIdle == buttonState->state.pressed) ||
        ((uint8_t)kStatus_BUTTON_PressDoubleStart == buttonState->state.pressed))
    {
        if (buttonState->config.pinStateDefault != pinState)
        {
            buttonState->state.pressed++;
            buttonState->pushPeriodCount = s_buttonList.periodCount;
        }
    }
    else
    {
        if (buttonState->config.pinStateDefault == pinState)
        {
            if ((BUTTON_DOUBLE_CLICK_THRESHOLD + buttonState->pushPeriodCountLast) >= buttonState->pushPeriodCount)
            {
                if ((s_buttonList.periodCount - buttonState->pushPeriodCount) < BUTTON_SHORT_PRESS_THRESHOLD)
                {
                    BUTTON_NotificationUpdate(buttonState, kBUTTON_EventDoubleClick);
                }
                else
                {
                    BUTTON_NotificationUpdate(buttonState, kBUTTON_EventError);
                }
            }
            else
            {
                if ((s_buttonList.periodCount - buttonState->pushPeriodCount) < BUTTON_SHORT_PRESS_THRESHOLD)
                {
                    buttonState->pushPeriodCountLast = s_buttonList.periodCount;
                    buttonState->state.pressed       = (uint8_t)kStatus_BUTTON_PressDoubleStart;
                }
                else if ((s_buttonList.periodCount - buttonState->pushPeriodCount) < BUTTON_LONG_PRESS_THRESHOLD)
                {
                    BUTTON_NotificationUpdate(buttonState, kBUTTON_EventShortPress);
                }
                else
                {
                    BUTTON_NotificationUpdate(buttonState, kBUTTON_EventLongPress);
                }
            }
        }
    }
}

static void BUTTON_Task(void *param)
{
#if defined(OSA_USED)

#if (defined(BUTTON_USE_COMMON_TASK) && (BUTTON_USE_COMMON_TASK > 0U))
#else
    osa_event_flags_t ev = 0;

    do
    {
        if (KOSA_StatusSuccess == OSA_EventWait((osa_event_handle_t)s_buttonList.eventHandle, osaEventFlagsAll_c, false,
                                                osaWaitForever_c, &ev))
        {
#endif

#endif
    button_state_t *buttonState = s_buttonList.button;
    BUTTON_SR_ALLOC();

    BUTTON_ENTER_CRITICAL();
    while (NULL != buttonState)
    {
        if (0U != buttonState->state.msg)
        {
            button_callback_message_t msg;
            BUTTON_EXIT_CRITICAL();
            msg.event = (button_event_t)buttonState->state.msg;
            (void)buttonState->callback(buttonState, &msg, buttonState->callbackParam);
            buttonState->state.msg = 0U;
            BUTTON_ENTER_CRITICAL();
        }
        buttonState = buttonState->next;
    }
    BUTTON_EXIT_CRITICAL();
#if defined(OSA_USED)

#if (defined(BUTTON_USE_COMMON_TASK) && (BUTTON_USE_COMMON_TASK > 0U))
#else
        }
    } while (gUseRtos_c);
#endif

#endif
}

static void BUTTON_TimerEvent(void *param)
{
    button_state_t *buttonState;
    BUTTON_SR_ALLOC();

    s_buttonList.periodCount += BUTTON_TIMER_INTERVAL;

    BUTTON_ENTER_CRITICAL();
    buttonState = s_buttonList.button;
    while (NULL != buttonState)
    {
        /*
         * The code block is used to indentify the button event is one click or double click.
         * If the flag pending is set and the button is not pressed, check the user activity is timeout or not.
         * If is times out, notify the upper layer it is kBUTTON_EventOneClick.
         * Otherwise, check the status next time.
         */
        if ((uint8_t)kStatus_BUTTON_PressDoubleStart == buttonState->state.pressed)
        {
            if ((BUTTON_DOUBLE_CLICK_THRESHOLD + buttonState->pushPeriodCountLast) < s_buttonList.periodCount)
            {
                BUTTON_NotificationUpdate(buttonState, kBUTTON_EventOneClick);
                buttonState->pushPeriodCountLast = 0U;
            }
        }
        buttonState = buttonState->next;
    }
    BUTTON_EXIT_CRITICAL();
}

static void BUTTON_OpenTimer(void)
{
    BUTTON_SR_ALLOC();
    uint8_t initTimer = 0U;

    BUTTON_ENTER_CRITICAL();
    initTimer = (uint8_t)(!(bool)s_buttonList.timerOpenedNesting);
    s_buttonList.timerOpenedNesting++;
    BUTTON_EXIT_CRITICAL();

    if (0U != initTimer)
    {
        timer_status_t timerStatus;
        timerStatus = TM_Open((timer_handle_t)s_buttonList.timerHandle);
        assert(kStatus_TimerSuccess == timerStatus);
        timerStatus = TM_InstallCallback(s_buttonList.timerHandle, BUTTON_TimerEvent, &s_buttonList);
        assert(kStatus_TimerSuccess == timerStatus);
        timerStatus = TM_Start(s_buttonList.timerHandle, (uint8_t)kTimerModeLowPowerTimer, BUTTON_TIMER_INTERVAL);
        assert(kStatus_TimerSuccess == timerStatus);
        (void)timerStatus;
    }
}

static void BUTTON_CloseTimer(void)
{
    BUTTON_SR_ALLOC();
    uint8_t deinitTimer = 0U;

    BUTTON_ENTER_CRITICAL();
    if (s_buttonList.timerOpenedNesting > 0U)
    {
        s_buttonList.timerOpenedNesting--;
        deinitTimer = (uint8_t)(!(bool)s_buttonList.timerOpenedNesting);
    }
    BUTTON_EXIT_CRITICAL();

    if (0U != deinitTimer)
    {
        timer_status_t timerStatus;
        timerStatus = TM_Close((timer_handle_t)s_buttonList.timerHandle);
        assert(kStatus_TimerSuccess == timerStatus);
        (void)timerStatus;
    }
}

button_status_t BUTTON_Init(button_handle_t buttonHandle, button_config_t *buttonConfig)
{
    hal_gpio_pin_config_t controlPin;
    button_state_t *buttonState;
    hal_gpio_status_t gpioStatus;
    BUTTON_SR_ALLOC();

    assert((NULL != buttonHandle) && (NULL != buttonConfig));
    assert(BUTTON_HANDLE_SIZE >= sizeof(button_state_t));

    buttonState = (button_state_t *)buttonHandle;

    (void)memset(buttonHandle, 0, sizeof(button_state_t));

    BUTTON_ENTER_CRITICAL();
    BUTTON_OpenTimer();
    if (NULL == s_buttonList.button)
    {
#if defined(OSA_USED)

#if (defined(BUTTON_USE_COMMON_TASK) && (BUTTON_USE_COMMON_TASK > 0U))
        COMMON_TASK_init();
#else
        osa_status_t osaStatus;

        osaStatus = OSA_EventCreate((osa_event_handle_t)s_buttonList.eventHandle, true);
        assert(KOSA_StatusSuccess == osaStatus);

        osaStatus = OSA_TaskCreate((osa_task_handle_t)s_buttonList.taskHandle, OSA_TASK(BUTTON_Task), &s_buttonList);
        assert(KOSA_StatusSuccess == osaStatus);
#endif

#endif
    }
    else
    {
        buttonState->next = s_buttonList.button;
    }
    s_buttonList.button = buttonState;
    BUTTON_EXIT_CRITICAL();

    controlPin.port      = buttonConfig->gpio.port;
    controlPin.pin       = buttonConfig->gpio.pin;
    controlPin.direction = kHAL_GpioDirectionIn;
    controlPin.level     = buttonConfig->gpio.pinStateDefault;
    gpioStatus           = HAL_GpioInit(buttonState->gpioHandle, &controlPin);
    assert(kStatus_HAL_GpioSuccess == gpioStatus);
    (void)gpioStatus;

    buttonState->config.port            = buttonConfig->gpio.port;
    buttonState->config.pin             = buttonConfig->gpio.pin;
    buttonState->config.pinStateDefault = (0U != buttonConfig->gpio.pinStateDefault) ? 1U : 0U;

    gpioStatus = HAL_GpioSetTriggerMode(buttonState->gpioHandle, kHAL_GpioInterruptEitherEdge);
    assert(kStatus_HAL_GpioSuccess == gpioStatus);
    (void)gpioStatus;

    return kStatus_BUTTON_Success;
}

button_status_t BUTTON_InstallCallback(button_handle_t buttonHandle, button_callback_t callback, void *callbackParam)
{
    button_state_t *buttonState;
    assert(buttonHandle);

    buttonState = (button_state_t *)buttonHandle;

    buttonState->callback      = callback;
    buttonState->callbackParam = callbackParam;

    (void)HAL_GpioInstallCallback(buttonState->gpioHandle, BUTTON_Event, buttonState);

    return kStatus_BUTTON_Success;
}

button_status_t BUTTON_Deinit(button_handle_t buttonHandle)
{
    button_state_t *buttonState;
    button_state_t *buttonStatePre;
    BUTTON_SR_ALLOC();

    assert(buttonHandle);

    buttonState = (button_state_t *)buttonHandle;

    BUTTON_ENTER_CRITICAL();
    buttonStatePre = s_buttonList.button;
    if (buttonStatePre != buttonState)
    {
        while ((NULL != buttonStatePre) && (buttonStatePre->next != buttonState))
        {
            buttonStatePre = buttonStatePre->next;
        }
        if (NULL != buttonStatePre)
        {
            buttonStatePre->next = buttonState->next;
        }
    }
    else
    {
        s_buttonList.button = buttonState->next;
    }

    if (NULL == s_buttonList.button)
    {
#if defined(OSA_USED)

#if (defined(BUTTON_USE_COMMON_TASK) && (BUTTON_USE_COMMON_TASK > 0U))

#else
        (void)OSA_TaskDestroy((osa_task_handle_t)s_buttonList.taskHandle);
        (void)OSA_EventDestroy((osa_event_handle_t)s_buttonList.eventHandle);
#endif

#endif
    }
    BUTTON_CloseTimer();
    BUTTON_EXIT_CRITICAL();

    (void)HAL_GpioDeinit(buttonState->gpioHandle);

    return kStatus_BUTTON_Success;
}

button_status_t BUTTON_WakeUpSetting(button_handle_t buttonHandle, uint8_t enable)
{
    button_state_t *buttonState;
    hal_gpio_status_t status;

    assert(buttonHandle);

    buttonState = (button_state_t *)buttonHandle;

    status = HAL_GpioWakeUpSetting(buttonState->gpioHandle, enable);

    if (kStatus_HAL_GpioSuccess == status)
    {
        return kStatus_BUTTON_Success;
    }
    return kStatus_BUTTON_Error;
}

button_status_t BUTTON_EnterLowpower(button_handle_t buttonHandle)
{
    button_state_t *buttonState;
    hal_gpio_status_t status;

    assert(buttonHandle);

    buttonState = (button_state_t *)buttonHandle;

    status = HAL_GpioEnterLowpower(buttonState->gpioHandle);

    if (kStatus_HAL_GpioSuccess != status)
    {
        return kStatus_BUTTON_Error;
    }

    BUTTON_CloseTimer();

    return kStatus_BUTTON_Success;
}

button_status_t BUTTON_ExitLowpower(button_handle_t buttonHandle)
{
    button_state_t *buttonState;
    hal_gpio_status_t status;

    assert(buttonHandle);

    buttonState = (button_state_t *)buttonHandle;

    BUTTON_OpenTimer();

    status = HAL_GpioExitLowpower(buttonState->gpioHandle);

    if (kStatus_HAL_GpioSuccess != status)
    {
        return kStatus_BUTTON_Error;
    }
    BUTTON_Event(buttonState);
    return kStatus_BUTTON_Success;
}
