/*
 * Copyright 2016-2021, Cypress Semiconductor Corporation (an Infineon company) or
 * an affiliate of Cypress Semiconductor Corporation.  All rights reserved.
 *
 * This software, including source code, documentation and related
 * materials ("Software") is owned by Cypress Semiconductor Corporation
 * or one of its affiliates ("Cypress") and is protected by and subject to
 * worldwide patent protection (United States and foreign),
 * United States copyright laws and international treaty provisions.
 * Therefore, you may use this Software only as provided in the license
 * agreement accompanying the software package from which you
 * obtained this Software ("EULA").
 * If no EULA applies, Cypress hereby grants you a personal, non-exclusive,
 * non-transferable license to copy, modify, and compile the Software
 * source code solely for use in connection with Cypress's
 * integrated circuit products.  Any reproduction, modification, translation,
 * compilation, or representation of this Software except as specified
 * above is prohibited without the express written permission of Cypress.
 *
 * Disclaimer: THIS SOFTWARE IS PROVIDED AS-IS, WITH NO WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, NONINFRINGEMENT, IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. Cypress
 * reserves the right to make changes to the Software without notice. Cypress
 * does not assume any liability arising out of the application or use of the
 * Software or any product or circuit described in the Software. Cypress does
 * not authorize its products for use in any products where a malfunction or
 * failure of the Cypress product may reasonably be expected to result in
 * significant property damage, injury or death ("High Risk Product"). By
 * including Cypress's product in a High Risk Product, the manufacturer
 * of such system or application assumes all risk of such use and in doing
 * so agrees to indemnify Cypress against all liability.
 */
/** @file
 *
 * Button manager implements generic interface for button events and button type configurations.
 * It exposes interface to configure platform button events (like click,long press) with user configurable timing.
 */
#include "wiced_button_manager.h"
#include "clock_timer.h"
#include "platform_button.h"
#include "string.h"
#include "wiced_bt_trace.h"
#ifdef CYW55572
#include "wiced_memory.h"
#include "wiced_misc_rtos_utils.h"
#endif

/******************************************************
 *                      Macros
 ******************************************************/

#define BUTTON_TIMER_TIMEOUT (100) /*msec*/

/******************************************************
 *                    Constants
 ******************************************************/

/******************************************************
 *                   Enumerations
 ******************************************************/

/******************************************************
 *                 Type Definitions
 ******************************************************/
#if BTSTACK_VER >= 0x03000001
#define TIMER_PARAM_TYPE WICED_TIMER_PARAM_TYPE
#endif

#ifdef CYW55572
#define BUTTON_EVENT_QUEUE_DEPTH 16
#endif

/******************************************************
 *                    Structures
 ******************************************************/
#ifdef CYW55572
typedef struct
{
    button_manager_button_t * p_button;
    button_manager_event_t event;
} button_event_defer_to_mpaf_t;
#endif

/******************************************************
 *               Function Declarations
 ******************************************************/
static void button_state_change_callback(platform_button_t id, wiced_bool_t new_state);
static wiced_result_t button_pressed_event_handler(void * arg);
static wiced_result_t button_released_event_handler(void * arg);
static wiced_result_t deferred_button_timer_handler(void * arg);

static wiced_bool_t button_check_event_mask(button_manager_button_t * button, uint16_t new_event);
static void button_check_for_double_click(button_manager_button_t * button, button_manager_event_t * new_event);
static button_manager_event_t button_deduce_duration_event(button_manager_button_t * button, uint32_t current_interval);
static button_manager_button_t * get_button(platform_button_t id);
#ifdef CYW55572
static void button_event_defer_to_mpaf(void * arg);
#endif

/******************************************************
 *               Variables Definitions
 ******************************************************/
static button_manager_t * button_manager;
#ifdef CYW55572
static wiced_mutex_t * p_mutex_button_event;
static wiced_bt_buffer_q_t button_event_queue;
static wiced_bt_pool_t * p_button_event_pool = NULL;
#endif

/******************************************************
 *               Function Definitions
 ******************************************************/

/*
 * button_long_press_detect_timeout_handler
 *
 * Timeout handler for button long press detect timer.
 *
 * The execution duration of this utility is defined in BUTTON_TIMER_TIMEOUT.
 */
