/**
 *
 * @file tests/stubs/Trace.cpp
 *
 * @copyright 2008-2024 Bordeaux INP, CNRS (LaBRI UMR 5800), Inria,
 *                      Univ. Bordeaux. All rights reserved.
 *
 * @author Camille Ordronneau
 * @author Mathieu Faverge
 *
 * @date 2024-07-17
 */
/*!
 *
 * \file Trace.hpp
 * \author  NOISETTE
 * \brief Bouchon
 *
 */
#include "Trace.hpp"

using namespace std;

Trace::Trace() {
}
Trace::~Trace() {
    free_str();
}

string Trace::to_string(const std::map<std::string, Value *> &extra_fields) {
    string *res = new string("option()"); /*
                                           if (extra_fields.size()>0){
                                           *res = "option(" ;
                                           for (unsigned int i=0;i<extra_fields.size();i++)
                                           (*res).append(extra_fields[i]->to_string() + " ");
                                           (*res).append(")");
                                           }
                                           else{
                                           (*res).assign("\0");
                                           }
                                           */
    to_freed.push_back(res);
    return *res;
}

void Trace::free_str() {
    for (unsigned int i = 0; i < to_freed.size(); i++)
        delete to_freed[i];

    if (!to_freed.empty())
        to_freed.clear();
}

void Trace::define_container_type(Name &alias, ContainerType *container_type_parent, const std::map<std::string, Value *> &extra_fields) {
    cout << "define_container_type "
         << alias.to_string()
         << " "
         << *container_type_parent
         << " "
         << to_string(extra_fields)
         << endl;

    free_str();
}

void Trace::create_container(const Date &time, const Name &alias, ContainerType *type, Container *parent, const map<string, Value *> &extra_fields) {
    cout << "create_container "
         << time.to_string()
         << " "
         << alias.to_string()
         << " "
         << *type
         << " "
         << *parent
         << " "
         << to_string(extra_fields)
         << endl;
    free_str();
}

void Trace::destroy_container(const Date &time, Container *cont, ContainerType *type, const map<string, Value *> &extra_fields) {
    cout << "destroy_container "
         << time.to_string()
         << " "
         << *cont
         << " "
         << *type
         << " "
         << to_string(extra_fields)
         << endl;
    free_str();
}

void Trace::define_event_type(const Name &alias, ContainerType *container_type, const map<string, Value *> &extra_fields) {
    cout << "define_event_type "
         << alias.to_string()
         << " "
         << *container_type
         << " "
         << to_string(extra_fields)
         << endl;
    free_str();
}

void Trace::define_state_type(const Name &alias, ContainerType *container_type, const map<string, Value *> &extra_fields) {
    cout << "define_state_type "
         << alias.to_string()
         << " "
         << *container_type
         << " "
         << to_string(extra_fields)
         << endl;
    free_str();
}

void Trace::define_variable_type(const Name &alias, ContainerType *container_type, const map<string, Value *> &extra_fields) {
    cout << "define_variable_type "
         << alias.to_string()
         << " "
         << *container_type
         << " "
         << to_string(extra_fields)
         << endl;
    free_str();
}

void Trace::define_link_type(const Name &alias, ContainerType *ancestor, ContainerType *source, ContainerType *destination, const map<string, Value *> &extra_fields) {
    cout << "define_link_type "
         << alias.to_string()
         << " "
         << *ancestor
         << " "
         << *source
         << " "
         << *destination
         << " "
         << to_string(extra_fields)
         << endl;
    free_str();
}

void Trace::define_entity_value(const Name &alias, EntityType *entity_type, const map<string, Value *> &extra_fields) {
    cout << "define_entity_value "
         << alias.to_string()
         << " "
         << *entity_type
         << " "
         << to_string(extra_fields)
         << endl;
    free_str();
}

void Trace::set_state(const Date &time, StateType *type, Container *container, EntityValue *value, const map<string, Value *> &extra_fields) {
    cout << "set_state "
         << time.to_string()
         << " "
         << *type
         << " "
         << *container
         << " "
         << *value
         << " "
         << to_string(extra_fields)
         << endl;
    free_str();
}

void Trace::push_state(const Date &time, StateType *type, Container *container, EntityValue *value, const map<string, Value *> &extra_fields) {
    cout << "push_state "
         << time.to_string()
         << " "
         << *type
         << " "
         << *container
         << " "
         << *value
         << " "
         << to_string(extra_fields)
         << endl;
    free_str();
}

