#include <yandex/maps/wiki/tasks/status_writer.h>

#include <maps/libs/common/include/exception.h>
#include <maps/libs/log8/include/log8.h>

#include <boost/filesystem/path.hpp>
#include <fstream>
#include <algorithm>

namespace maps {
namespace wiki {
namespace tasks {

namespace {

const std::string LOGGING_PREFIX = "StatusWriter: ";

} // namespace

StatusWriter::StatusWriter(std::optional<std::string> logPath)
    : filepath_(std::move(logPath))
{
    reset();
}

void StatusWriter::reinit(const std::string& dirname, const std::string& filename)
{
    boost::filesystem::path filepath(dirname);
    filepath /= filename;
    filepath_ = filepath.c_str();
    reset();
}

void StatusWriter::setMessage(StatusValue statusValue, const std::string& message)
{
    maxStatusValue_ = std::max(maxStatusValue_, statusValue);
    statusMessage_ += (statusValue == StatusValue::WARN ? "WARN: " : "ERR: ");
    statusMessage_ += message;
    statusMessage_ += ". ";
}

void StatusWriter::warn(const std::string& message)
{
    setMessage(StatusValue::WARN, message);
}

void StatusWriter::err(const std::string& message)
{
    setMessage(StatusValue::ERR, message);
}

bool StatusWriter::flush()
{
    bool retVal = true;
    if (filepath_) {
        try {
            INFO() << LOGGING_PREFIX << "writing status into file: '"
                    << *filepath_ << "'. Message: " << statusMessage_;
            std::ofstream of(*filepath_);
            of << static_cast<size_t>(maxStatusValue_) << ";";
            if (statusMessage_.empty()) {
                of << "OK";
            } else {
                of << statusMessage_;
            }
        } catch (const std::exception& ex) {
            FATAL() << LOGGING_PREFIX << "failed: " << ex.what();
            retVal = false;
        }
    } else {
        INFO() << LOGGING_PREFIX << "status is not written";
    }
    return retVal;
}

void StatusWriter::reset()
{
    maxStatusValue_ = StatusValue::OK;
    statusMessage_.clear();
}

} //namespace tasks
} //namespace wiki
} //namespace maps
