/*
 *
 *    Copyright (c) 2020 Project CHIP Authors
 *    Copyright (c) 2016-2017 Nest Labs, Inc.
 *
 *    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.
 */

/**
 *    @file
 *      This file defines the member functions and private data for
 *      the chip::System::Timer class, which is used for
 *      representing an in-progress one-shot timer.
 */

// Include module header
#include <system/SystemTimer.h>

// Include common private header
#include "SystemLayerPrivate.h"

// Include local headers
#include <string.h>

#include <system/SystemError.h>
#include <system/SystemFaultInjection.h>
#include <system/SystemLayer.h>

#include <support/CodeUtils.h>

/*******************************************************************************
 * Timer state
 *
 * There are two fundamental state-change variables: Object::mSystemLayer and
 * Timer::OnComplete. These must be checked and changed atomically. The state
 * of the timer is governed by the following state machine:
 *
 *  INITIAL STATE: mSystemLayer == NULL, OnComplete == NULL
 *      |
 *      V
 *  UNALLOCATED<-----------------------------+
 *      |                                    |
 *  (set mSystemLayer != NULL)               |
 *      |                                    |
 *      V                                    |
 *  ALLOCATED-------(set mSystemLayer NULL)--+
 *      |    \-----------------------------+
 *      |                                  |
 *  (set OnComplete != NULL)               |
 *      |                                  |
 *      V                                  |
 *    ARMED ---------( clear OnComplete )--+
 *
 * When in the ARMED state:
 *
 *     * None of the member variables may mutate.
 *     * OnComplete must only be cleared by Cancel() or HandleComplete()
 *     * Cancel() and HandleComplete() will test that they are the one to
 *       successfully set OnComplete NULL. And if so, that will be the
 *       thread that must call Object::Release().
 *
 *******************************************************************************
 */