void Trace::pop_state(const Date &time, StateType *type, Container *container, const map<string, Value *> &extra_fields) {

    cout << "pop_state "
         << time.to_string()
         << " "
         << *type
         << " "
         << *container
         << " "
         << to_string(extra_fields)
         << endl;
    free_str();
}

void Trace::new_event(const Date &time, EventType *type, Container *container, EntityValue *value, const map<string, Value *> &extra_fields) {
    cout << "new_event "
         << time.to_string()
         << " "
         << *type
         << " "
         << *container
         << " "
         << *value
         << " "
         << to_string(extra_fields)
         << endl;
    free_str();
}

void Trace::set_variable(const Date &time, VariableType *type, Container *container, const Double &value, const map<string, Value *> &extra_fields) {

    cout << "set_variable "
         << time.to_string()
         << " "
         << *type
         << " "
         << *container
         << " "
         << value.to_string()
         << " "
         << to_string(extra_fields)
         << endl;
    free_str();
}

void Trace::add_variable(const Date &time, VariableType *type, Container *container, const Double &value, const map<string, Value *> &extra_fields) {

    cout << "add_variable "
         << time.to_string()
         << " "
         << *type
         << " "
         << *container
         << " "
         << value.to_string()
         << " "
         << to_string(extra_fields)
         << endl;
    free_str();
}

void Trace::sub_variable(const Date &time, VariableType *type, Container *container, const Double &value, const map<string, Value *> &extra_fields) {

    cout << "sub_variable "
         << time.to_string()
         << " "
         << *type
         << " "
         << *container
         << " "
         << value.to_string()
         << " "
         << to_string(extra_fields)
         << endl;
    free_str();
}

void Trace::start_link(Date &time, LinkType *type, Container *ancestor, Container *source, EntityValue *value, const String &key, const map<string, Value *> &extra_fields) {

    cout << "start_link "
         << time.to_string()
         << " "
         << *type
         << " "
         << *ancestor
         << " "
         << *source
         << " "
         << *value
         << " "
         << key.to_string()
         << " "
         << to_string(extra_fields)
         << endl;
    free_str();
}

void Trace::end_link(Date &time, LinkType *type, Container *ancestor, Container *destination, EntityValue *value, const String &key, const map<string, Value *> &extra_fields) {

    cout << "end_link "
         << time.to_string()
         << " "
         << *type
         << " "
         << *ancestor
         << " "
         << *destination
         << " "
         << *value
         << " "
         << key.to_string()
         << " "
         << to_string(extra_fields)
         << endl;
    free_str();
}

Container *Trace::search_container_type(const String &name) const {
    string *res = new string((string) "search(" + name.to_string() + ")");
    to_freed.push_back(res);
    return res;
}

Container *Trace::search_container(const String &name) const {
    string *res = new string((string) "search(" + name.to_string() + ")");
    to_freed.push_back(res);
    return res;
}

Container *Trace::search_container(const String &name) const {
    string *res = new string((string) "search(" + name.to_string() + ")");
    to_freed.push_back(res);
    return res;
}

Container *Trace::search_event_type(const String &name) {
    string *res = new string((string) "search(" + name.to_string() + ")");
    to_freed.push_back(res);
    return res;
}

Container *Trace::search_state_type(const String &name) {
    string *res = new string("search(" + name.to_string() + ")");
    to_freed.push_back(res);
    return res;
}

VariableType *Trace::search_variable_type(const String &name) {
    string *res = new string("search(" + name.to_string() + ")");
    to_freed.push_back(res);
    return res;
}

LinkType *Trace::search_link_type(const String &name) {
    string *res = new string((string) "search(" + name.to_string() + ")");
    to_freed.push_back(res);
    return res;
}

EntityValue *Trace::search_entity_value(const String &name, EntityType *entity_type) const {
    string *res = new string((string) "search(" + name.to_string() + ")");
    to_freed.push_back(res);
    return res;
}

EntityType *Trace::search_entity_type(const String &name) const {
    string *res = new string((string) "search(" + name.to_string() + ")");
    to_freed.push_back(res);
    return res;
}

void Trace::finish() {
    cout << "finish" << endl;
}
