/*
 * Author:          Patrick-Christopher Mattulat
 * Company:         Lynar Studios
 * E-Mail:          webmaster@lynarstudios.com
 * Created:         2020-08-20
 * Changed:         2021-04-23
 *
 * */

#include <ls_std/io/logging/Logger.hpp>
#include <ls_std/time/Date.hpp>
#include <ls_std/io/NewLine.hpp>
#include <ls_std/boxing/String.hpp>
#include <ls_std/exception/NullPointerException.hpp>

ls_std::Logger::Logger(const std::shared_ptr<ls_std::IWriter> &_writer)
    : ls_std::Class("Logger"),
      logLevel(ls_std::LogLevelValue::INFO)
{
  if (_writer == nullptr)
  {
    throw ls_std::NullPointerException{};
  }

  this->writer = _writer;
}

void ls_std::Logger::debug(const ls_std::byte *_data)
{
  if (this->logLevel >= ls_std::LogLevelValue::DEBUG)
  {
    this->_log(_data, ls_std::LogLevel(ls_std::LogLevelValue::DEBUG));
  }
}

void ls_std::Logger::error(const ls_std::byte *_data)
{
  if (this->logLevel >= ls_std::LogLevelValue::ERR)
  {
    this->_log(_data, ls_std::LogLevel(ls_std::LogLevelValue::ERR));
  }
}

void ls_std::Logger::fatal(const ls_std::byte *_data)
{
  if (this->logLevel >= ls_std::LogLevelValue::FATAL)
  {
    this->_log(_data, ls_std::LogLevel(ls_std::LogLevelValue::FATAL));
  }
}

ls_std::LogLevel ls_std::Logger::getLogLevel()
{
  return this->logLevel;
}

void ls_std::Logger::info(const ls_std::byte *_data)
{
  if (this->logLevel >= ls_std::LogLevelValue::INFO)
  {
    this->_log(_data, ls_std::LogLevel(ls_std::LogLevelValue::INFO));
  }
}

void ls_std::Logger::setLogLevel(const ls_std::LogLevelValue &_logLevelValue)
{
  this->logLevel = _logLevelValue;
}

void ls_std::Logger::trace(const ls_std::byte *_data)
{
  if (this->logLevel >= ls_std::LogLevelValue::TRACE)
  {
    this->_log(_data, ls_std::LogLevel(ls_std::LogLevelValue::TRACE));
  }
}

void ls_std::Logger::warn(const ls_std::byte *_data)
{
  if (this->logLevel >= ls_std::LogLevelValue::WARN)
  {
    this->_log(_data, ls_std::LogLevel(ls_std::LogLevelValue::WARN));
  }
}

void ls_std::Logger::_log(const ls_std::byte *_data, const ls_std::LogLevel &_logLevel)
{
  ls_std::Date date{};
  std::string message = "[" + date.toString() + "] " + ls_std::String{_logLevel.toString() + ":"}.padRight(10, ' ') + std::string(_data) + ls_std::NewLine::getUnixNewLine();
  this->writer->write(message);
}
