#pragma once

#include <chrono>
#include <exception>
#include <list>
#include <memory>
#include <string>
#include <vector>

#include "auth_algo.hpp"
#include "crypt_algo.hpp"
#include "integrity_algo.hpp"
#include "endian.hpp"
#include "socket_channel.hpp"

namespace session
{

using namespace std::chrono_literals;
using SessionID = uint32_t;

enum class Privilege : uint8_t
{
    HIGHEST_MATCHING,
    CALLBACK,
    USER,
    OPERATOR,
    ADMIN,
    OEM,
};

enum class State
{
    INACTIVE,             // Session is not in use
    SETUP_IN_PROGRESS,    // Session Setup Sequence is progressing
    ACTIVE,               // Session is active
    TEAR_DOWN_IN_PROGRESS,// When Closing Session
};

// Seconds of inactivity allowed during session setup stage
constexpr auto SESSION_SETUP_TIMEOUT = 5s;
// Seconds of inactivity allowed when session is active
constexpr auto SESSION_INACTIVITY_TIMEOUT = 60s;

/**
 * @struct SequenceNumbers Session Sequence Numbers
 *
 * IPMI v2.0 RMCP+ Session Sequence Numbers are used for rejecting packets that
 * may have been duplicated by the network or intentionally replayed. There are
 * two sets of Session SequenceNumbers for a given session.One set of inbound
 * and outbound sequence numbers is used for authenticated (signed) packets,
 * and the other set is used for unauthenticated packets.
 *
 * The individual Session Sequence Numbers is are initialized to zero whenever
 * a session is created and incremented by one at the start of outbound
 * processing for a given packet (i.e. the first transmitted packet has a ‘1’
 * as the sequence number, not 0). Session Sequence numbers are incremented for
 * every packet that is transmitted by a given sender, regardless of whether
 * the payload for the packet is a ‘retry’ or not.
 */
struct SequenceNumbers
{
        auto get(bool inbound = true) const
        {
            return inbound ? in : out;
        }

        void set(uint32_t seqNumber, bool inbound = true)
        {
            inbound ? (in = seqNumber) : (out = seqNumber);
        }

        auto increment()
        {
            return ++out;
        }

    private:
        uint32_t in = 0;
        uint32_t out = 0;
};
/**
 * @class Session
 *
 * Encapsulates the data related to an IPMI Session
 *
 * Authenticated IPMI communication to the BMC is accomplished by establishing
 * a session. Once established, a session is identified by a Session ID. The
 * Session ID may be thought of as a handle that identifies a connection between
 * a given remote user and the BMC. The specification supports having multiple
 * active sessions established with the BMC. It is recommended that a BMC
 * implementation support at least four simultaneous sessions
 */
class Session
{
    public:

        Session() = default;
        ~Session() = default;
        Session(const Session&) = delete;
        Session& operator=(const Session&) = delete;
        Session(Session&&) = default;
        Session& operator=(Session&&) = default;

        /**
         * @brief Session Constructor
         *
         * This is issued by the Session Manager when a session is started for
         * the Open SessionRequest command
         *
         * @param[in] inRemoteConsoleSessID - Remote Console Session ID
         * @param[in] priv - Privilege Level requested in the Command
         */
        Session(SessionID inRemoteConsoleSessID, Privilege priv):
            curPrivLevel(priv),
            bmcSessionID(std::rand()),
            remoteConsoleSessionID(inRemoteConsoleSessID) {}

        auto getBMCSessionID() const
        {
            return bmcSessionID;
        }

        auto getRCSessionID() const
        {
            return remoteConsoleSessionID;
        }

        auto getAuthAlgo() const
        {
            if(authAlgoInterface)
            {
                return authAlgoInterface.get();
            }
            else
            {
                throw std::runtime_error("Authentication Algorithm Empty");
            }
        }

        void setAuthAlgo(std::unique_ptr<cipher::rakp_auth::Interface>&&
                         inAuthAlgo)
        {
            authAlgoInterface = std::move(inAuthAlgo);
        }

        /**
         * @brief Get Session's Integrity Algorithm
         *
         * @return pointer to the integrity algorithm
         */
        auto getIntegrityAlgo() const
        {
            if(integrityAlgoInterface)
            {
                return integrityAlgoInterface.get();
            }
            else
            {
                throw std::runtime_error("Integrity Algorithm Empty");
            }
        }

        /**
         * @brief Set Session's Integrity Algorithm
         *
         * @param[in] integrityAlgo - unique pointer to integrity algorithm
         *                              instance
         */
        void setIntegrityAlgo(
                std::unique_ptr<cipher::integrity::Interface>&& integrityAlgo)
        {
            integrityAlgoInterface = std::move(integrityAlgo);
        }

        /** @brief Check if integrity algorithm is enabled for this session.
         *
         *  @return true if integrity algorithm is enabled else false.
         */
        auto isIntegrityAlgoEnabled()
        {
            return integrityAlgoInterface ? true : false;
        }

        /**
         * @brief Get Session's Confidentiality Algorithm
         *
         * @return pointer to the confidentiality algorithm
         */
        auto getCryptAlgo() const
        {
            if(cryptAlgoInterface)
            {
                return cryptAlgoInterface.get();
            }
            else
            {
                throw std::runtime_error("Confidentiality Algorithm Empty");
            }
        }

        /**
         * @brief Set Session's Confidentiality Algorithm
         *
         * @param[in] confAlgo - unique pointer to confidentiality algorithm
         *                       instance
         */
        void setCryptAlgo(
                std::unique_ptr<cipher::crypt::Interface>&& cryptAlgo)
        {
            cryptAlgoInterface = std::move(cryptAlgo);
        }

        /** @brief Check if confidentiality algorithm is enabled for this
         *         session.
         *
         *  @return true if confidentiality algorithm is enabled else false.
         */
        auto isCryptAlgoEnabled()
        {
            return cryptAlgoInterface ? true : false;
        }

        void updateLastTransactionTime()
        {
            lastTime = std::chrono::steady_clock::now();
        }

        /**
         * @brief Session Active Status
         *
         * Session Active status is decided upon the Session State and the last
         * transaction time is compared against the session inactivity timeout.
         *
         */
        bool isSessionActive();

        /**
         * @brief Session's Current Privilege Level
         */
        Privilege curPrivLevel;

        /**
         * @brief Session's Maximum Privilege Level
         */
        Privilege maxPrivLevel = Privilege::CALLBACK;

        SequenceNumbers sequenceNums; // Session Sequence Numbers
        State state = State::INACTIVE; // Session State
        std::vector<char> userName; // User Name

        /** @brief Socket channel for communicating with the remote client.*/
        std::shared_ptr<udpsocket::Channel> channelPtr;

    private:

        SessionID bmcSessionID = 0; //BMC Session ID
        SessionID remoteConsoleSessionID = 0; //Remote Console Session ID

        // Authentication Algorithm Interface for the Session
        std::unique_ptr<cipher::rakp_auth::Interface> authAlgoInterface;

        // Integrity Algorithm Interface for the Session
        std::unique_ptr<cipher::integrity::Interface> integrityAlgoInterface =
                nullptr;

        // Confidentiality Algorithm Interface for the Session
        std::unique_ptr<cipher::crypt::Interface> cryptAlgoInterface =
                nullptr;

        // Last Transaction Time
        decltype(std::chrono::steady_clock::now()) lastTime;
};

} // namespace session