namespace chip {
namespace System {

ObjectPool<Timer, CHIP_SYSTEM_CONFIG_NUM_TIMERS> Timer::sPool;

/**
 *  This method returns the current epoch, corrected by system sleep with the system timescale, in milliseconds.
 *
 *  DEPRECATED -- Please use System::Layer::GetClock_MonotonicMS() instead.
 *
 *  @return A timestamp in milliseconds.
 */
Timer::Epoch Timer::GetCurrentEpoch(void)
{
    return Platform::Layer::GetClock_MonotonicMS();
}

/**
 *  Compares two Timer::Epoch values and returns true if the first value is earlier than the second value.
 *
 *  @brief
 *      A static API that gets called to compare 2 time values.  This API attempts to account for timer wrap by assuming that the
 *      difference between the 2 input values will only be more than half the Epoch scalar range if a timer wrap has occurred
 *      between the 2 samples.
 *
 *  @note
 *      This implementation assumes that Timer::Epoch is an unsigned scalar type.
 *
 *  @return true if the first param is earlier than the second, false otherwise.
 */
bool Timer::IsEarlierEpoch(const Timer::Epoch & inFirst, const Timer::Epoch & inSecond)
{
    static const Epoch kMaxTime_2 = static_cast<Epoch>((static_cast<Epoch>(0) - static_cast<Epoch>(1)) / 2);

    // account for timer wrap with the assumption that no two input times will "naturally"
    // be more than half the timer range apart.
    return (((inFirst < inSecond) && (inSecond - inFirst < kMaxTime_2)) ||
            ((inFirst > inSecond) && (inFirst - inSecond > kMaxTime_2)));
}

/**
 *  This method registers an one-shot timer with the underlying timer mechanism provided by the platform.
 *
 *  @param[in]  aDelayMilliseconds  The number of milliseconds before this timer fires
 *  @param[in]  aOnComplete          A pointer to the callback function when this timer fires
 *  @param[in]  aAppState            An arbitrary pointer to be passed into onComplete when this timer fires
 *
 *  @retval #CHIP_SYSTEM_NO_ERROR Unconditionally.
 *
 */
Error Timer::Start(uint32_t aDelayMilliseconds, OnCompleteFunct aOnComplete, void * aAppState)
{
    Layer & lLayer = this->SystemLayer();

    CHIP_SYSTEM_FAULT_INJECT(FaultInjection::kFault_TimeoutImmediate, aDelayMilliseconds = 0);

    this->AppState     = aAppState;
    this->mAwakenEpoch = Timer::GetCurrentEpoch() + static_cast<Epoch>(aDelayMilliseconds);
    if (!__sync_bool_compare_and_swap(&this->OnComplete, NULL, aOnComplete))
    {
        chipDie();
    }

#if CHIP_SYSTEM_CONFIG_USE_LWIP
    // add to the sorted list of timers. Earliest timer appears first.
    if (lLayer.mTimerList == NULL || this->IsEarlierEpoch(this->mAwakenEpoch, lLayer.mTimerList->mAwakenEpoch))
    {
        this->mNextTimer  = lLayer.mTimerList;
        lLayer.mTimerList = this;

        // this is the new eariest timer and so the timer needs (re-)starting provided that
        // the system is not currently processing expired timers, in which case it is left to
        // HandleExpiredTimers() to re-start the timer.
        if (!lLayer.mTimerComplete)
        {
            lLayer.StartPlatformTimer(aDelayMilliseconds);
        }
    }
    else
    {
        Timer * lTimer = lLayer.mTimerList;

        while (lTimer->mNextTimer)
        {
            if (this->IsEarlierEpoch(this->mAwakenEpoch, lTimer->mNextTimer->mAwakenEpoch))
            {
                // found the insert location.
                break;
            }

            lTimer = lTimer->mNextTimer;
        }

        this->mNextTimer   = lTimer->mNextTimer;
        lTimer->mNextTimer = this;
    }
#endif // CHIP_SYSTEM_CONFIG_USE_LWIP
#if CHIP_SYSTEM_CONFIG_USE_SOCKETS
    lLayer.WakeSelect();
#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS

    return CHIP_SYSTEM_NO_ERROR;
}

Error Timer::ScheduleWork(OnCompleteFunct aOnComplete, void * aAppState)
{
    Error err      = CHIP_SYSTEM_NO_ERROR;
    Layer & lLayer = this->SystemLayer();

    this->AppState     = aAppState;
    this->mAwakenEpoch = Timer::GetCurrentEpoch();
    if (!__sync_bool_compare_and_swap(&this->OnComplete, NULL, aOnComplete))
    {
        chipDie();
    }

#if CHIP_SYSTEM_CONFIG_USE_LWIP
    err = lLayer.PostEvent(*this, chip::System::kEvent_ScheduleWork, 0);
#endif // CHIP_SYSTEM_CONFIG_USE_LWIP
#if CHIP_SYSTEM_CONFIG_USE_SOCKETS
    lLayer.WakeSelect();
#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS

    return err;
}

/**
 *  This method de-initializes the timer object, and prevents this timer from firing if it hasn't done so.
 *
 *  @retval #CHIP_SYSTEM_NO_ERROR Unconditionally.
 */
Error Timer::Cancel()
{
#if CHIP_SYSTEM_CONFIG_USE_LWIP
    Layer & lLayer = this->SystemLayer();
#endif // CHIP_SYSTEM_CONFIG_USE_LWIP
    OnCompleteFunct lOnComplete = this->OnComplete;

    // Check if the timer is armed
    VerifyOrExit(lOnComplete != NULL, );
    // Atomically disarm if the value has not changed
    VerifyOrExit(__sync_bool_compare_and_swap(&this->OnComplete, lOnComplete, NULL), );

    // Since this thread changed the state of OnComplete, release the timer.
    this->AppState = NULL;

#if CHIP_SYSTEM_CONFIG_USE_LWIP
    if (lLayer.mTimerList)
    {
        if (this == lLayer.mTimerList)
        {
            lLayer.mTimerList = this->mNextTimer;
        }
        else
        {
            Timer * lTimer = lLayer.mTimerList;

            while (lTimer->mNextTimer)
            {
                if (this == lTimer->mNextTimer)
                {
                    lTimer->mNextTimer = this->mNextTimer;
                    break;
                }

                lTimer = lTimer->mNextTimer;
            }
        }

        this->mNextTimer = NULL;
    }
#endif // CHIP_SYSTEM_CONFIG_USE_LWIP

    this->Release();
exit:
    return CHIP_SYSTEM_NO_ERROR;
}

/**
 *  This method is called by the underlying timer mechanism provided by the platform when the timer fires.
 */
void Timer::HandleComplete()
{
    // Save information needed to perform the callback.
    Layer & lLayer                    = this->SystemLayer();
    const OnCompleteFunct lOnComplete = this->OnComplete;
    void * lAppState                  = this->AppState;

    // Check if timer is armed
    VerifyOrExit(lOnComplete != NULL, );
    // Atomically disarm if the value has not changed.
    VerifyOrExit(__sync_bool_compare_and_swap(&this->OnComplete, lOnComplete, NULL), );

    // Since this thread changed the state of OnComplete, release the timer.
    AppState = NULL;
    this->Release();

    // Invoke the app's callback, if it's still valid.
    if (lOnComplete != NULL)
        lOnComplete(&lLayer, lAppState, CHIP_SYSTEM_NO_ERROR);

exit:
    return;
}

#if CHIP_SYSTEM_CONFIG_USE_LWIP
/**
 * Completes any timers that have expired.
 *
 *  @brief
 *      A static API that gets called when the platform timer expires. Any expired timers are completed and removed from the list
 *      of active timers in the layer object. If unexpired timers remain on completion, StartPlatformTimer will be called to
 *      restart the platform timer.
 *
 *  @note
 *      It's harmless if this API gets called and there are no expired timers.
 *
 *  @return CHIP_SYSTEM_NO_ERROR on success, error code otherwise.
 *
 */
Error Timer::HandleExpiredTimers(Layer & aLayer)
{
    size_t timersHandled = 0;

    // Expire each timer in turn until an unexpired timer is reached or the timerlist is emptied.  We set the current expiration
    // time outside the loop; that way timers set after the current tick will not be executed within this expiration window
    // regardless how long the processing of the currently expired timers took
    Epoch currentEpoch = Timer::GetCurrentEpoch();

    while (aLayer.mTimerList)
    {
        // limit the number of timers handled before the control is returned to the event queue.  The bound is similar to
        // (though not exactly same) as that on the sockets-based systems.

        // The platform timer API has MSEC resolution so expire any timer with less than 1 msec remaining.
        if ((timersHandled < Timer::sPool.Size()) && Timer::IsEarlierEpoch(aLayer.mTimerList->mAwakenEpoch, currentEpoch + 1))
        {
            Timer & lTimer    = *aLayer.mTimerList;
            aLayer.mTimerList = lTimer.mNextTimer;
            lTimer.mNextTimer = NULL;

            aLayer.mTimerComplete = true;
            lTimer.HandleComplete();
            aLayer.mTimerComplete = false;

            timersHandled++;
        }
        else
        {
            // timers still exist so restart the platform timer.
            uint64_t delayMilliseconds = 0ULL;

            currentEpoch = Timer::GetCurrentEpoch();

            // the next timer expires in the future, so set the delayMilliseconds to a non-zero value
            if (currentEpoch < aLayer.mTimerList->mAwakenEpoch)
            {
                delayMilliseconds = aLayer.mTimerList->mAwakenEpoch - currentEpoch;
            }
            /*
             * StartPlatformTimer() accepts a 32bit value in milliseconds.  Epochs are 64bit numbers.  The only way in which this
             * could overflow is if time went backwards (e.g. as a result of a time adjustment from time synchronization).  Verify
             * that the timer can still be executed (even if it is very late) and exit if that is the case.  Note: if the time sync
             * ever ends up adjusting the clock, we should implement a method that deals with all the timers in the system.
             */
            VerifyOrDie(delayMilliseconds <= UINT32_MAX);

            aLayer.StartPlatformTimer(static_cast<uint32_t>(delayMilliseconds));
            break; // all remaining timers are still ticking.
        }
    }

    return CHIP_SYSTEM_NO_ERROR;
}
#endif // CHIP_SYSTEM_CONFIG_USE_LWIP

} // namespace System
} // namespace chip
