/**
 *
 * @file src/core/Core.hpp
 *
 * @copyright 2008-2024 Bordeaux INP, CNRS (LaBRI UMR 5800), Inria,
 *                      Univ. Bordeaux. All rights reserved.
 *
 * @author Camille Ordronneau
 * @author Samuel Thibault
 * @author Johnny Jazeix
 * @author Nolan Bredel
 * @author Mathieu Faverge
 * @author Francois Trahay
 * @author Thibault Soucarre
 * @author Thomas Herault
 * @author Jule Marcoueille
 * @author Olivier Lagrasse
 * @author Augustin Degomme
 *
 * @date 2024-07-17
 */
/*!
 *\file Core.hpp
 */

#ifndef CORE_HPP
#define CORE_HPP

#include "common/common.hpp"

#include "render/Render.hpp"
#include "render/Render_windowed.hpp"

class Core;
class Interface_graphic;
class LogConsole;

class Trace;
class Variable;
class QApplication;
class QCoreApplication;
class QString;
class QMutex;
class Parser;
class QWaitCondition;
class QEventLoop;

#include <QObject>

#ifdef USE_MPI
#include <boost/mpi/environment.hpp>
#include <boost/mpi/communicator.hpp>
#endif
// #include "render/GanttDiagram.hpp"
#include "common/Log.hpp"

/*!
 *\brief This class is an terminal interface, it inherited from the Interface interface.
 */
class Core : public QObject
{
    Q_OBJECT
public:
    /***********************************
     *
     * The command line parameter processing functions.
     *
     **********************************/

    enum STATES {
        // An error state
        _STATE_UNKNOWN,
        // A state which corresponds to display a help text.
        _STATE_DISPLAY_HELP,
        // A state which corresponds to display a the ViTE window and opening a file.
        _STATE_OPEN_FILE,
        // A state which corresponds to an export of file.
        _STATE_EXPORT_FILE,
        // A state which corresponds to display the ViTE window.
        _STATE_LAUNCH_GRAPHICAL_INTERFACE,
        // A state for splitting the file
        _STATE_SPLITTING,
        // A state to display version
        _STATE_VERSION_DISPLAY
    };

    /*!
     * \brief Launch an action according to the argument state value.
     * \param state An integer corresponding to a kind of action which must be executed.
     * \param arg Contains necessary arguments needed for the action to launch.
     *
     * This functions triggers an action of ViTE according to its argument. state can takes some values :
     * <ul><li><b>STATE_DISPLAY_HELP</b> -> this value means that the console interface must be displayed
     * in the terminal the help text, then wait until user specify another command.</li>
     * <li><b>STATE_LAUNCH_GRAPHICAL_INTERFACE</b> -> this value means that the console interface will let
     * user to use the graphical interface: in that case, ViTE displays the window and all
     * of the warning or error messages will be displayed in dialog boxes.</li>
     * </ul>
     */
    void launch_action(int state, void *arg = nullptr);

    QEventLoop *waitGUIInit;

protected:
    /***********************************
     *
     * Window interface instance.
     *
     **********************************/

    /*!
     * \brief Contains the instance of the window class.
     */
    Interface_graphic *_main_window;

    /*!
     * \brief
     */
    LogConsole *_log_console;

#ifdef USE_MPI
    boost::mpi::communicator _world;
#endif

    /*!
     * \brief Contains the main Qt application instance.
     */
    QApplication *graphic_app;

    /*!
     * \brief Contains the main Qt if no interface is loaded
     */
    QCoreApplication *console_app;

    /*!
     *\brief This attributes contains the launching current directory (_run_env[0]) and the first argument of the running command (_run_env[1]).
     */
    QString *_run_env[2];

    /*!
     *\brief If a file must be opened, this attribute contains its path.
     */
    std::string _file_to_open;

    /*!
     *\brief If a container's config file has to be opened, this attribute contains its path.
     */
    std::string _xml_config_file;

    /*!
     *\brief If a file must be exported, this attribute contains its path.
     */
    std::string _path_to_export;

    /*!
     *\brief The time where we start to watch the trace.
     */
    double _time_start;

    /*!
     *\brief The time where we stop to watch the trace.
     */
    double _time_end;

    /*!
     * \brief Return the state of ViTE according to the arguments.
     * \param argc The number of parameters given when the program was called.
     * \param argv A set of strings which contains each parameter.
     * \return An integer corresponding to a command which will be processed by ViTE.
     */
    int get_options(int &argc, char **argv);

    /*!
     * \brief Displays in the terminal the help text.
     */
    void display_help();

public:
    /***********************************
     *
     * Constructor and destructor.
     *
     **********************************/

    /*!
     * \brief The default constructor of the class.
     * \param argc The number of parameters given when the program was called.
     * \param argv A set of strings which contains each parameter.
     */
    Core(int &argc, char **argv);

    /*!
     * \brief The destructor.
     */
    ~Core() override;

    /***********************************
     *
     * Running function.
     *
     **********************************/

    /*!
     * \brief This function launch trace drawing.
     * \param trace Trace to draw
     */
    void draw_trace(Trace *trace);

    /*!
     * \brief Build a trace from a file
     * \param filename Name of the file from which to build the trace
     */
    Trace *build_trace(const std::string &filename, bool is_state_splitting = false);

    /*!
     * \brief This function launch Qt event loop.
     */
    int run();

    /*!
     * \brief Get the _run_env matrix.
     *
     */
    const QString **get_runenv() const;

    void load_data(Trace *trace);

    /***********************************
     *
     * Informative message functions.
     *
     **********************************/

    /*!
     *\brief Set the minimum for export
     *\param d The double.
     */
    void set_min_value_for_export(const double d);

    /*!
     *\brief Set the minimum for export
     *\param d The double.
     */
    void set_max_value_for_export(const double d);

    /*!
     *\brief Export a counter
     * Need to choose a counter, and a filename
     */
    void export_variable(Variable *var, const std::string &filename);

    /*!
     * \brief Export a trace to a svg file
     * \param trace The trace to export
     * \param path_to_export The path corresponding to the output svg path
     */
    void export_trace_to_svg(Trace *trace, const std::string &path_to_export);

    /*!
     * \brief Change the color corresponding to an EntityValue
     */
    void change_entity_color(std::string entity, Element_col r, Element_col g, Element_col b);

    void change_event_color(std::string event, Element_col r, Element_col g, Element_col b);

    void change_link_color(std::string link, Element_col r, Element_col g, Element_col b);

    void change_entity_visible(std::string entity, bool visible);

    void change_event_visible(std::string event, bool visible);

    void change_link_visible(std::string link, bool visible);

    /*!
     * \brief reload state color from trace file
     */
    void reload_states();

    void reload_links();

    void reload_events();

public
    Q_SLOT :
        /*!
         * \brief Write the percentage of parsing done in the console and update progress bar
         */
        void
        update_parsing_progress(const int time_elapsed, const float percent_loaded);

    // Qt signals fo the Parsing Thread
Q_SIGNALS:

    /*!
     *\brief run_parsing()
     * signal to launch the parsing
     */
    void run_parsing();

    /*!
     *\brief dump())
     * signal to dump last IntervalOfContainers and wait for the end of event loop
     */
    void dump(std::string, std::string);

    void quit_app();
};

#endif
