#pragma once

#include "session.hpp"

#include <boost/asio/steady_timer.hpp>
#include <chrono>
#include <ipmid/api.hpp>
#include <ipmid/sessiondef.hpp>
#include <map>
#include <memory>
#include <mutex>
#include <string>

namespace session
{

enum class RetrieveOption
{
    BMC_SESSION_ID,
    RC_SESSION_ID,
};

static constexpr size_t maxSessionHandles = multiIntfaceSessionHandleMask;

/**
 * @class Manager
 *
 * Manager class acts a manager for the IPMI sessions and provides interfaces
 * to start a session, stop a session and get reference to the session objects.
 *
 */

class Manager
{
  public:
    // BMC Session ID is the key for the map
    using SessionMap = std::map<SessionID, std::shared_ptr<Session>>;

    Manager() = delete;
    explicit Manager(std::shared_ptr<boost::asio::io_context>& io) :
        io(io), timer(*io){};
    ~Manager() = default;
    Manager(const Manager&) = delete;
    Manager& operator=(const Manager&) = delete;
    Manager(Manager&&) = default;
    Manager& operator=(Manager&&) = default;

    /**
     * @brief Start an IPMI session
     *
     * @param[in] remoteConsoleSessID - Remote Console Session ID mentioned
     *            in the Open SessionRequest Command
     * @param[in] priv - Privilege level requested
     * @param[in] authAlgo - Authentication Algorithm
     * @param[in] intAlgo - Integrity Algorithm
     * @param[in] cryptAlgo - Confidentiality Algorithm
     *
     * @return session handle on success and nullptr on failure
     *
     */
    std::shared_ptr<Session>
        startSession(SessionID remoteConsoleSessID, Privilege priv,
                     cipher::rakp_auth::Algorithms authAlgo,
                     cipher::integrity::Algorithms intAlgo,
                     cipher::crypt::Algorithms cryptAlgo);

    /**
     * @brief Stop IPMI Session
     *
     * @param[in] bmcSessionID - BMC Session ID
     *
     * @return true on success and failure if session ID is invalid
     *
     */
    bool stopSession(SessionID bmcSessionID);

    /**
     * @brief Get Session Handle
     *
     * @param[in] sessionID - Session ID
     * @param[in] option - Select between BMC Session ID and Remote Console
     *            Session ID, Default option is BMC Session ID
     *
     * @return session handle on success and nullptr on failure
     *
     */
    std::shared_ptr<Session>
        getSession(SessionID sessionID,
                   RetrieveOption option = RetrieveOption::BMC_SESSION_ID);
    uint8_t getActiveSessionCount() const;
    uint8_t getSessionHandle(SessionID bmcSessionID) const;
    uint8_t storeSessionHandle(SessionID bmcSessionID);
    uint32_t getSessionIDbyHandle(uint8_t sessionHandle) const;

    void managerInit(const std::string& channel);

    uint8_t getNetworkInstance(void);

    /**
     * @brief Clean Session Stale Entries
     *
     *  Schedules cleaning the inactive sessions entries from the Session Map
     */
    void scheduleSessionCleaner(const std::chrono::microseconds& grace);

  private:
    /**
     * @brief reclaim system resources by limiting idle sessions
     *
     * Limits on active, authenticated sessions are calculated independently
     * from in-setup sessions, which are not required to be authenticated. This
     * will prevent would-be DoS attacks by calling a bunch of Open Session
     * requests to fill up all available sessions. Too many active sessions will
     * trigger a shorter timeout, but is unaffected by setup session counts.
     *
     * For active sessions, grace time is inversely proportional to (the number
     * of active sessions beyond max sessions per channel)^3
     *
     * For sessions in setup, grace time is inversely proportional to (the
     * number of total sessions beyond max sessions per channel)^3, with a max
     * of 3 seconds
     */
    void cleanStaleEntries();

    std::shared_ptr<boost::asio::io_context> io;
    boost::asio::steady_timer timer;

    std::array<uint32_t, session::maxSessionHandles> sessionHandleMap = {0};

    /**
     * @brief Session Manager keeps the session objects as a sorted
     *        associative container with Session ID as the unique key
     */
    SessionMap sessionsMap;
    std::unique_ptr<sdbusplus::server::manager::manager> objManager = nullptr;
    std::string chName{}; // Channel Name
    uint8_t ipmiNetworkInstance;
    void setNetworkInstance(void);
};

} // namespace session
