/*
 *
 *    Copyright (c) 2016-2017 Nest Labs, Inc.
 *    All rights reserved.
 *
 *    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
 *      nl::Weave::System::Layer class and its related types, data and
 *      functions.
 */

#ifndef SYSTEMLAYER_H
#define SYSTEMLAYER_H

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

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

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

#include <Weave/Support/NLDLLUtil.h>

#include <SystemLayer/SystemError.h>
#include <SystemLayer/SystemObject.h>
#include <SystemLayer/SystemEvent.h>

#if WEAVE_SYSTEM_CONFIG_PROVIDE_OBSOLESCENT_INTERFACES

namespace nl {
namespace Inet {

class InetLayer;

} // namespace Inet
} // namespace nl

#endif // WEAVE_SYSTEM_CONFIG_PROVIDE_OBSOLESCENT_INTERFACES

namespace nl {
namespace Weave {
namespace System {

class Layer;
class Timer;

#if WEAVE_SYSTEM_CONFIG_USE_LWIP
class Object;
#endif // WEAVE_SYSTEM_CONFIG_USE_LWIP

namespace Platform {
namespace Layer {

using ::nl::Weave::System::Error;
using ::nl::Weave::System::Layer;

#if WEAVE_SYSTEM_CONFIG_USE_LWIP
using ::nl::Weave::System::Object;
#endif // WEAVE_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 WEAVE_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 // WEAVE_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 WEAVE_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 // WEAVE_SYSTEM_CONFIG_USE_LWIP

/**
 *  @class Layer
 *
 *  @brief
 *      This provides access to timers according to the configured event handling model.
 *
 *      For #WEAVE_SYSTEM_CONFIG_USE_SOCKETS, event readiness notification is handled via traditional poll/select implementation on
 *      the platform adaptation.
 *
 *      For #WEAVE_SYSTEM_CONFIG_USE_LWIP, event readiness notification is handle via events / messages and platform- and
 *      system-specific hooks for the event/message system.
 */
class NL_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 WEAVE_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 // WEAVE_SYSTEM_CONFIG_USE_SOCKETS

#if WEAVE_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 // WEAVE_SYSTEM_CONFIG_USE_LWIP

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

#if WEAVE_SYSTEM_CONFIG_USE_LWIP
    static LwIPEventHandlerDelegate sSystemEventHandlerDelegate;

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

#if WEAVE_SYSTEM_CONFIG_USE_SOCKETS
    int mWakePipeIn;
    int mWakePipeOut;

#if WEAVE_SYSTEM_CONFIG_POSIX_LOCKING
    pthread_t mHandleSelectThread;
#endif // WEAVE_SYSTEM_CONFIG_POSIX_LOCKING
#endif // WEAVE_SYSTEM_CONFIG_USE_SOCKETS

#if WEAVE_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 // WEAVE_SYSTEM_CONFIG_USE_LWIP

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

    friend class Timer;

#if WEAVE_SYSTEM_CONFIG_PROVIDE_OBSOLESCENT_INTERFACES
    friend class Inet::InetLayer;
    void CancelAllMatchingInetTimers(Inet::InetLayer& aInetLayer, void* aOnCompleteInetLayer, void* aAppState);
#endif // WEAVE_SYSTEM_CONFIG_PROVIDE_OBSOLESCENT_INTERFACES
};

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

} // namespace System
} // namespace Weave
} // namespace nl

#endif // defined(SYSTEMLAYER_H)
