/*
 *
 *    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 "FreeRtosHooks.h"

#include "FreeRTOS.h"
#include "semphr.h"

#include <assert.h>

#include <stdio.h>
#include <string.h>

#include "PDM.h"
#include "PWR_Interface.h"
#include "TimersManager.h"
#include "board.h"
#include "pdm_ram_storage_glue.h"

/* Bluetooth Low Energy */
#include "ble_config.h"
#include "l2ca_cb_interface.h"

#include "controller_interface.h"

#if defined gLoggingActive_d && (gLoggingActive_d > 0)
#include "dbg_logging.h"
#ifndef DBG_APP
#define DBG_APP 0
#endif
#define APP_DBG_LOG(fmt, ...)                                                                                                      \
    if (DBG_APP)                                                                                                                   \
        do                                                                                                                         \
        {                                                                                                                          \
            DbgLogAdd(__FUNCTION__, fmt, VA_NUM_ARGS(__VA_ARGS__), ##__VA_ARGS__);                                                 \
        } while (0);
#else
#define APP_DBG_LOG(...)
#endif

#if (configUSE_TICKLESS_IDLE != 0)
#define DBG_PostStepTickAssess 0
#if DBG_PostStepTickAssess && !gTimestampUseWtimer_c
#error "gTimestampUseWtimer_c required for DBG_PostStepTickAssess"
#endif
#if defined(gPWR_FreqScalingWFI) && (gPWR_FreqScalingWFI != 0)
/* this MACRO is required when gPWR_FreqScalingWFI is not equal to zero (system clock frequency
    reduced in WFI)           */
#define App_SuppressTickInStopMode 1
#else
#define App_SuppressTickInStopMode 0
#endif
#if gPWR_CpuClk_48MHz
/* for systick accuracy, this is recommended to enable FRO calibration */
#define gApp_SystemClockCalibration 1
#endif
#endif

#define PDM_MAX_WRITES_INFINITE 0xFF

static inline void mutex_init(mbedtls_threading_mutex_t * p_mutex)
{
    assert(p_mutex != NULL);
    *p_mutex = xSemaphoreCreateMutex();
    assert(*p_mutex != NULL);
}

static inline void mutex_free(mbedtls_threading_mutex_t * p_mutex)
{
    assert(p_mutex != NULL);
    assert(*p_mutex != NULL);
    vSemaphoreDelete(*p_mutex);
}

static inline int mutex_lock(mbedtls_threading_mutex_t * p_mutex)
{
    assert(p_mutex != NULL);
    assert(*p_mutex != NULL);
    return xSemaphoreTake(*p_mutex, portMAX_DELAY) != pdTRUE;
}

static inline int mutex_unlock(mbedtls_threading_mutex_t * p_mutex)
{
    assert(p_mutex != NULL);
    assert(*p_mutex != NULL);
    return xSemaphoreGive(*p_mutex) != pdTRUE;
}

void freertos_mbedtls_mutex_init(void)
{
    mbedtls_threading_set_alt(mutex_init, mutex_free, mutex_lock, mutex_unlock);
}

void freertos_mbedtls_mutex_free(void)
{
    mbedtls_threading_free_alt();
}

#if defined(cPWR_UsePowerDownMode) && (cPWR_UsePowerDownMode) && (configUSE_TICKLESS_IDLE != 0)

/*
 * Setup the systick timer to generate the tick interrupts at the required
 * frequency.
 */
void vPortSetupTimerInterrupt(void)
{
    /* Stop and clear the SysTick. */
    SysTick->CTRL = 0UL;
    SysTick->VAL  = 0UL;

#if DBG_PostStepTickAssess
    tickless_SystickCheckDriftInit();
#endif

    /* configure module for tickless mode */
    tickless_init();

#if gApp_SystemClockCalibration
    /* calibration on the internal FRO48MHz clock - this clock is inaccurate (2%),
     * so it needs calibration if we want the systick to be accurate to less
     * than 500pp. */
    tickless_StartFroCalibration();
#endif

    /* Configure SysTick to interrupt at the requested rate. */
    SysTick_Config(CLOCK_GetFreq(kCLOCK_CoreSysClk) / configTICK_RATE_HZ);
}

void vPortSuppressTicksAndSleep(TickType_t xExpectedIdleTime)
{
    tmrlp_tickless_systick_t lp_ctx;
    APP_DBG_LOG("xExpectedIdleTime = %d ticks %d ms", xExpectedIdleTime, xExpectedIdleTime * portTICK_PERIOD_MS);
    OSA_InterruptDisable();

    /* Do not go to sleep, lowpower or WFI if there is a pending task to schedule
     * Scheduler is suspended when calling vPortSuppressTicksAndSleep,
     * as interrupt are disabled if one is pending, eTaskConfirmSleepModeStatus
     * will prevent sleep.
     */
    if (eTaskConfirmSleepModeStatus() == eAbortSleep)
    {
        APP_DBG_LOG("task to schedule");
        /* Do nothing */
    }
#if gApp_SystemClockCalibration
    /* Prevent lowpower / tickless mode if cal ongoing - get estimated core freq */
    else if (tickless_EstimateCoreClockFreq())
    {
        /* can eventually enter sleep or re evaluate on next idle loop, the calibration shall take 4 ms average */
        // PWR_EnterSleep();
    }
#endif

    /* Do not go to power down if:
     * - the RTOS is expecting a wake-up too close to the current date
     * To worth a power down the xExpectedIdleTime should be
     * > to 2 rtos tick (which includes residual_count worst margin + carry after wake-up worst margin)
     * + enter/exist power down duration converted in RTOS tick
     * - power down is not allowed
     */
    else if ((xExpectedIdleTime >
              (2 + ((PWR_SYSTEM_EXIT_LOW_POWER_DURATION_MS + PWR_SYSTEM_ENTER_LOW_POWER_DURATION_MS) / portTICK_PERIOD_MS) + 1)))
    {
        int result = PWR_CheckIfDeviceCanGoToSleepExt();
        if (result >= kPmPowerDown0)
        {
            PWR_WakeupReason_t wakeupReason;
            lp_ctx.exitTicklessDuration32kTick = MILLISECONDS_TO_TICKS32K(PWR_SYSTEM_EXIT_LOW_POWER_DURATION_MS);
            /* Tickless pre processing */
            tickless_PreProcessing(&lp_ctx, xExpectedIdleTime);

            /* Enter power down */
            wakeupReason = PWR_EnterPowerDown();

            APP_DBG_LOG("wakeReason=%x", (uint16_t) wakeupReason.AllBits);
            (void) wakeupReason;

            /* Tickless post processing */
            tickless_PostProcessing(&lp_ctx);

#if DBG_PostStepTickAssess
            if (wakeupReason.Bits.FromTMR == 1)
                configASSERT(lp_ctx.idle_tick_jump == xExpectedIdleTime);
            if (wakeupReason.Bits.DidPowerDown == 1)
                configASSERT((wakeupReason.AllBits & ~0x8000U) != 0);
#endif
        }
        else if ((result == kPmSleep) || (result < 0))
        {
#if App_SuppressTickInStopMode
            lp_ctx.exitTicklessDuration32kTick = 0;
            /* Tickless pre processing */
            tickless_PreProcessing(&lp_ctx, xExpectedIdleTime);
#endif

            PWR_EnterSleep();

#if App_SuppressTickInStopMode
            /* Tickless post processing */
            tickless_PostProcessing(&lp_ctx);
#endif
        }
    }
    else
    {
#if App_SuppressTickInStopMode
        lp_ctx.exitTicklessDuration32kTick = 0;
        /* Tickless pre processing */
        tickless_PreProcessing(&lp_ctx, xExpectedIdleTime);
#endif

        PWR_EnterSleep();

#if App_SuppressTickInStopMode
        /* Tickless post processing */
        tickless_PostProcessing(&lp_ctx);
#endif
    }

#if DBG_PostStepTickAssess
    tickless_SystickCheckDrift();
#endif

    OSA_InterruptEnable();
}
#endif /*  (cPWR_UsePowerDownMode) && (configUSE_TICKLESS_IDLE != 0) */

static void BOARD_ActionOnIdle(void)
{
#if ((defined gTcxo32k_ModeEn_c) && (gTcxo32k_ModeEn_c != 0))
    BOARD_tcxo32k_compensation_run(2, 0);
#endif
#if ((defined gTcxo32M_ModeEn_c) && (gTcxo32M_ModeEn_c != 0))
    BOARD_tcxo32M_compensation_run(2, 10); /* 2 degrees - wait for 10us */
#endif
}

extern void OTAIdleActivities(void);

void vApplicationIdleHook(void)
{
    FS_vIdleTask(PDM_MAX_WRITES_INFINITE);

    OTAIdleActivities();

#if gAdcUsed_d
    BOARD_ADCMeasure();
#endif

    BOARD_ActionOnIdle();
}
