/**
 *
 * @file src/trace/TraceBuilderThread.hpp
 *
 * @copyright 2008-2024 Bordeaux INP, CNRS (LaBRI UMR 5800), Inria,
 *                      Univ. Bordeaux. All rights reserved.
 *
 * @author Camille Ordronneau
 * @author Johnny Jazeix
 * @author Mathieu Faverge
 * @author Thibault Soucarre
 * @author Augustin Degomme
 *
 * @date 2024-07-17
 */
#ifndef TRACEBUILDER_HPP
#define TRACEBUILDER_HPP
#include <iostream>
#include <string>
#include <queue>
#include <map>

#include <QWaitCondition>
#include <QSemaphore>
#include <QObject>
#include <QMutex>
#include <QThread>
/* -- */

#include "trace/values/Values.hpp"
#include "trace/EntityValue.hpp"
#include "trace/EntityTypes.hpp"
#include "trace/Entitys.hpp"
#include "trace/Trace.hpp"
#include "trace/tree/Node.hpp"
#include "trace/tree/BinaryTree.hpp"
/* -- */
#include "common/common.hpp"
#include "common/Info.hpp" /* Dirty, should be remove */
#include "common/Message.hpp"
#include "common/Errors.hpp"
/* -- */
#include "trace/tree/Interval.hpp"

#include "parser/Parser.hpp"

typedef std::map<const String, Container *, String::less_than> Container_map;
/*
typedef struct Test_struct{
    int _id;
}Test_struct;*/

typedef struct Trace_builder_struct
{
    int _id;
    // void (*func)(void* tb,Date, Name alias, String container_type,String, String, String, String, std::map<std::string, Value *> *extra_fields);
    void (*func)(Trace_builder_struct *);
    Date time;
    Name alias;
    String type;
    String start_container_type;
    String end_container_type;
    String container;
    String value_string;
    Double value_double;
    String start_container;
    String end_container;
    String key;
    std::map<std::string, Value *> extra_fields;
    // std::map<std::string, Value *> *extra_fields;
    Trace *_trace;
    Parser *_parser;
    Container_map *_containers;
    Trace_builder_struct() { /*extra_fields=NULL;*/
    }

} Trace_builder_struct;

class TraceBuilderThread : public QObject
{
    Q_OBJECT

private:
    QWaitCondition *_cond;
    bool _is_finished;
    QSemaphore *_freeSlots;
    QMutex *_mutex;

public:
    TraceBuilderThread(QWaitCondition *cond, QSemaphore *freeSlots, QMutex *mutex);
    static void define_container_type(Trace_builder_struct *tb_struct);
    static void create_container(Trace_builder_struct *tb_struct);
    static void destroy_container(Trace_builder_struct *tb_struct);
    static void define_event_type(Trace_builder_struct *tb_struct);
    static void define_state_type(Trace_builder_struct *tb_struct);
    static void define_variable_type(Trace_builder_struct *tb_struct);
    static void define_link_type(Trace_builder_struct *tb_struct);
    static void define_entity_value(Trace_builder_struct *tb_struct);
    static void set_state(Trace_builder_struct *tb_struct);
    static void push_state(Trace_builder_struct *tb_struct);
    static void pop_state(Trace_builder_struct *tb_struct);
    static void new_event(Trace_builder_struct *tb_struct);
    static void set_variable(Trace_builder_struct *tb_struct);
    static void add_variable(Trace_builder_struct *tb_struct);
    static void sub_variable(Trace_builder_struct *tb_struct);
    static void start_link(Trace_builder_struct *tb_struct);
    static void end_link(Trace_builder_struct *tb_struct);

public Q_SLOTS:
    void build_trace(int n, Trace_builder_struct *tb_struct);
    void build_finished();
    bool is_finished();
};

#endif
