/*
 *
 *    Copyright (c) 2020 Google LLC.
 *    All rights reserved.
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *        http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

#include <stdint.h>
#include <string.h>
#include <em_device.h>

#include "rtos_gecko.h"
#include "gecko_configuration.h"
#include <Weave/DeviceLayer/EFR32/freertos_bluetooth.h>

#ifdef CONFIGURATION_HEADER
#include CONFIGURATION_HEADER
#endif // CONFIGURATION_HEADER

void                              BluetoothUpdate();
volatile struct gecko_cmd_packet *bluetooth_evt;
SemaphoreHandle_t                 BluetoothMutex = NULL;

volatile static uint32_t          command_header;
volatile static void *            command_data;
volatile static gecko_cmd_handler command_handler_func = NULL;

// Bluetooth task
#ifndef BLUETOOTH_STACK_SIZE
#define BLUETOOTH_STACK_SIZE (2048)
#endif
static void         BluetoothTask(void *p_arg);
static TaskHandle_t BluetoothTaskHandle = NULL;

// Linklayer task
#ifndef LINKLAYER_STACK_SIZE
#define LINKLAYER_STACK_SIZE (2048)
#endif
static void         LinklayerTask(void *p_arg);
static TaskHandle_t LinklayerTaskHandle = NULL;
//
#define RTOS_TICK_HZ 1024
#define BLUETOOTH_TICK_HZ 32768
#define BLUETOOTH_TO_RTOS_TICK (BLUETOOTH_TICK_HZ / RTOS_TICK_HZ)

static volatile wakeupCallback wakeupCB = NULL;
// Set the task to post semaphore
void BluetoothSetWakeupCallback(wakeupCallback cb)
{
    wakeupCB = (volatile wakeupCallback)cb;
}
EventGroupHandle_t bluetooth_event_flags;

errorcode_t bluetooth_start(UBaseType_t               ll_priority,
                            UBaseType_t               stack_priority,
                            bluetooth_stack_init_func initialize_bluetooth_stack)
{
    errorcode_t err;
    bluetooth_event_flags = xEventGroupCreate();
    configASSERT(bluetooth_event_flags);

    BluetoothMutex = xSemaphoreCreateMutex();

    err = initialize_bluetooth_stack();

    if (err == 0)
    {
        // create tasks for Bluetooth host stack
        xTaskCreate(BluetoothTask,                              /* Function that implements the task. */
                    "Bluetooth Task",                           /* Text name for the task. */
                    BLUETOOTH_STACK_SIZE / sizeof(StackType_t), /* Number of indexes in the xStack array. */
                    NULL,                                       /* Parameter passed into the task. */
                    stack_priority,                             /* Priority at which the task is created. */
                    &BluetoothTaskHandle);                      /* Variable to hold the task's data structure. */

        // create tasks for Linklayer
        xTaskCreate(LinklayerTask,                              /* Function that implements the task. */
                    "Linklayer Task",                           /* Text name for the task. */
                    LINKLAYER_STACK_SIZE / sizeof(StackType_t), /* Number of indexes in the xStack array. */
                    NULL,                                       /* Parameter passed into the task. */
                    ll_priority,                                /* Priority at which the task is created. */
                    &LinklayerTaskHandle);                      /* Variable to hold the task's data structure. */
    }

    return err;
}

