/*
** This file is part of the ViTE project.
**
** This software is governed by the CeCILL-A license under French law
** and abiding by the rules of distribution of free software. You can
** use, modify and/or redistribute the software under the terms of the
** CeCILL-A license as circulated by CEA, CNRS and INRIA at the following
** URL: "http://www.cecill.info".
** 
** As a counterpart to the access to the source code and rights to copy,
** modify and redistribute granted by the license, users are provided
** only with a limited warranty and the software's author, the holder of
** the economic rights, and the successive licensors have only limited
** liability.
** 
** In this respect, the user's attention is drawn to the risks associated
** with loading, using, modifying and/or developing or reproducing the
** software by the user in light of its specific status of free software,
** that may mean that it is complicated to manipulate, and that also
** therefore means that it is reserved for developers and experienced
** professionals having in-depth computer knowledge. Users are therefore
** encouraged to load and test the software's suitability as regards
** their requirements in conditions enabling the security of their
** systems and/or data to be ensured and, more generally, to use and
** operate it in the same conditions as regards security.
** 
** The fact that you are presently reading this means that you have had
** knowledge of the CeCILL-A license and that you accept its terms.
**
**
** ViTE developers are (for version 0.* to 1.0):
**
**        - COULOMB Kevin
**        - FAVERGE Mathieu
**        - JAZEIX Johnny
**        - LAGRASSE Olivier
**        - MARCOUEILLE Jule
**        - NOISETTE Pascal
**        - REDONDY Arthur
**        - VUCHENER Clément 
**
*/
/**
 *  @file ParserEventOTF.hpp
 *
 *  @brief This file contains the event parser used by the ParserOTF.
 * 
 *  @author Lagrasse Olivier 
 *  @author Johnny Jazeix
 *  @author Mathieu Faverge
 *
 */
#ifndef PARSEREVENTOTF_HPP
#define PARSEREVENTOTF_HPP

class Trace;
class ParserDefinitionOTF;

/*!
 * \struct Marker
 * \brief Contains the definition of a marker
 */
struct Marker {
    /*!
     * \brief Name of the marker
     */
    std::string _name;
    /*!
     * \brief stream where is defined this marker
     */
    uint32_t _stream;
    /*!
     * \brief type of the marker
     */
    uint32_t _type;
};


/**
 * \class ParserEventOTF
 * \brief Reads Use handlers in order to fill the data structure
 *
 */

class ParserEventOTF{
private:
    OTF_HandlerArray* _handlers;

    static std::map <const String, Container *, String::less_than> _containers;

    static uint64_t _cur_time;
    static uint64_t _min_time;
    static uint64_t _max_time;

    static std::map<uint32_t, Marker > _marker;

    // Handlers for OTF event records
    static int handler_NoOp( void*, uint64_t, uint32_t, OTF_KeyValueList * );
    static int handler_Enter( void*, uint64_t, uint32_t, uint32_t, uint32_t, OTF_KeyValueList * );
    static int handler_Leave( void*, uint64_t, uint32_t, uint32_t, uint32_t, OTF_KeyValueList * );
    static int handler_SendMsg( void*, uint64_t, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t, OTF_KeyValueList * );
    static int handler_RecvMsg( void*, uint64_t, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t, OTF_KeyValueList * );
    static int handler_Counter( void*, uint64_t, uint32_t, uint32_t, uint64_t, OTF_KeyValueList * );
    static int handler_CollectiveOperation( void*, uint64_t, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t, uint64_t, uint32_t, OTF_KeyValueList * );
    static int handler_BeginCollectiveOperation( void*, uint64_t, uint32_t, uint32_t, uint64_t, uint32_t, uint32_t, uint64_t, uint64_t, uint32_t, OTF_KeyValueList * );
    static int handler_EndCollectiveOperation( void*, uint64_t, uint32_t, uint64_t, OTF_KeyValueList * );
    static int handler_EventComment( void*, uint64_t, uint32_t, const char*, OTF_KeyValueList * );
    static int handler_BeginProcess( void*, uint64_t, uint32_t, OTF_KeyValueList * );
    static int handler_EndProcess( void*, uint64_t, uint32_t, OTF_KeyValueList * );
    static int handler_FileOperation( void*, uint64_t, uint32_t, uint32_t, uint64_t, uint32_t, uint64_t, uint64_t, uint32_t, OTF_KeyValueList * );
    static int handler_BeginFileOperation( void*, uint64_t, uint32_t, uint64_t, uint32_t, OTF_KeyValueList * );
    static int handler_EndFileOperation( void*, uint64_t, uint32_t, uint32_t, uint64_t, uint64_t, uint32_t, uint64_t, uint32_t, OTF_KeyValueList * );
    static int handler_RMAPut( void*, uint64_t, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t, uint64_t, uint32_t, OTF_KeyValueList * );
    static int handler_RMAPutRemoteEnd( void*, uint64_t, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t, uint64_t, uint32_t, OTF_KeyValueList * );
    static int handler_RMAGet( void*, uint64_t, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t, uint64_t, uint32_t, OTF_KeyValueList * );
    static int handler_RMAEnd( void*, uint64_t, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t, OTF_KeyValueList * );

    // Handlers for OTF marker records
    static int handler_DefMarker(void *, uint32_t, uint32_t, const char *, uint32_t, OTF_KeyValueList * );
    static int handler_Marker(void *, uint64_t, uint32_t, uint32_t, const char *, OTF_KeyValueList * );

    ParserEventOTF(const ParserEventOTF &);
public:
    /*!
     * \fn ParserEventOTF()
     * \brief constructor
     */
    ParserEventOTF();

    /*!
     * \fn ~ParserEventOTF()
     * \brief constructor
     */
    ~ParserEventOTF();

    /*!
     * \fn set_handlers(Trace *t)
     * \brief Create and set the handlers for the event parsing.
     * \param t The trace we want to store in.
     */
    void set_handlers(Trace *t);

    /*!
     * \fn read_events(OTF_Reader *reader)
     * \brief Begin the reading of the events
     * \param reader The main otf file we want to read in.
     */
    int read_events(OTF_Reader *reader);

    /*!
     * \fn read_markers(OTF_Reader *reader)
     * \brief Begin the reading of the markers (corresponds to events in Paje)
     * \param reader The main otf file we want to read in.
     */
    void read_markers(OTF_Reader *reader);

    /*!
     * \fn set_number_event_read_by_each_pass(OTF_Reader *reader, int number);
     * \brief set the number of event we want to read by pass.
     * Allow us to do a prevision for the remaining time.
     * \param reader The main otf file we want to read in.
     * \param number The number of events read.
     */
    void set_number_event_read_by_each_pass(OTF_Reader *reader, int number);

    /*!
     * \fn get_percent_loaded()
     * \brief get the size already parsed.
     * It is an approximation, we consider that parsing the definitions is done in a constant time.
     * \return the scale of the size already parsed. (between 0 and 1)
     */
    static float get_percent_loaded();

};
#endif // PARSEREVENTOTF_HPP
