/*
 *
 *    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;
class TestTimer;

/**
 * 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 LayerImplSelect;
    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);
        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 TestTimer;
    ObjectPool<Timer, CHIP_SYSTEM_CONFIG_NUM_TIMERS> mTimerPool;
};

} // namespace System
} // namespace chip
