/*
** 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 ParserDefinitionOTF.hpp
 *
 *  @author Lagrasse Olivier 
 *  @author Johnny Jazeix
 *  @author Mathieu Faverge
 *
 */

#ifndef PARSERDEFINITIONOTF_HPP
#define PARSERDEFINITIONOTF_HPP

class Trace;

/*!
 * \def SET_HANDLER(handler, func_name, data, handler_kind)
 * Set the handler for handler_kind. Uses the function func_name.
 * data corresponds to the first argument of the handler.
 * Used in the two OTF parsers.
 */
#define SET_HANDLER(handler, func_name, data, handler_kind) {            \
        OTF_HandlerArray_setHandler(handler, (OTF_FunctionPointer*) func_name, handler_kind); \
        OTF_HandlerArray_setFirstHandlerArg(handler, data, handler_kind); \
    }

/*!
 * \struct Process
 * \brief Contains the definition of a process (equivalent in Paje : Container)
 */
struct Process {
    /*! \brief Name of the process */
    std::string _name;
    /*! \brief id of the parent process */
    uint32_t _parent;
    /*! \brief stream where is defined this process */
    uint32_t _stream;
};

/*!
 * \struct ProcessGroup
 * \brief Contains the definition of a processGroup (equivalent in Paje : ContainerType)
 */
struct ProcessGroup {
    /*! \brief Name of the processGroup */
    const char *_name;
    /*! \brief Number of process in this group */
    uint32_t _numberOfProcs;
    /*! \brief stream where is defined this process */
    uint32_t _stream;
    /*! \brief ids of the child process */
    uint32_t *_procs;
};

/*!
 * \struct Function
 * \brief Contains the definition of a function (equivalent in Paje : state)
 */
struct Function {
    /*! \brief _name Name of the function*/
    std::string _name;
    /*! \brief stream where is defined this function */
    uint32_t _stream;
    /*! \brief The file id where the function is defined */
    uint32_t _func_group;
    /*! \brief The file id where the function is defined */
    uint32_t _file_source;
    /*! \brief Boolean to know if the corresponding state has been created (useful for event parser) */
    uint32_t _is_defined;
};

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

/*!
 * \struct Counter
 * \brief Contains the definition of a counter (equivalent in Paje : Variable)
 */
struct Counter {
    /*! \brief Name of the counter */
    std::string _name;
    /*! \brief stream where is defined this counter */
    uint32_t _stream;
    /*! \brief Some properties, not used... */
    uint32_t _properties;
    /*! \brief id of the counter group if belongs to one (\see CounterGroup) */
    uint32_t _counter_group;
    /*! \brief The unit of the counter (meters, yard, ...) */
    std::string _unit;
};

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

/*!
 * \struct FileSource
 * \brief Contains the definition of a file source
 */
struct FileSource {
    /*! \brief Name of the file source */
    std::string _name;
    /*! \brief stream where is defined this fileSource */
    uint32_t _stream;
    
};

/*!
 * \struct FileLine
 * \brief Contains the definition of a file source
 */
struct FileLine {
    /*! \brief id of the corresponding file (\see FileSource) */
    uint32_t _file_id;
    /*! \brief line where the function is defined */
    uint32_t _line_number;
    /*! \brief stream where is defined this process */
    uint32_t _stream;
};
/*!
 *
 * \class ParserDefinitionOTF
 * \brief Parse the definitions of the trace and store them.
 *
 */
class ParserDefinitionOTF{
private:

    /*!
     * Maps in order to easily retrieve the events.
     */
    static std::map<uint32_t, Process >       _process;
    static std::map<uint32_t, ProcessGroup >  _process_group;
    static std::map<uint32_t, Function >      _function;
    static std::map<uint32_t, FunctionGroup > _function_group;
    static std::map<uint32_t, Counter >       _counter;
    static std::map<uint32_t, CounterGroup >  _counter_group;
    static std::map<uint32_t, FileSource >    _file_source;
    static std::map<uint32_t, FileLine >      _file_line;

    static uint32_t                           _ticks_per_second;

    /*!
     * Table containing default colors.
     * We take the state id modulo the max number to get the color.
     */
    static std::vector<Color *>        _default_colors;

    OTF_HandlerArray* _handlers;

