#ifndef VOXELVERSE_SESSION_HPP_
#define VOXELVERSE_SESSION_HPP_

#include <chrono>
#include <memory>
#include <vector>
#include <string>
#include <iostream>

/**
 * @brief Base class for voxelverse session implementations.
 *
 * A session is a single execution of the game. There are two session types:
 * server and client. This is the base class for both.
 *
 * A frontend is expected to initialize a session. This is done by setting the
 * global variable `voxelverse` to an instance of a session, and then calling the
 * `start()` method, for example to create a client:
 *
 * ```
 * voxelverse = std::make_unique<VoxelverseClient>();
 * voxelverse->start(argc, argv);
 * ```
 */
class VoxelverseSession
{
protected:
    std::vector<std::string> args;

    /**
     * @brief Run the main part of the session and return the exit code.
     */
    virtual int run() = 0;

public:
    std::chrono::time_point<std::chrono::steady_clock> startTime;

    virtual ~VoxelverseSession() = default;

    /**
     * @brief Start the session, passing command-line arguments.
     */
    int start(int argc, char **argv);

    /**
     * @brief Return the name of the session type (e.g. "server").
     */
    virtual std::string getSessionTypeName() = 0;
};

#ifdef _MSC_VER
#   ifdef BUILDING_ENGINE
#       define GLOBAL_VAR extern __declspec(dllexport)
#   else
#       define GLOBAL_VAR __declspec(dllimport)
#   endif
#else
#   define GLOBAL_VAR extern
#endif

GLOBAL_VAR std::unique_ptr<VoxelverseSession> voxelverse;

#undef GLOBAL_VAR

#endif