// This callback is called from interrupt context (Kernel Aware)
// sets flag to trigger Link Layer Task
void BluetoothLLCallback()
{
    EventBits_t eventBits;
    BaseType_t  pxHigherPriorityTaskWoken = pdFALSE;
    eventBits =
        vRaiseEventFlagBasedOnContext(bluetooth_event_flags, BLUETOOTH_EVENT_FLAG_LL, &pxHigherPriorityTaskWoken);
    (void)eventBits;
}
// This callback is called from Bluetooth stack
// Called from kernel aware interrupt context (RTCC interrupt) and from Bluetooth task
// sets flag to trigger running Bluetooth stack
void BluetoothUpdate()
{
    EventBits_t eventBits;
    BaseType_t  pxHigherPriorityTaskWoken = pdFALSE;
    eventBits =
        vRaiseEventFlagBasedOnContext(bluetooth_event_flags, BLUETOOTH_EVENT_FLAG_STACK, &pxHigherPriorityTaskWoken);
    (void)eventBits;
}
// Bluetooth task, it waits for events from bluetooth and handles them
void BluetoothTask(void *p)
{
    EventBits_t flags = BLUETOOTH_EVENT_FLAG_EVT_HANDLED | BLUETOOTH_EVENT_FLAG_STACK;
    EventBits_t eventBits;
    TickType_t  xTicksToWait;

    while (1)
    {
        // Command needs to be sent to Bluetooth stack
        if (flags & BLUETOOTH_EVENT_FLAG_CMD_WAITING)
        {
            uint32_t          header      = command_header;
            gecko_cmd_handler cmd_handler = command_handler_func;
            sli_bt_cmd_handler_delegate(header, cmd_handler, (void *)command_data);
            command_handler_func = NULL;
            flags &= ~BLUETOOTH_EVENT_FLAG_CMD_WAITING;
            eventBits = vRaiseEventFlagBasedOnContext(bluetooth_event_flags, BLUETOOTH_EVENT_FLAG_RSP_WAITING, NULL);
            (void)eventBits;
        }

        // Bluetooth stack needs updating, and evt can be used
        if ((flags & BLUETOOTH_EVENT_FLAG_STACK) && (flags & BLUETOOTH_EVENT_FLAG_EVT_HANDLED))
        { // update bluetooth & read event
            bluetooth_evt = gecko_wait_event();
            if (bluetooth_evt != NULL)
            { // we got event, notify event handler. evt state is now waiting handling
                eventBits =
                    vRaiseEventFlagBasedOnContext(bluetooth_event_flags, BLUETOOTH_EVENT_FLAG_EVT_WAITING, NULL);
                (void)eventBits;
                flags &= ~(BLUETOOTH_EVENT_FLAG_EVT_HANDLED);
                if (wakeupCB != NULL)
                {
                    wakeupCB();
                }
            }
            else
            { // nothing to do in stack, clear the flag
                flags &= ~(BLUETOOTH_EVENT_FLAG_STACK);
            }
        }

        // Ask from Bluetooth stack how long we can sleep
        // UINT32_MAX = sleep indefinitely
        // 0 = cannot sleep, stack needs update and we need to check if evt is handled that we can actually update it
        uint32_t timeout = gecko_can_sleep_ms();
        if (timeout == 0 && (flags & BLUETOOTH_EVENT_FLAG_EVT_HANDLED))
        {
            flags |= BLUETOOTH_EVENT_FLAG_STACK;
            continue;
        }

        if (timeout == 0x07CFFFFF)
        {
            xTicksToWait = portMAX_DELAY;
        }
        else if (timeout == 0)
        {
            xTicksToWait = 10 / portTICK_PERIOD_MS;
        }
        else
        {
            // round up to RTOS ticks
            xTicksToWait = timeout / portTICK_PERIOD_MS;
        }
        flags |=
            xEventGroupWaitBits(bluetooth_event_flags, /* The event group being tested. */
                                (BLUETOOTH_EVENT_FLAG_STACK + BLUETOOTH_EVENT_FLAG_EVT_HANDLED +
                                 BLUETOOTH_EVENT_FLAG_CMD_WAITING), /* The bits within the event group to wait for. */
                                pdTRUE,        /* BLUETOOTH_EVENT_FLAG_LL should be cleared before returning. */
                                pdFALSE,       /* Wait for all the bits to be set, not needed for single bit. */
                                xTicksToWait); /* Wait for maximum duration for bit to be set. With 1 ms tick,
                                                  portMAX_DELAY will result in wait of 50 days*/

        if (((flags & BLUETOOTH_EVENT_FLAG_STACK) == 0) && ((flags & BLUETOOTH_EVENT_FLAG_EVT_HANDLED) == 0) &&
            ((flags & BLUETOOTH_EVENT_FLAG_CMD_WAITING) == 0))
        {
            // timeout occurred, set the flag to update the Bluetooth stack
            flags |= BLUETOOTH_EVENT_FLAG_STACK;
        }
    }
}