static void button_long_press_detect_timeout_handler(TIMER_PARAM_TYPE arg)
{
    button_manager_button_t * p_button = (button_manager_button_t *) arg;

    /* Check if button is under debouncing state. */
    if (p_button->debouncing)
    {
        return;
    }

    /* Get current button state. */
    p_button->current_state = (button_manager_button_state_t) platform_button_get_value(p_button->configuration->button);

    if (p_button->current_state != BUTTON_STATE_HELD)
    {
        WICED_BT_TRACE("Err: Button %d is already released\n", p_button->configuration->button);

        if (wiced_is_timer_in_use(&p_button->long_press_timer))
        {
            wiced_stop_timer(&p_button->long_press_timer);
        }

        return;
    }
    /* Get current timestatmp. */
    p_button->timer_timestamp = clock_SystemTimeMicroseconds64();

    deferred_button_timer_handler((void *) p_button);
}

/*
 * button_debounce_timeout_handler
 *
 * Timeout handler for button debounce timer.
 */
static void button_debounce_timeout_handler(TIMER_PARAM_TYPE arg)
{
    button_manager_button_t * p_button = (button_manager_button_t *) arg;
    wiced_result_t result;

    // WICED_BT_TRACE("button_debounce_timeout_handler (%d, %d)\n", p_button->configuration->button, p_button->debounce_counter);

    if (p_button->debounce_counter > 0)
    {
        /* Reset the button debounce counter. */
        p_button->debounce_counter = 0;

        button_pressed_event_handler((void *) p_button);
    }
    else
    {
        if (wiced_is_timer_in_use(&p_button->long_press_timer))
        {
            wiced_stop_timer(&p_button->long_press_timer);
        }
    }

    /* Reset the button debounce state. */
    p_button->debouncing = WICED_FALSE;
}

/**
 * The application should call this function to Initialize the Button Manager
 */
wiced_result_t __attribute__((weak))
wiced_button_manager_init(button_manager_t * manager, const wiced_button_manager_configuration_t * configuration,
                          button_manager_button_t * buttons, uint32_t number_of_buttons)
{
    uint32_t a;

    memset(manager, 0, sizeof(*manager));

    manager->configuration     = configuration;
    manager->buttons           = buttons;
    manager->number_of_buttons = number_of_buttons;

    button_manager = manager;

    for (a = 0; a < number_of_buttons; a++)
    {
        platform_button_init(buttons[a].configuration->button);
        platform_button_enable(buttons[a].configuration->button);
        buttons[a].current_state    = BUTTON_STATE_RELEASED;
        buttons[a].repeat           = 0;
        buttons[a].debounce_counter = 0;
        buttons[a].debouncing       = WICED_FALSE;
    }

    platform_button_register_state_change_callback(button_state_change_callback);

    /* Initialize the timers used for detecting the long press event. */
    for (a = 0; a < number_of_buttons; a++)
    {
        wiced_init_timer(&buttons[a].long_press_timer, button_long_press_detect_timeout_handler, (TIMER_PARAM_TYPE) &buttons[a],
                         WICED_MILLI_SECONDS_PERIODIC_TIMER);
    }

    /* Initialize the timers used for de-bounce. */
    for (a = 0; a < number_of_buttons; a++)
    {
        wiced_init_timer(&buttons[a].debounce_timer, button_debounce_timeout_handler, (TIMER_PARAM_TYPE) &buttons[a],
                         WICED_MILLI_SECONDS_TIMER);
    }

#ifdef CYW55572
    p_button_event_pool =
        wiced_bt_create_pool("Button Event", sizeof(button_event_defer_to_mpaf_t), BUTTON_EVENT_QUEUE_DEPTH, NULL);

    if (!p_button_event_pool)
    {
        WICED_BT_TRACE("%s: Fail to create pool.\n", __FUNCTION__);
        return WICED_ERROR;
    }

    wiced_bt_init_q(&button_event_queue, NULL);
    p_mutex_button_event = wiced_rtos_create_mutex();
    if (p_mutex_button_event == NULL)
    {
        WICED_BT_TRACE("%s: Fail to create mutex.\n", __FUNCTION__);
        return WICED_ERROR;
    }

    if (wiced_rtos_init_mutex(p_mutex_button_event) != WICED_SUCCESS)
    {
        WICED_BT_TRACE("%s: Fail to init. mutex.\n", __FUNCTION__);
        return WICED_ERROR;
    }
#endif

    return WICED_SUCCESS;
}

/**
 * The application should call this function to de-Initialize the Button Manager
 *
 * @param     manager   : Pointer to button manager to de-initialize.
 * @return              : result.
 */
