/*
** 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 developpers are (for version 0.* to 1.0):
**
**        - COULOMB Kevin
**        - FAVERGE Mathieu
**        - JAZEIX Johnny
**        - LAGRASSE Olivier
**        - MARCOUEILLE Jule
**        - NOISETTE Pascal
**        - REDONDY Arthur
**        - VUCHENER Clément 
**
*/
#ifndef ERRORS_HPP
#define ERRORS_HPP

/** 
 * This file contains all the significations of the errors or warnings that can be thrown by the parser 
 *
 **/

#include <string>
#include <queue>
#include <iostream>
#include <fstream>

/*! \class Error
 *  \brief Define errors and warnings used in the parser.
 */
class Error{
private:
    Error();
    static int _line_error;

    static std::queue<std::string> _errors;
    static std::queue<std::string> _warnings;
    static std::string _content;

public:

    /*
     * Priorities of errors
     */
    /*!
     * \brief Define the priority _ERROR.
     */
    const static int _EVERYTHING;

    /*!
     * \brief Define the priority _WARNING.
     */
    const static int _WARNING;


    /*!
     * \brief Define the priority _ERROR.
     */
    const static int _ERROR;

    /*
     * Kind of errors known
     */
    /*!
     * \brief Define the error when expected the character " (before the end of the file).
     */
    const static std::string _PARSE;
    /*!
     * \brief Define the error when the mmap function fails.
     */
    const static std::string _MMAP;
    /*!
     * \brief Define the error when the file is empty.
     */
    const static std::string _EMPTY_FILE;
    /*!
     * \brief Define the error when the fstat function fails.
     */
    const static std::string _FSTAT;
    /*!
     * \brief Define the error when the open function fails.
     */
    const static std::string _OPEN;
    /*!
     * \brief Define the error when the munmap function fails.
     */
    const static std::string _MUNMAP;
    /*!
     * \brief Define the error when missing the end of a definition.
     */
    const static std::string _EXPECT_END_DEF;
    /*!
     * \brief Define the error when missing the beginning of a definition.
     */
    const static std::string _EXPECT_EVENT_DEF;
    /*!
     * \brief Define the error when missing the name of a definition.
     */
    const static std::string _EXPECT_NAME_DEF;
    /*!
     * \brief Define the error when missing the identity of a definition.
     */
    const static std::string _EXPECT_ID_DEF;
    /*!
     * \brief Define the error when the identity of a definition doesn't match with any definition defined.
     */
    const static std::string _UNKNOWN_ID_DEF;
    /*!
     * \brief Define the error when some extra tokens are ignored at the end of a line.
     */
    const static std::string _EXTRA_TOKEN;
    /*!
     * \brief Define the error when an event doesn't match with the event with the same name know by the parser.
     */
    const static std::string _UNKNOWN_EVENT_DEF;
    /*!
     * \brief Define the error when missing the type of a field in a definition.
     */
    const static std::string _FIELD_TYPE_MISSING;
    /*!
     * \brief Define the error when the type of a field in not recognized by the parser.
     */
    const static std::string _FIELD_TYPE_UNKNOWN;
    /*!
     * \brief Define the error when a definition has no field.
     */
    const static std::string _EMPTY_DEF;
    /*!
     * \brief Define the error when a value don't match with its type.
     */
    const static std::string _INCOMPATIBLE_VALUE_IN_EVENT;
    /*!
     * \brief Define the error when the file which has to be parse doesn't have the right extension.
     */
    const static std::string _BAD_FILE_EXTENSION;
    /*!
     * \brief Define the error when some field values are missing for an event.
     */
    const static std::string _LINE_TOO_SHORT_EVENT;

    //////
    /// Errors from undefined entities
    //////

    /*!
     * \brief Define the error when a container type does not exist.
     */
    const static std::string _UNKNOWN_CONTAINER_TYPE;
    /*!
     * \brief Define the error when a containere does not exist.
     */
    const static std::string _UNKNOWN_CONTAINER;
    /*!
     * \brief Define the error when an event type does not exist.
     */
    const static std::string _UNKNOWN_EVENT_TYPE;
    /*!
     * \brief Define the error when a state type does not exist.
     */
    const static std::string _UNKNOWN_STATE_TYPE;
    /*!
     * \brief Define the error when a variable type does not exist.
     */
    const static std::string _UNKNOWN_VARIABLE_TYPE;
    /*!
     * \brief Define the error when a link type does not exist.
     */
    const static std::string _UNKNOWN_LINK_TYPE;
    /*!
     * \brief Define the error when a entity type does not exist.
     */
    const static std::string _UNKNOWN_ENTITY_TYPE;





    /*!
     *  \fn set(const std::string kind_of_error, const int priority) static void
     *  \brief raise an error or a warning
     *  \param kind_of_error : content of error
     *  \param priority : _ERROR or _WARNING
     */
    static void set(const std::string kind_of_error, const int priority);


    static void set(const std::string kind_of_error, const unsigned int line_number, const int priority);
    /*!
     *  \fn set_and_print(const std::string kind_of_error, const int priority) static void
     *  \brief raise and throw to the interface an error or a warning
     *  \param kind_of_error : content of error
     *  \param priority : _ERROR or _WARNING
     */
    static void set_and_print(const std::string kind_of_error, const int priority);

    /*!
     *  \fn set_and_print(const std::string kind_of_error, const unsigned int line_number, const int priority) static void
     *  \brief raise and throw to the interface an error or a warning and the line when it occurs
     *  \param kind_of_error : content of error
     *  \param line_number : position of the error in the trace
     *  \param priority : _ERROR or _WARNING
     */
    static void set_and_print(const std::string kind_of_error, const unsigned int line_number, const int priority);

    /*!
     *  \fn print(const int priority) static void
     *  \brief print the current error
     *  \param priority : _ERROR or _WARNING
     */
    static void print(const int priority);

    /*!
     *  \fn print(const std::string content, const int priority) static void
     *  \brief print the current error
     *  \param content : the string we want to print
     *  \param priority : _ERROR or _WARNING
     */
    static void print(const std::string content, const int priority);

    /*!
     *  \fn set_if(bool condition, const std::string kind_of_error, const unsigned int line_number, const int priority) static bool
     *  \brief raise an error or a warning and the line when it occurs if the condition is satisfied
     *  \param condition : a condition
     *  \param kind_of_error : content of error
     *  \param line_number : position of the error in the trace
     *  \param priority : _ERROR or _WARNING
     *  \return true if the condition is satisfied
     */
    static bool set_if(bool condition, const std::string kind_of_error, const unsigned int line_number, const int priority);

    /*!
     *  \fn print_numbers() static void
     *  \brief throw to the interface a message about the number of errors and warnings
     */
    static void print_numbers();

    /*!
     *  \fn flush(const std::string &filename) static void
     *  \brief print all the errors and warnings saved in a file and empty the queues _errors and _warnings
     *  \param filename : a file path
     */
    static void flush(const std::string &filename);

};

#endif // ERRORS_HPP
