/*
 *
 *    Copyright (c) 2014-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 the basis class for reference counting
 *      objects by the Inet layer as well as a class for representing
 *      the pending or resulting I/O events on a socket.
 */

#ifndef INETLAYERBASIS_H
#define INETLAYERBASIS_H

#include <InetLayer/InetConfig.h>

#include <Weave/Support/NLDLLUtil.h>
#include <SystemLayer/SystemObject.h>
#include <stdint.h>

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

namespace nl {
namespace Inet {

//--- Forward declaration of InetLayer singleton class
class InetLayer;

/**
 *  @class InetLayerBasis
 *
 *  @brief
 *    This is the basis class of reference-counted objects managed by an
 *    InetLayer object.
 *
 */
class InetLayerBasis : public Weave::System::Object
{
public:
    InetLayer& Layer(void) const;
    bool IsCreatedByInetLayer(const InetLayer& aInetLayer) const;

protected:
    void InitInetLayerBasis(InetLayer& aInetLayer, void* aAppState = NULL);

private:
    InetLayer* mInetLayer;  /**< Pointer to the InetLayer object that owns this object. */
};

/**
 *  Returns a reference to the Inet layer object that owns this basis object.
 */
inline InetLayer& InetLayerBasis::Layer(void) const
{
    return *mInetLayer;
}

/**
 *  Returns \c true if the basis object was obtained by the specified INET layer instance.
 *
 *  @param[in]  aInetLayer    An instance of the INET layer.
 *
 *  @return     \c true if owned by \c aInetLayer, otherwise \c false.
 *
 *  @note
 *      Does not check whether the object is actually obtained by the system layer instance associated with the INET layer
 *      instance. It merely tests whether \c aInetLayer is the INET layer instance that was provided to \c InitInetLayerBasis.
 */
inline bool InetLayerBasis::IsCreatedByInetLayer(const InetLayer& aInetLayer) const
{
    return mInetLayer == &aInetLayer;
}

inline void InetLayerBasis::InitInetLayerBasis(InetLayer& aInetLayer, void* aAppState)
{
    AppState = aAppState;
    mInetLayer = &aInetLayer;
}

#if INET_CONFIG_PROVIDE_OBSOLESCENT_INTERFACES
typedef InetLayerBasis InetLayerObject;
#endif // INET_CONFIG_PROVIDE_OBSOLESCENT_INTERFACES

#if WEAVE_SYSTEM_CONFIG_USE_SOCKETS

/**
 *  @class SocketEvents
 *
 *  @brief
 *    Represent a set of I/O events requested/pending on a socket.
 *
 */
class SocketEvents
{
public:
    enum
    {
        kRead    = 0x01,        /**< Bit flag indicating if there is a read event on a socket. */
        kWrite   = 0x02,        /**< Bit flag indicating if there is a write event on a socket. */
        kError   = 0x04,        /**< Bit flag indicating if there is an error event on a socket. */
    };

    int Value;                  /**< Contains the bit flags for the socket event. */

    /**
     *  Constructor for the SocketEvents class.
     *
     */
    SocketEvents()              { Value = 0; }

    /**
     *  Copy constructor for the SocketEvents class.
     *
     */
    SocketEvents(const SocketEvents& other) { Value = other.Value; }

    /**
     *  Check if any of the bit flags for the socket events are set.
     *
     *  @return true if set, otherwise false.
     *
     */
    bool IsSet() const          { return Value != 0; }

    /**
     *  Check if the bit flags indicate that the socket is readable.
     *
     *  @return true if socket is readable, otherwise false.
     *
     */
    bool IsReadable() const     { return (Value & kRead) != 0; }

    /**
     *  Check if the bit flags indicate that the socket is writable.
     *
     *  @return true if socket is writable, otherwise false.
     *
     */
    bool IsWriteable() const    { return (Value & kWrite) != 0; }

    /**
     *  Check if the bit flags indicate that the socket has an error.
     *
     *  @return true if socket has an error, otherwise false.
     *
     */
    bool IsError() const        { return (Value & kError) != 0; }

    /**
     *  Set the read bit flag for the socket.
     *
     */
    void SetRead()              { Value |= kRead; }

    /**
     *  Set the write bit flag for the socket.
     *
     */
    void SetWrite()             { Value |= kWrite; }

    /**
     *  Set the error bit flag for the socket.
     *
     */
    void SetError()             { Value |= kError; }

    /**
     *  Clear the bit flags for the socket.
     *
     */
    void Clear()                { Value = 0; }

    /**
     *  Clear the read bit flag for the socket.
     *
     */
    void ClearRead()            { Value &= ~kRead; }

    /**
     *  Clear the write bit flag for the socket.
     *
     */
    void ClearWrite()           { Value &= ~kWrite; }

    /**
     *  Clear the error bit flag for the socket.
     *
     */
    void ClearError()           { Value &= ~kError; }

    void SetFDs(int socket, int& nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds);
    static SocketEvents FromFDs(int socket, fd_set *readfds, fd_set *writefds, fd_set *exceptfds);
};

/**
 *  @def INET_INVALID_SOCKET_FD
 *
 *  @brief
 *    This is the invalid socket file descriptor identifier.
 */
#define INET_INVALID_SOCKET_FD (-1)

#endif // WEAVE_SYSTEM_CONFIG_USE_SOCKETS

} // namespace Inet
} // namespace nl

#endif // !defined(INETLAYERBASIS_H)
