#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

    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
