/**
 *
 * @file src/parser/OTF2Parser/ParserOTF2.cpp
 *
 * @copyright 2008-2024 Bordeaux INP, CNRS (LaBRI UMR 5800), Inria,
 *                      Univ. Bordeaux. All rights reserved.
 *
 * @author Camille Ordronneau
 * @author Francois Trahay
 * @author Johnny Jazeix
 *
 * @date 2024-07-17
 */
/**
 *  @file ParserOTF2.cpp
 *
 *  @author Lagrasse Olivier
 *  @author Johnny Jazeix
 *  @author Mathieu Faverge
 *
 */

#include <iostream>
#include <fstream>
#include <string>
#include <map>
#include <list>
/* -- */
#include <otf2/otf2.h>
/* -- */
#include "trace/values/Values.hpp"
#include "trace/EntityTypes.hpp"
#include "trace/Entitys.hpp"
#include "trace/Trace.hpp"
/* -- */
#include "parser/Parser.hpp"
#include "parser/OTF2Parser/ParserOTF2.hpp"
#include "parser/OTF2Parser/ParserDefinitionOTF2.hpp"
#include "parser/OTF2Parser/ParserEventOTF2.hpp"
/* -- */

using namespace std;

#define VITE_OTF_2_MAXFILES_OPEN 100

#define VITE_ERR_OTF_2_OPENREADER "Failed to create the OTF2 Reader\n"

ParserOTF2::ParserOTF2() { }
ParserOTF2::ParserOTF2(const string &filename) :
    Parser(filename) { }
ParserOTF2::~ParserOTF2() { }

void ParserOTF2::parse(Trace &trace,
                       bool finish_trace_after_parse) {

    ParserDefinitionOTF2 *parserdefinition;
    ParserEventOTF2 *parserevent;
    OTF2_Reader *reader;
    string filename = get_next_file_to_parse();

    reader = OTF2_Reader_Open(filename.c_str());
    if (reader == NULL) {
        cerr << QObject::tr(VITE_ERR_OTF_2_OPENREADER).toStdString() << endl;
        finish();

        if (finish_trace_after_parse) { // true by default
            trace.finish();
        }
        return;
    }

    parserdefinition = new ParserDefinitionOTF2(reader);
    parserdefinition->set_handlers(&trace);
    parserdefinition->read_definitions(reader);
    parserdefinition->create_container_types(&trace);
    parserdefinition->initialize_types(&trace);

#if DEBUG
    parserdefinition->print_definitions();
#endif // DEBUG

    parserevent = new ParserEventOTF2(reader);
    parserevent->set_handlers(reader, &trace);

    parserevent->read_events(reader);

    // parserevent->read_markers(reader);

    finish();

    if (finish_trace_after_parse) { // true by default
        trace.finish();
    }

    delete parserevent;
    delete parserdefinition;

    OTF2_Reader_Close(reader);
}

float ParserOTF2::get_percent_loaded() const {
    // return ParserEventOTF::get_percent_loaded();
    return 1;
}
