/***************************************************************************//**
 *
 * \file support/log.cpp
 *
 * \author David Juhasz (david.juhasz@tuwien.ac.at)
 *
 * \date 2017
 *
 * \brief Implementation for rosa/support/log.h.
 *
 ******************************************************************************/

#include "rosa/support/log.h"

#include "rosa/support/debug.hpp" // NOLINT
#include "rosa/support/terminal_colors.h"

#include <array>

namespace rosa {

/// Textual representation of `rosa::LogLevel` values.
/// \note Do not index with `rosa::LogLevel::NumLogLevels`!
constexpr std::array<const char *, static_cast<size_t>(LogLevel::NumLogLevels)>
    LogLevelStrings{{"ERROR", "WARNING", "INFO", "DEBUG", "TRACE"}};

/// Terminal colors associated to `rosa::LogLevel` values.
/// \note  Do not index with `rosa::LogLevel::NumLogLevels`!
constexpr std::array<terminal::Color,
                     static_cast<size_t>(LogLevel::NumLogLevels)>
    LogLevelColors{{
        terminal::Color::Red,     ///< color corresponding to
                                  /// `rosa::LogLevel::Error`
        terminal::Color::Yellow,  ///< color corresponding to
                                  /// `rosa::LogLevel::Warning`
        terminal::Color::Green,   ///< color corresponding to
                                  /// `rosa::LogLevel::Info`
        terminal::Color::Blue,    ///< color corresponding to
                                  /// `rosa::LogLevel::Debug`
        terminal::Color::Default, ///< color corresponding to
                                  /// `rosa::LogLevel::Trace`
    }};

std::string logLevelToString(const LogLevel logLevel) {
  ASSERT(logLevel != LogLevel::NumLogLevels);
  return LogLevelStrings[static_cast<size_t>(logLevel)];
}

std::ostream &operator<<(std::ostream &OS, const LogLevel logLevel) {
  ASSERT(logLevel != LogLevel::NumLogLevels);
  OS << LogLevelColors[static_cast<size_t>(logLevel)] << "["
     << logLevelToString(logLevel) << "]" << terminal::Color::Default;
  return OS;
}

std::ostream LogSink(nullptr);

} // End namespace rosa

