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

#include <iostream>
#include <sstream>
/* -- */
#include "common.hpp"
#include "Log.hpp"
/* -- */

#ifdef VITE_DEBUG
/* Test mode */
class Log
{
public:
    void error(const std::string &s) {
        std::cerr << "ERROR: " << s << std::endl;
    }
    void warning(const std::string &s) {
        std::cerr << "WARNING: " << s << std::endl;
    }
    void information(const std::string &s) {
        std::cerr << "INFORMATION: " << s << std::endl;
    }
};
#else
/* Release mode */

#include "Log.hpp"

#endif

#include "common/Message.hpp"

Message *Message::_message = nullptr;
Log *Message::_log_support = nullptr;

#ifdef _MSC_VER // TODO : Check if needed for icc
const Message::end_error_t Message::ende;
const Message::end_warning_t Message::endw;
const Message::end_information_t Message::endi;
#endif

Message::Message() = default;

Message *Message::get_instance() {
    if (_message)
        return _message;
    else
        return _message = new Message();
}

void Message::kill() {
    if (_message)
        delete _message;
    _message = nullptr;
}

void Message::set_log_support(Log *log_support) {
    _log_support = log_support;
}

Log *Message::get_log_support() {
    return _log_support;
}

std::ostream &operator<<(std::ostream &out, Message::end_error_t) {
    Message *message = Message::get_instance();
    Log *log_support = Message::get_log_support();

    if (log_support) {
        log_support->error(message->str());
        message->str(""); // flush the stream
    }
    else {
        vite_error("Warning: no log_support designed to display messages.");
    }
    return out;
}

std::ostream &operator<<(std::ostream &out, Message::end_warning_t) {
    Message *message = Message::get_instance();
    Log *log_support = Message::get_log_support();

    if (log_support) {
        log_support->warning(message->str());
        message->str(""); // flush the stream
    }
    else {
        vite_error("Warning: no log_support designed to display messages.");
    }
    return out;
}

std::ostream &operator<<(std::ostream &out, Message::end_information_t) {
    Message *message = Message::get_instance();
    Log *log_support = Message::get_log_support();

    if (log_support) {
        log_support->information(message->str());
        message->str(""); // flush the stream
    }
    else {
        vite_error("Warning: no log_support designed to display messages.");
    }
    return out;
}