static void LinklayerTask(void *p_arg)
{
    (void)p_arg;

    while (1)
    {
        EventBits_t uxBits;

        uxBits = xEventGroupWaitBits(bluetooth_event_flags,   /* The event group being tested. */
                                     BLUETOOTH_EVENT_FLAG_LL, /* The bits within the event group to wait for. */
                                     pdTRUE,         /* BLUETOOTH_EVENT_FLAG_LL should be cleared before returning. */
                                     pdTRUE,         /* Wait for all the bits to be set, not needed for single bit. */
                                     portMAX_DELAY); /* Wait for maximum duration for bit to be set. With 1 ms tick,
                                                        portMAX_DELAY will result in wait of 50 days*/

        if (uxBits & BLUETOOTH_EVENT_FLAG_LL)
        {
            gecko_priority_handle();
        }
    }
}

// hooks for API
// called from tasks using BGAPI
void rtos_gecko_handle_command(uint32_t header, void *payload)
{
    sli_bt_cmd_handler_rtos_delegate(header, NULL, payload);
}
void rtos_gecko_handle_command_noresponse(uint32_t header, void *payload)
{
    sli_bt_cmd_handler_rtos_delegate(header, NULL, payload);
}
void sli_bt_cmd_handler_rtos_delegate(uint32_t header, gecko_cmd_handler handler, const void *payload)
{
    EventBits_t uxBits;

    command_header       = header;
    command_handler_func = handler;
    command_data         = (void *)payload;
    // Command structure is filled, notify the stack
    uxBits = vRaiseEventFlagBasedOnContext(bluetooth_event_flags, BLUETOOTH_EVENT_FLAG_CMD_WAITING, NULL);

    // wait for response
    uxBits = xEventGroupWaitBits(bluetooth_event_flags,            /* The event group being tested. */
                                 BLUETOOTH_EVENT_FLAG_RSP_WAITING, /* The bits within the event group to wait for. */
                                 pdTRUE,         /* BLUETOOTH_EVENT_FLAG_LL should be cleared before returning. */
                                 pdTRUE,         /* Wait for all the bits to be set, not needed for single bit. */
                                 portMAX_DELAY); /* Wait for maximum duration for bit to be set. With 1 ms tick,
                                                    portMAX_DELAY will result in wait of 50 days*/
    (void)uxBits;
}

void BluetoothPend(void)
{
    xSemaphoreTake(BluetoothMutex, portMAX_DELAY);
}
void BluetoothPost(void)
{
    xSemaphoreGive(BluetoothMutex);
}

void vApplicationMallocFailedHook(void)
{
    /* Called if a call to pvPortMalloc() fails because there is insufficient
    free memory available in the FreeRTOS heap.  pvPortMalloc() is called
    internally by FreeRTOS API functions that create tasks, queues, software
    timers, and semaphores.  The size of the FreeRTOS heap is set by the
    configTOTAL_HEAP_SIZE configuration constant in FreeRTOSConfig.h. */

    /* Force an assert. */
    configASSERT((volatile void *)NULL);
}
/*-----------------------------------------------------------*/

void vApplicationStackOverflowHook(TaskHandle_t pxTask, char *pcTaskName)
{
    (void)pcTaskName;
    (void)pxTask;

    /* Run time stack overflow checking is performed if
    configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2.  This hook
    function is called if a stack overflow is detected. */

    /* Force an assert. */
    configASSERT((volatile void *)NULL);
}

void vApplicationTickHook(void)
{
}

/*-----------------------------------------------------------*/