wiced_result_t wiced_button_manager_deinit(button_manager_t * manager)
{
    uint32_t a;
    for (a = 0; a < manager->number_of_buttons; a++)
    {
        platform_button_disable(manager->buttons[a].configuration->button);
        platform_button_deinit(manager->buttons[a].configuration->button);
    }

    for (a = 0; a < manager->number_of_buttons; a++)
    {
        if (WICED_TRUE == wiced_is_timer_in_use(&manager->buttons[a].debounce_timer))
        {
            wiced_stop_timer(&manager->buttons[a].debounce_timer);
        }

        wiced_deinit_timer(&manager->buttons[a].debounce_timer);

        if (WICED_TRUE == wiced_is_timer_in_use(&manager->buttons[a].long_press_timer))
        {
            wiced_stop_timer(&manager->buttons[a].long_press_timer);
        }

        wiced_deinit_timer(&manager->buttons[a].long_press_timer);
    }

    button_manager = NULL;
    return WICED_SUCCESS;
}

/**
 * Deferred Handler initiated from timer handler
 *
 * @param     arg   : Arguments passed by the timer framework to timer handler
 * @return          : result
 */
static wiced_result_t deferred_button_timer_handler(void * arg)
{
    button_manager_button_t * p_button = (button_manager_button_t *) arg;
    uint64_t duration; // us
    button_manager_event_t new_held_event = 0;

    /* Check current button state. */
    if (p_button->current_state == BUTTON_STATE_RELEASED)
    {
        return WICED_SUCCESS;
    }

    /* Calculate the time difference. */
    duration = p_button->timer_timestamp - p_button->pressed_timestamp; // us
    duration = duration / 1000;                                         // ms

    /* deduce the event depending on the duration */
    new_held_event = button_deduce_duration_event(p_button, (uint32_t) duration);

    /*
     * timers should be mainly interested in duration-specific events;
     * let release_handler only report Click events to the application
     */
    if (new_held_event == BUTTON_CLICK_EVENT)
    {
        return WICED_SUCCESS;
    }

    if (button_check_event_mask(p_button, new_held_event))
    {
        if (p_button->last_sent_event != BUTTON_HOLDING_EVENT)
        {
            if (p_button->last_sent_event != new_held_event)
            {
                button_manager->configuration->event_handler(p_button, new_held_event, p_button->current_state);
                p_button->last_sent_event = new_held_event;
            }
        }
        else
        {
            button_manager->configuration->event_handler(p_button, new_held_event, p_button->current_state);
            p_button->last_sent_event = new_held_event;
        }
    }

    return WICED_SUCCESS;
}

static void button_state_change_callback_pressed(button_manager_button_t * p_button)
{
    /* Check if the button is under de-bounce state. */
    if (p_button->debouncing)
    { // under de-bounce state
        p_button->debounce_counter++;
    }
    else
    {
        /* ignore pressed event for already pressed button*/
        if (p_button->current_state == BUTTON_STATE_HELD)
        {
            return;
        }

        /* Get current timestamp for pressed event. */
        p_button->pressed_timestamp = clock_SystemTimeMicroseconds64();

        /* Start the button debounce timer. */
        wiced_start_timer(&p_button->debounce_timer, (uint32_t) button_manager->configuration->debounce_duration);

        /* Start the long pressed event detect timer. */
        wiced_start_timer(&p_button->long_press_timer, BUTTON_TIMER_TIMEOUT);

        /* Update information. */
        p_button->debouncing       = WICED_TRUE;
        p_button->debounce_counter = 1;
    }
}

static void button_state_change_callback_released(button_manager_button_t * p_button)
{
    wiced_result_t result;

    /* Check if the button is under de-bounce state. */
    if (p_button->debouncing)
    { // under de-bounce state
        p_button->debounce_counter--;
    }
    else
    {
        /* ignore released event for already released button */
        if (p_button->current_state == BUTTON_STATE_RELEASED)
        {
            return;
        }

        /* Get current timestamp for release event. */
        p_button->released_timestamp = clock_SystemTimeMicroseconds64();

        /* Stop the long pressed event detect timer. */
        if (wiced_is_timer_in_use(&p_button->long_press_timer))
        {
            wiced_stop_timer(&p_button->long_press_timer);
        }

        button_released_event_handler((void *) p_button);
    }
}

/**
 * Call back received when button state is changed.
 *
 * @param     id        : id of the button.
 * @param     new_state : new state of the button.
 * @return         void : no return value is expected.
 */
