/*
 *  Copyright (c) 2019, The OpenThread Authors.
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 *  1. Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *  2. Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *  3. Neither the name of the copyright holder nor the
 *     names of its contributors may be used to endorse or promote products
 *     derived from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 *  POSSIBILITY OF SUCH DAMAGE.
 */

/**
 * @file
 *   This file implements the OpenThread platform abstraction for the alarm.
 *
 */

#include <assert.h>
#include <stdbool.h>
#include <stdint.h>

#include "openthread-system.h"
#include <openthread/config.h>
#include <openthread/platform/alarm-milli.h>
#include <openthread/platform/diag.h>
#include "common/logging.hpp"

#include "platform-efr32.h"
#include "utils/code_utils.h"

#include "em_core.h"
#include "rail.h"

#define XTAL_ACCURACY 200
#define US_IN_MS 1000

// Minimum duration of an alarm in milliseconds. Used to avoid setting the absolute
// expiry time of an alarm to the current time or slightly in the past.
#define TIMER_EPSILON_MS 1

// The longest Rail can set a timer is 53 minutes.  Timers of a longer duration
// must wake up before this and set another timer for the remainder.  We currently
// split long delays in 30 minute intervals using a value of 1800000.
#define RAIL_TIMER_MAX_DELTA_MS 1800000

static uint32_t sTimerHi   = 0;
static uint32_t sTimerLo   = 0;
static uint32_t sAlarmT0   = 0;
static uint32_t sAlarmDt   = 0;
static bool     sIsRunning = false;

static void RAILCb_TimerExpired(RAIL_Handle_t aHandle)
{
    otSysEventSignalPending();
}

void efr32AlarmInit(void)
{
}

uint64_t otPlatTimeGet(void)
{
    uint32_t timer_lo;
    uint64_t timer_us;

    CORE_DECLARE_IRQ_STATE;
    CORE_ENTER_CRITICAL();

    timer_lo = RAIL_GetTime();

    if (timer_lo < sTimerLo)
    {
        sTimerHi++;
    }

    sTimerLo = timer_lo;

    timer_us = (((uint64_t)sTimerHi << 32) | sTimerLo);

    CORE_EXIT_CRITICAL();

    return timer_us;
}

uint32_t otPlatAlarmMilliGetNow(void)
{
    return otPlatTimeGet() / US_IN_MS;
}

uint32_t otPlatTimeGetXtalAccuracy(void)
{
    return XTAL_ACCURACY;
}

void otPlatAlarmMilliStartAt(otInstance *aInstance, uint32_t t0, uint32_t dt)
{
    OT_UNUSED_VARIABLE(aInstance);
    uint32_t      expires_microsec;
    RAIL_Status_t status;

    assert(gRailHandle != NULL);

    if (sIsRunning)
    {
        RAIL_CancelTimer(gRailHandle);
    }

    sAlarmT0 = t0;
    sAlarmDt = dt;

    if (dt > RAIL_TIMER_MAX_DELTA_MS)
    {
        dt = RAIL_TIMER_MAX_DELTA_MS;
    }
    else if (dt < TIMER_EPSILON_MS)
    {
        dt = TIMER_EPSILON_MS;
    }

    expires_microsec = (t0 + dt) * US_IN_MS;
    status           = RAIL_SetTimer(gRailHandle, expires_microsec, RAIL_TIME_ABSOLUTE, RAILCb_TimerExpired);

    if (status != RAIL_STATUS_NO_ERROR)
    {
        // The RAIL timer could not be set due to expiration time being in the past with respect to RAIL's current
        // time which is in microseconds. We fallback to using a relative timer from the current time.

        expires_microsec = dt * US_IN_MS;
        status           = RAIL_SetTimer(gRailHandle, expires_microsec, RAIL_TIME_DELAY, RAILCb_TimerExpired);

        if (status != RAIL_STATUS_NO_ERROR)
        {
            otLogCritPlat("Alarm start timer failed, status: %d, dt: %u, t0: %u, now: %u", status, dt, t0,
                          otPlatAlarmMilliGetNow());
            assert(false);
        }
    }

    sIsRunning = true;
}

void otPlatAlarmMilliStop(otInstance *aInstance)
{
    OT_UNUSED_VARIABLE(aInstance);

    sIsRunning = false;

    assert(gRailHandle != NULL);
    RAIL_CancelTimer(gRailHandle);
}

void efr32AlarmProcess(otInstance *aInstance)
{
    uint32_t      now;
    uint32_t      new_expires_microsec;
    uint32_t      dt;
    RAIL_Status_t status;

    otEXPECT(sIsRunning);

    assert(gRailHandle != NULL);

    if (RAIL_IsTimerExpired(gRailHandle))
    {
        sIsRunning = false;

        if (sAlarmDt > RAIL_TIMER_MAX_DELTA_MS)
        {
            // We split longer delays in two due to the maximum allowed timer in RAIL.  Here we
            // re-arm the RAIL timer with the remaining part of the alarm.

            now = otPlatAlarmMilliGetNow();
            dt  = (sAlarmT0 + sAlarmDt) - now;

            if (dt > RAIL_TIMER_MAX_DELTA_MS)
            {
                dt = RAIL_TIMER_MAX_DELTA_MS;
            }
            else if (dt < TIMER_EPSILON_MS)
            {
                dt = TIMER_EPSILON_MS;
            }

            new_expires_microsec = (now + dt) * US_IN_MS;
            status = RAIL_SetTimer(gRailHandle, new_expires_microsec, RAIL_TIME_ABSOLUTE, RAILCb_TimerExpired);

            if (status != RAIL_STATUS_NO_ERROR)
            {
                new_expires_microsec = dt * US_IN_MS;
                status = RAIL_SetTimer(gRailHandle, new_expires_microsec, RAIL_TIME_DELAY, RAILCb_TimerExpired);

                if (status != RAIL_STATUS_NO_ERROR)
                {
                    otLogCritPlat("Alarm extend timer failed, status: %d, dt: %u, now: %u", status, dt,
                                  otPlatAlarmMilliGetNow());
                    assert(false);
                }
            }

            sIsRunning = true;
        }
        else
        {
#if OPENTHREAD_CONFIG_DIAG_ENABLE
            if (otPlatDiagModeGet())
            {
                otPlatDiagAlarmFired(aInstance);
            }
            else
#endif
            {
                otPlatAlarmMilliFired(aInstance);
            }
        }
    }
exit:
    return;
}