/* configUSE_STATIC_ALLOCATION is set to 1, so the application must provide an
implementation of vApplicationGetIdleTaskMemory() to provide the memory that is
used by the Idle task. */
void vApplicationGetIdleTaskMemory(StaticTask_t **ppxIdleTaskTCBBuffer,
                                   StackType_t ** ppxIdleTaskStackBuffer,
                                   uint32_t *     pulIdleTaskStackSize)
{
    /* If the buffers to be provided to the Idle task are declared inside this
    function then they must be declared static - otherwise they will be allocated on
    the stack and so not exists after this function exits. */
    static StaticTask_t xIdleTaskTCB;
    static StackType_t  uxIdleTaskStack[configMINIMAL_STACK_SIZE];

    /* Pass out a pointer to the StaticTask_t structure in which the Idle task's
    state will be stored. */
    *ppxIdleTaskTCBBuffer = &xIdleTaskTCB;

    /* Pass out the array that will be used as the Idle task's stack. */
    *ppxIdleTaskStackBuffer = uxIdleTaskStack;

    /* Pass out the size of the array pointed to by *ppxIdleTaskStackBuffer.
    Note that, as the array is necessarily of type StackType_t,
    configMINIMAL_STACK_SIZE is specified in words, not bytes. */
    *pulIdleTaskStackSize = configMINIMAL_STACK_SIZE;
}
/*-----------------------------------------------------------*/

/* configUSE_STATIC_ALLOCATION and configUSE_TIMERS are both set to 1, so the
application must provide an implementation of vApplicationGetTimerTaskMemory()
to provide the memory that is used by the Timer service task. */
void vApplicationGetTimerTaskMemory(StaticTask_t **ppxTimerTaskTCBBuffer,
                                    StackType_t ** ppxTimerTaskStackBuffer,
                                    uint32_t *     pulTimerTaskStackSize)
{
    /* If the buffers to be provided to the Timer task are declared inside this
    function then they must be declared static - otherwise they will be allocated on
    the stack and so not exists after this function exits. */
    static StaticTask_t xTimerTaskTCB;
    static StackType_t  uxTimerTaskStack[configTIMER_TASK_STACK_DEPTH];

    /* Pass out a pointer to the StaticTask_t structure in which the Timer
    task's state will be stored. */
    *ppxTimerTaskTCBBuffer = &xTimerTaskTCB;

    /* Pass out the array that will be used as the Timer task's stack. */
    *ppxTimerTaskStackBuffer = uxTimerTaskStack;

    /* Pass out the size of the array pointed to by *ppxTimerTaskStackBuffer.
    Note that, as the array is necessarily of type StackType_t,
    configMINIMAL_STACK_SIZE is specified in words, not bytes. */
    *pulTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH;
}

EventBits_t vRaiseEventFlagBasedOnContext(EventGroupHandle_t xEventGroup,
                                          EventBits_t        uxBitsToWaitFor,
                                          BaseType_t *       pxHigherPriorityTaskWoken)
{
    EventBits_t eventBits;
    BaseType_t  higherPrioTaskWoken = pdFALSE;

    if (xPortIsInsideInterrupt())
    {
        eventBits = xEventGroupSetBitsFromISR(xEventGroup, uxBitsToWaitFor, &higherPrioTaskWoken);
    }
    else
    {
        eventBits = xEventGroupSetBits(xEventGroup, uxBitsToWaitFor);
    }

    if (pxHigherPriorityTaskWoken != NULL)
    {
        *pxHigherPriorityTaskWoken = higherPrioTaskWoken;
    }
    return eventBits;
}

EventBits_t vSendToQueueBasedOnContext(QueueHandle_t xQueue,
                                       void *        xItemToQueue,
                                       TickType_t    xTicksToWait,
                                       BaseType_t *  pxHigherPriorityTaskWoken)
{
    BaseType_t status;
    BaseType_t higherPrioTaskWoken = pdFALSE;

    if (xPortIsInsideInterrupt())
    {
        status = xQueueSendFromISR(xQueue, xItemToQueue, &higherPrioTaskWoken);
    }
    else
    {
        status = xQueueSend(xQueue, xItemToQueue, xTicksToWait);
    }

    if (pxHigherPriorityTaskWoken != NULL)
    {
        *pxHigherPriorityTaskWoken = higherPrioTaskWoken;
    }

    return status;
}