    static int handler_DefinitionComment( void *, uint32_t, const char *, OTF_KeyValueList *); 
    static int handler_DefTimerResolution(void *, uint32_t, uint32_t, OTF_KeyValueList *); 
    static int handler_DefProcess(        void *, uint32_t, uint32_t, const char *, uint32_t, OTF_KeyValueList *); 
    static int handler_DefProcessGroup(   void *, uint32_t, uint32_t, const char *, uint32_t, const uint32_t *, OTF_KeyValueList *);
    static int handler_DefAttributeList(  void *, uint32_t, uint32_t, uint32_t, OTF_ATTR_TYPE *, OTF_KeyValueList *);
    static int handler_DefProcessOrGroupAttribute(void *, uint32_t, uint32_t, uint32_t, OTF_KeyValueList *);; 
    static int handler_DefFunction(       void *, uint32_t, uint32_t, const char *, uint32_t, uint32_t, OTF_KeyValueList *); 
    static int handler_DefFunctionGroup(  void *, uint32_t, uint32_t, const char *, OTF_KeyValueList *);
    static int handler_DefCollectiveOperation(void *, uint32_t, uint32_t, const char *, uint32_t, OTF_KeyValueList *);
    static int handler_DefCounter(        void *, uint32_t, uint32_t, const char *, uint32_t, uint32_t, const char *, OTF_KeyValueList *);
    static int handler_DefCounterGroup(   void *, uint32_t, uint32_t, const char *, OTF_KeyValueList *);
    static int handler_DefScl(            void *, uint32_t, uint32_t, uint32_t, uint32_t, OTF_KeyValueList *);
    static int handler_DefSclFile(        void *, uint32_t, uint32_t, const char *, OTF_KeyValueList *);
    static int handler_DefCreator(        void *, uint32_t, const char *, OTF_KeyValueList * ); 
    static int handler_DefVersion(        void *, uint32_t, uint8_t, uint8_t, uint8_t, const char *, OTF_KeyValueList * ); 
    static int handler_DefFile(           void *, uint32_t, uint32_t, const char *, uint32_t, OTF_KeyValueList * ); 
    static int handler_DefFileGroup(      void *, uint32_t, uint32_t, const char *, OTF_KeyValueList * ); 
    static int handler_DefKeyValue(       void *, uint32_t, uint32_t, OTF_Type, const char *, const char *, OTF_KeyValueList * ); 

    ParserDefinitionOTF(const ParserDefinitionOTF&);

public:

    /*!
     * \fn ParserDefinitionOTF()
     * \brief constructor
     */
    ParserDefinitionOTF();

    /*!
     * \fn ~ParserDefinitionOTF()
     * \brief destructor
     */
    ~ParserDefinitionOTF();

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

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

    /*!
     * \fn create_container_types(Trace *t)
     * \brief Create all the container types needed for the trace
     * It is run at the end of the definitions parsing.
     * \param t The trace where we store data
     */
    void create_container_types(Trace *t);

    /*!
     * \fn print_definitions()
     * \brief Print all the definitions stored. Useful for debug
     */
    void print_definitions();

    /*!
     * \fn get_function_by_id(const uint32_t id)
     * \brief Accessor for the function map
     * \param id the id we want the corresponding function
     * \return The function associated to id
     */
    static Function &get_function_by_id(const uint32_t id);

    /*!
     * \fn get_counter_by_id(const uint32_t id)
     * \brief Accessor for the counter map
     * \param id the id we want the corresponding counter
     * \return The counter associated to id
     */
    static Counter get_counter_by_id(const uint32_t id);

    /*!
     * \fn get_process_by_id(const uint32_t id)
     * \brief Accessor for the process map
     * \param id the id we want the corresponding process
     * \return The process associated to id
     */
    static Process get_process_by_id(const uint32_t id);

    /*!
     * \fn get_processgroup_by_id(const uint32_t id)
     * \brief Accessor for the processGroup map
     * \param id the id we want the corresponding processGroup
     * \return The ProcessGroup associated to id
     */
    static ProcessGroup get_processgroup_by_id(const uint32_t id);

    /*!
     * \fn get_processgroup_by_process(const unsigned int process_id)
     * \brief Get the first processGroup which contains the process process_id
     * \param process_id the id of the process we want the group
     * \return The ProcessGroup associated to id
     */
    static ProcessGroup get_processgroup_by_process(const unsigned int process_id);

    /*!
     * \fn get_filesource_by_id(const uint32_t id)
     * \brief Accessor for the fileSource map
     * \param id the id we want the corresponding file source
     * \return The FileSource associated to id
     */
    static FileSource get_filesource_by_id(const uint32_t id);

    /*!
     * \fn get_fileline_by_id(const uint32_t id)
     * \brief Accessor for the fileLine map
     * \param id the id we want the corresponding file line
     * \return The FileLine associated to id
     */
    static FileLine get_fileline_by_id(const uint32_t id);

    /*!
     * \fn get_function_group_by_id(const uint32_t id)
     * \brief Accessor for the function_group map
     * \param id the id we want the corresponding functionGroup
     * \return The functionGroup associated to id
     */
    static FunctionGroup get_function_group_by_id(const uint32_t id);

    /*!
     * \fn get_counter_group_by_id(const uint32_t id)
     * \brief Accessor for the counter_group map
     * \param id the id we want the corresponding counterGroup
     * \return The CounterGroup associated to id
     */
    static CounterGroup get_counter_group_by_id(const uint32_t id);

    /*!
     * \fn get_ticks_per_second()
     * \brief Accessor for the tick_per_second (equivalent to a time unit)
     * \return The number of ticks per second
     */
    static uint32_t get_ticks_per_second();

    static Color *get_color(uint32_t func_id);
};

#endif // PARSERDEFINITIONOTF_HPP
