/*
 *
 *    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 contains declarations of the
 *      chip::System::Layer class and its related types, data and
 *      functions.
 */

#ifndef SYSTEMLAYER_H
#define SYSTEMLAYER_H

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

#include <support/DLLUtil.h>
#include <system/SystemError.h>
#include <system/SystemEvent.h>
#include <system/SystemObject.h>

// Include dependent headers
#if CHIP_SYSTEM_CONFIG_USE_SOCKETS
#include <sys/select.h>
#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS

#if CHIP_SYSTEM_CONFIG_POSIX_LOCKING
#include <pthread.h>
#endif // CHIP_SYSTEM_CONFIG_POSIX_LOCKING

namespace chip {
namespace System {

class Layer;
class Timer;

#if CHIP_SYSTEM_CONFIG_USE_LWIP
class Object;
#endif // CHIP_SYSTEM_CONFIG_USE_LWIP

namespace Platform {
namespace Layer {

using ::chip::System::Error;
using ::chip::System::Layer;

#if CHIP_SYSTEM_CONFIG_USE_LWIP
using ::chip::System::Object;
#endif // CHIP_SYSTEM_CONFIG_USE_LWIP

extern Error WillInit(Layer & aLayer, void * aContext);
extern Error WillShutdown(Layer & aLayer, void * aContext);

extern void DidInit(Layer & aLayer, void * aContext, Error aStatus);
extern void DidShutdown(Layer & aLayer, void * aContext, Error aStatus);

#if CHIP_SYSTEM_CONFIG_USE_LWIP
extern Error PostEvent(Layer & aLayer, void * aContext, Object & aTarget, EventType aType, uintptr_t aArgument);
extern Error DispatchEvents(Layer & aLayer, void * aContext);
extern Error DispatchEvent(Layer & aLayer, void * aContext, Event aEvent);
extern Error StartTimer(Layer & aLayer, void * aContext, uint32_t aMilliseconds);
#endif // CHIP_SYSTEM_CONFIG_USE_LWIP

} // namespace Layer
} // namespace Platform

/**
 *  @enum LayerState
 *
 *  The state of a Layer object.
 */
enum LayerState
{
    kLayerState_NotInitialized = 0, /**< Not initialized state. */
    kLayerState_Initialized    = 1  /**< Initialized state. */
};

#if CHIP_SYSTEM_CONFIG_USE_LWIP
typedef Error (*LwIPEventHandlerFunction)(Object & aTarget, EventType aEventType, uintptr_t aArgument);

class LwIPEventHandlerDelegate
{
    friend class Layer;

public:
    bool IsInitialized(void) const;
    void Init(LwIPEventHandlerFunction aFunction);
    void Prepend(const LwIPEventHandlerDelegate *& aDelegateList);

private:
    LwIPEventHandlerFunction mFunction;
    const LwIPEventHandlerDelegate * mNextDelegate;
};
#endif // CHIP_SYSTEM_CONFIG_USE_LWIP

/**
 *  @class Layer
 *
 *  @brief
 *      This provides access to timers according to the configured event handling model.
 *
 *      For \c CHIP_SYSTEM_CONFIG_USE_SOCKETS, event readiness notification is handled via traditional poll/select implementation on
 *      the platform adaptation.
 *
 *      For \c CHIP_SYSTEM_CONFIG_USE_LWIP, event readiness notification is handle via events / messages and platform- and
 *      system-specific hooks for the event/message system.
 */
class DLL_EXPORT Layer
{
public:
    Layer(void);

    Error Init(void * aContext);
    Error Shutdown(void);

    void * GetPlatformData(void) const;
    void SetPlatformData(void * aPlatformData);

    LayerState State(void) const;

    Error NewTimer(Timer *& aTimerPtr);

    typedef void (*TimerCompleteFunct)(Layer * aLayer, void * aAppState, Error aError);
    Error StartTimer(uint32_t aMilliseconds, TimerCompleteFunct aComplete, void * aAppState);
    void CancelTimer(TimerCompleteFunct aOnComplete, void * aAppState);

    Error ScheduleWork(TimerCompleteFunct aComplete, void * aAppState);

#if CHIP_SYSTEM_CONFIG_USE_SOCKETS
    void PrepareSelect(int & aSetSize, fd_set * aReadSet, fd_set * aWriteSet, fd_set * aExceptionSet, struct timeval & aSleepTime);
    void HandleSelectResult(int aSetSize, fd_set * aReadSet, fd_set * aWriteSet, fd_set * aExceptionSet);
    void WakeSelect(void);
#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS

#if CHIP_SYSTEM_CONFIG_USE_LWIP
    typedef Error (*EventHandler)(Object & aTarget, EventType aEventType, uintptr_t aArgument);
    Error AddEventHandlerDelegate(LwIPEventHandlerDelegate & aDelegate);

    // Event Handling
    Error PostEvent(Object & aTarget, EventType aEventType, uintptr_t aArgument);
    Error DispatchEvents(void);
    Error DispatchEvent(Event aEvent);
    Error HandleEvent(Object & aTarget, EventType aEventType, uintptr_t aArgument);

    // Timer Management
    Error HandlePlatformTimer(void);
#endif // CHIP_SYSTEM_CONFIG_USE_LWIP

    static uint64_t GetClock_Monotonic(void);
    static uint64_t GetClock_MonotonicMS(void);
    static uint64_t GetClock_MonotonicHiRes(void);
    static Error GetClock_RealTime(uint64_t & curTime);
    static Error GetClock_RealTimeMS(uint64_t & curTimeMS);
    static Error SetClock_RealTime(uint64_t newCurTime);

private:
    LayerState mLayerState;
    void * mContext;
    void * mPlatformData;

#if CHIP_SYSTEM_CONFIG_USE_LWIP
    static LwIPEventHandlerDelegate sSystemEventHandlerDelegate;

    const LwIPEventHandlerDelegate * mEventDelegateList;
    Timer * mTimerList;
    bool mTimerComplete;
#endif // CHIP_SYSTEM_CONFIG_USE_LWIP

#if CHIP_SYSTEM_CONFIG_USE_SOCKETS
    int mWakePipeIn;
    int mWakePipeOut;

#if CHIP_SYSTEM_CONFIG_POSIX_LOCKING
    pthread_t mHandleSelectThread;
#endif // CHIP_SYSTEM_CONFIG_POSIX_LOCKING
#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS

#if CHIP_SYSTEM_CONFIG_USE_LWIP
    static Error HandleSystemLayerEvent(Object & aTarget, EventType aEventType, uintptr_t aArgument);

    Error StartPlatformTimer(uint32_t aDelayMilliseconds);

    friend Error Platform::Layer::PostEvent(Layer & aLayer, void * aContext, Object & aTarget, EventType aType,
                                            uintptr_t aArgument);
    friend Error Platform::Layer::DispatchEvents(Layer & aLayer, void * aContext);
    friend Error Platform::Layer::DispatchEvent(Layer & aLayer, void * aContext, Event aEvent);
    friend Error Platform::Layer::StartTimer(Layer & aLayer, void * aContext, uint32_t aMilliseconds);
#endif // CHIP_SYSTEM_CONFIG_USE_LWIP

    // Copy and assignment NOT DEFINED
    Layer(const Layer &);
    Layer & operator=(const Layer &);

    friend class Timer;
};

/**
 * This returns the current state of the layer object.
 */
inline LayerState Layer::State(void) const
{
    return this->mLayerState;
}

} // namespace System
} // namespace chip

#endif // defined(SYSTEMLAYER_H)