static void button_state_change_callback(platform_button_t id, wiced_bool_t new_state)
{
    button_manager_button_t * button = get_button(id);

#if 0
    WICED_BT_TRACE("button_state_change_callback (button %d %s, %s, %d, %d)\n",
                   id,
                   button->current_state == BUTTON_STATE_HELD ? "H" : "R",
                   button->debouncing ? "D" : "-",
                   new_state,
                   button->debounce_counter);
#endif

    /* Check module state.*/
    if (button == NULL || button_manager == NULL)
    {
        WICED_BT_TRACE("button manager not initialized\n");
        return;
    }

    if (new_state == WICED_TRUE)
    {
        button_state_change_callback_pressed(button);
    }
    else
    {
        button_state_change_callback_released(button);
    }
}

/**
 * Event handler for button press event.
 *
 * @param     arg   : Arguments passed by the event manager
 * @return    void  : No return value expected.
 */
static wiced_result_t button_pressed_event_handler(void * arg)
{
    button_manager_button_t * button = (button_manager_button_t *) arg;

    if (button->current_state == BUTTON_STATE_HELD)
    {
        return WICED_SUCCESS;
    }

    /** Button is pressed; update the state so that timer-handlers know it */
    button->current_state = BUTTON_STATE_HELD;

    return WICED_SUCCESS;
}

/**
 * Event handler for button release event.
 *
 * @param     arg   : Arguments passed by the event manager
 * @return    void  : No return value expected.
 */

static wiced_result_t button_released_event_handler(void * arg)
{
    button_manager_button_t * button         = (button_manager_button_t *) arg;
    button_manager_event_t new_release_event = 0;
    uint64_t duration; // us

    if (button->current_state == BUTTON_STATE_RELEASED)
    {
        return WICED_SUCCESS;
    }

    button->current_state = BUTTON_STATE_RELEASED;

    /* Calculate the time difference. */
    duration = button->released_timestamp - button->pressed_timestamp; // us
    duration = duration / 1000;                                        // ms

    /** If release event comes before debounce duration, ignore it */
    if (duration <= button_manager->configuration->debounce_duration)
    {
        return WICED_SUCCESS;
    }

    /** deduce the event depending on the duration */
    new_release_event = button_deduce_duration_event(button, (uint32_t) duration);

    /** Check if this Release is from 2nd click of a double-click event */
    button_check_for_double_click(button, &new_release_event);

    /**
     * As the new state is Release and application has asked for this kind of event,
     * send it irrespective of whether timer-handler
     * had sent it previously
     */
    if (button_check_event_mask(button, new_release_event))
    {
#ifndef CYW55572
        button_manager->configuration->event_handler(button, new_release_event, button->current_state);
#else
        /*
         * Button released event is handled by another thread, it needs defer to mpaf thread.
         * Deferred_button_timer_handler(long press) is handled by timer which is in mpaf thread,
         * it does not need defer.
         */
        wiced_result_t result;

        wiced_rtos_lock_mutex(p_mutex_button_event);
        button_event_defer_to_mpaf_t * p_data = (button_event_defer_to_mpaf_t *) wiced_bt_get_buffer_from_pool(p_button_event_pool);

        if (!p_data)
        {
            wiced_rtos_unlock_mutex(p_mutex_button_event);
            WICED_BT_TRACE("Err: release event_handler no memory \n");
            goto DEFER_MPAF_ERROR;
        }

        p_data->p_button = button;
        p_data->event    = new_release_event;
        wiced_bt_enqueue(&button_event_queue, (wiced_bt_buffer_t *) p_data);
        wiced_rtos_unlock_mutex(p_mutex_button_event);
        result = wiced_rtos_defer_execution(WICED_RTOS_DEFER_TO_MPAF_THREAD, &button_event_defer_to_mpaf, NULL);

        if (result != WICED_SUCCESS)
        {
            wiced_rtos_lock_mutex(p_mutex_button_event);
            button_event_defer_to_mpaf_t * p_buf = (button_event_defer_to_mpaf_t *) wiced_bt_dequeue(&button_event_queue);
            wiced_bt_free_buffer(p_buf);
            wiced_rtos_unlock_mutex(p_mutex_button_event);
            WICED_BT_TRACE("Err: release event_handler wiced_rtos_defer_execution (%d)\n", result);
            goto DEFER_MPAF_ERROR;
        }
#endif
    }

#ifdef CYW55572
DEFER_MPAF_ERROR:
#endif

    /** reset the button's last-sent so that a new press/held after this release is handled properly */
    button->last_sent_event = 0;

    return WICED_SUCCESS;
}

