/*
 *
 *    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.
 */

/**
 *  This file defines the chip::System::Timer class and related types that can be used for representing
 *  an in-progress one-shot timer. Implementations of System::Layer may (but are not required to) use
 *  these for their versions of timer events.
 */

#pragma once

// Include configuration headers
#include <system/SystemConfig.h>

// Include dependent headers
#include <lib/support/DLLUtil.h>
#include <lib/support/Pool.h>

#include <system/SystemClock.h>
#include <system/SystemError.h>
#include <system/SystemLayer.h>
#include <system/SystemStats.h>

#if CHIP_SYSTEM_CONFIG_USE_DISPATCH
#include <dispatch/dispatch.h>
#endif

namespace chip {
namespace System {

class Layer;

/**
 * Basic Timer information: time and callback.
 */
class DLL_EXPORT TimerData
{
public:
    class Callback
    {
    public:
        Callback(Layer & systemLayer, TimerCompleteCallback onComplete, void * appState) :
            mSystemLayer(&systemLayer), mOnComplete(onComplete), mAppState(appState)
        {}
        void Invoke() const { mOnComplete(mSystemLayer, mAppState); }
        const TimerCompleteCallback & GetOnComplete() const { return mOnComplete; }
        void * GetAppState() const { return mAppState; }
        Layer * GetSystemLayer() const { return mSystemLayer; }

    private:
#if CHIP_SYSTEM_CONFIG_USE_LIBEV
        friend class LayerImplSelect;
#endif
        Layer * mSystemLayer;
        TimerCompleteCallback mOnComplete;
        void * mAppState;
    };

    TimerData(Layer & systemLayer, System::Clock::Timestamp awakenTime, TimerCompleteCallback onComplete, void * appState) :
        mAwakenTime(awakenTime), mCallback(systemLayer, onComplete, appState)
    {}
    ~TimerData() = default;

    /**
     * Return the expiration time.
     */
    Clock::Timestamp AwakenTime() const { return mAwakenTime; }

    /**
     * Return callback information.
     */
    const Callback & GetCallback() const { return mCallback; }

private:
    Clock::Timestamp mAwakenTime;
    Callback mCallback;

#if CHIP_SYSTEM_CONFIG_USE_DISPATCH
    friend class LayerImplDispatch;
    dispatch_source_t mTimerSource = nullptr;
#elif CHIP_SYSTEM_CONFIG_USE_LIBEV
    friend class LayerImplSelect;
    struct ev_timer mLibEvTimer;
#endif // CHIP_SYSTEM_CONFIG_USE_DISPATCH

    // Not defined
    TimerData(const TimerData &)             = delete;
    TimerData & operator=(const TimerData &) = delete;
};

/**
 * List of `Timer`s ordered by expiration time.
 */
class TimerList
{
public:
    class Node : public TimerData
    {
    public:
        Node(Layer & systemLayer, System::Clock::Timestamp awakenTime, TimerCompleteCallback onComplete, void * appState) :
            TimerData(systemLayer, awakenTime, onComplete, appState), mNextTimer(nullptr)
        {}
        Node * mNextTimer;
    };

    TimerList() : mEarliestTimer(nullptr) {}

    /**
     * Add a timer to the list
     *
     * @return  The new earliest timer in the list. If this is the newly added timer, that implies it is earlier
     *          than any existing timer.
     */
    Node * Add(Node * timer);

    /**
     * Remove the given timer from the list, if present. It is not an error for the timer not to be present.
     *
     * @return  The new earliest timer in the list, or nullptr if the list is empty.
     */
    Node * Remove(Node * remove);

    /**
     * Remove the first timer with the given properties, if present. It is not an error for no such timer to be present.
     *
     * @return  The removed timer, or nullptr if the list contains no matching timer.
     */
    Node * Remove(TimerCompleteCallback onComplete, void * appState);

    /**
     * Remove and return the earliest timer in the list.
     *
     * @return  The earliest timer, or nullptr if the list is empty.
     */
    Node * PopEarliest();

    /**
     * Remove and return the earliest timer in the list, provided it expires earlier than the given time @a t.
     *
     * @return  The earliest timer expiring before @a t, or nullptr if there is no such timer.
     */
    Node * PopIfEarlier(Clock::Timestamp t);

    /**
     * Get the earliest timer in the list.
     *
     * @return  The earliest timer, or nullptr if there are no timers.
     */
    Node * Earliest() const { return mEarliestTimer; }

    /**
     * Test whether there are any timers.
     */
    bool Empty() const { return mEarliestTimer == nullptr; }

    /**
     * Remove and return all timers that expire before the given time @a t.
     */
    TimerList ExtractEarlier(Clock::Timestamp t);

    /**
     * Remove all timers.
     */
    void Clear() { mEarliestTimer = nullptr; }

    /**
     * Find the timer with the given properties, if present, and return its remaining time
     *
     * @return The remaining time on this partifcular timer or 0 if not found.
     */
    Clock::Timeout GetRemainingTime(TimerCompleteCallback aOnComplete, void * aAppState);

private:
    Node * mEarliestTimer;
};

/**
 * ObjectPool wrapper that keeps System Timer statistics.
 */
template <typename T = TimerList::Node>
class TimerPool
{
public:
    using Timer = T;

    /**
     * Create a new timer from the pool.
     */
    Timer * Create(Layer & systemLayer, System::Clock::Timestamp awakenTime, TimerCompleteCallback onComplete, void * appState)
    {
        Timer * timer = mTimerPool.CreateObject(systemLayer, awakenTime, onComplete, appState);
        if (timer != nullptr)
        {
            SYSTEM_STATS_INCREMENT(Stats::kSystemLayer_NumTimers);
        }

        return timer;
    }

    /**
     * Release a timer to the pool.
     */
    void Release(Timer * timer)
    {
        SYSTEM_STATS_DECREMENT(Stats::kSystemLayer_NumTimers);
        mTimerPool.ReleaseObject(timer);
    }

    /**
     * Release all timers.
     */
    void ReleaseAll()
    {
        SYSTEM_STATS_RESET(Stats::kSystemLayer_NumTimers);
        mTimerPool.ReleaseAll();
    }

    /**
     * Release a timer to the pool and invoke its callback.
     */
    void Invoke(Timer * timer)
    {
        typename Timer::Callback callback = timer->GetCallback();
        Release(timer);
        callback.Invoke();
    }

private:
    friend class TestSystemTimer_CheckTimerPool_Test;
    ObjectPool<Timer, CHIP_SYSTEM_CONFIG_NUM_TIMERS> mTimerPool;
};

} // namespace System
} // namespace chip
