// This file is part of necsim project which is released under MIT license.
// See file **LICENSE.txt** or visit https://opensource.org/licenses/MIT) for full license details.
/**
 * @author Sam Thompson
 * @file LogFile.h
 * @brief Contains a class for logging to a logfile, including reporting level and timestamps.
 * @copyright <a href="https://opensource.org/licenses/MIT"> MIT Licence.</a>
 */

#ifndef LOGFILE_H
#define LOGFILE_H

#include <cstring>
#include <fstream>
#include <ctime>
#include <map>

#define LOGNAME_FORMAT "%d%m%Y_%H%M%S"

using std::string;
namespace necsim
{
    /**
     * @brief Gets the current system time in string form.
     * @return the system time in string form
     */
    string getTime();

    /**
     * @brief Gets the default log file path.
     * Stored at log/DDMMYYYY_HHMMSS.log where DDMMYYYY_HHMMSS are replaced by the current date and time.
     * @return location of the default logging position.
     */
    string getDefaultLogFile();

    /**
     * @brief Modifies the file name so that it doesn't point to an existing file.
     * @param basic_string the file name to modify
     */
    void getUniqueFileName(string &basic_string);

    /**
     * @brief Contains routines for writing to log files.
     */
    class LogFile
    {
    protected:
        // output stream to log file
        std::ofstream output_stream;
        // log file name
        string file_name;
        // mapping integer levels to logger level
        std::map<int, string> levels_map;





    public:
        /**
         * @brief Default constructor.
         */
        LogFile();
        // Makes the class non-copyable as we don't want to copy file streams
        LogFile(const LogFile &) = delete;

        LogFile &operator=(const LogFile &) = delete;

        /**
         * @brief Constructor taking location of a log file.
         * @param file_name_in the path to the log file to open
         */
        explicit LogFile(string file_name_in);

        /**
         * @brief Default destructor, including writing closure out to log file.
         */
        ~LogFile();

        /**
         * @brief Initialises the LogFile by creating a file at the specified location.
         * @param file_name_in the file to create
         */
        void init(string file_name_in);

        /**
         * @brief Writes the message out to the logfile at the specified logging level.
         * @param level the level of logging severity
         * @param message the message to write out
         */
        void write(const int &level, string message);

        /**
         * @brief Writes the message out to the logfile at the specified logging level.
         * @param level the level of logging severity
         * @param message the message to write out
         */
        void write(const int &level, std::stringstream &message);
    };
}
#endif //LOGFILE_H