/**
 * Checks if the event is a double click event.
 *
 * @param     button    : button information.
 * @param     new_event : new event generated for the button.
 * @return         void : no return value is expected.
 */
static void button_check_for_double_click(button_manager_button_t * button, button_manager_event_t * new_event)
{
    if (!button_check_event_mask(button, BUTTON_DOUBLE_CLICK_EVENT) || *new_event != BUTTON_CLICK_EVENT)
    {
        return;
    }
    /** figure out the time-difference in two-releases */
    if ((button->released_timestamp - button->last_released_timestamp) <= button_manager->configuration->double_click_interval)
    {
        /** morph it as DOUBLE_CLICK */
        *new_event = BUTTON_DOUBLE_CLICK_EVENT;
    }

    button->last_released_timestamp = button->released_timestamp;

    return;
}

/**
 * Checks the event mask for the button
 *
 * @param     button        : button information.
 * @param     new_event     : new event generated for the button.
 * @return    wiced_bool_t  : returns true/false based on the new event.
 */
static wiced_bool_t button_check_event_mask(button_manager_button_t * button, uint16_t new_event)
{
    if (!button)
    {
        return WICED_FALSE;
    }

    return ((new_event & button->configuration->button_event_mask) ? WICED_TRUE : WICED_FALSE);
}

/**
 * Checks duration of the event
 *
 * @param   button                    : the button that been triggered
 * @param   current_interval          : current time interval
 * @return  button_manager_event_t    : returns button manager event.
 */

static button_manager_event_t button_deduce_duration_event(button_manager_button_t * button, uint32_t current_interval)
{
    button_manager_event_t new_event = 0;
    uint32_t target_hold_interval;

    if (current_interval <= button_manager->configuration->debounce_duration)
    {
        return (button_manager_event_t) 0;
    }
    else if (current_interval > button_manager->configuration->debounce_duration &&
             current_interval <= button_manager->configuration->short_hold_duration)
    {
        return BUTTON_CLICK_EVENT;
    }
    else if (current_interval > button_manager->configuration->short_hold_duration &&
             current_interval <= button_manager->configuration->medium_hold_duration)
    {
        return BUTTON_SHORT_DURATION_EVENT;
    }
    else if (current_interval > button_manager->configuration->medium_hold_duration &&
             current_interval <= button_manager->configuration->long_hold_duration)
    {
        return BUTTON_MEDIUM_DURATION_EVENT;
    }
    else if (current_interval > button_manager->configuration->long_hold_duration &&
             current_interval <= button_manager->configuration->very_long_hold_duration)
    {
        button->repeat = 0;
        return BUTTON_LONG_DURATION_EVENT;
    }
    else
    { // current_interval > button_manager->configuration->very_long_hold_duration
        if (button_manager->configuration->continuous_hold_detect == WICED_FALSE)
        {
            return BUTTON_VERY_LONG_DURATION_EVENT;
        }
        else
        {
            target_hold_interval = (button->repeat + 2) * button_manager->configuration->long_hold_duration;

            if (current_interval > target_hold_interval)
            {
                button->repeat++;

                return BUTTON_HOLDING_EVENT;
            }
            else
            {
                return (button_manager_event_t) 0;
            }
        }
    }
}

/**
 * returns button based on the button id
 *
 * @param   id                         : id of the buttonl
 * @return  button_manager_button_t    : returns button.
 */

static button_manager_button_t * get_button(platform_button_t id)
{
    uint8_t a;

    for (a = 0; a < button_manager->number_of_buttons; a++)
    {
        if (button_manager->buttons[a].configuration->button == id)
        {
            return &button_manager->buttons[a];
        }
    }

    return NULL;
}

#ifdef CYW55572
static void button_event_defer_to_mpaf(void * arg)
{
    button_event_defer_to_mpaf_t button_event_buf;

    wiced_rtos_lock_mutex(p_mutex_button_event);
    button_event_defer_to_mpaf_t * p_buf = (button_event_defer_to_mpaf_t *) wiced_bt_dequeue(&button_event_queue);
    memcpy(&button_event_buf, p_buf, sizeof(button_event_defer_to_mpaf_t));
    wiced_bt_free_buffer(p_buf);
    wiced_rtos_unlock_mutex(p_mutex_button_event);
    button_manager->configuration->event_handler(button_event_buf.p_button, button_event_buf.event,
                                                 button_event_buf.p_button->current_state);
}
#endif
