#include <maps/wikimap/mapspro/services/mrc/libs/ugc_event_logger/include/logger.h>

#include <maps/libs/enum_io/include/enum_io.h>
#include <maps/libs/json/include/builder.h>

#include <string_view>

namespace maps::mrc::ugc_event_logger {

namespace {

using namespace std::string_view_literals;


constexpr enum_io::Representations<Action> ACTION_REPRESENTATIONS{
    {Action::Create, "create"sv},
    {Action::Update, "update"sv},
    {Action::Delete, "delete"sv},
    {Action::View, "view"sv},
};

DECLARE_ENUM_IO(Action);
DEFINE_ENUM_IO(Action, ACTION_REPRESENTATIONS);

chrono::TimePoint getCurrentTimestamp()
{
    return chrono::TimePoint::clock::now();
}


std::string serialize(chrono::TimePoint timePoint, const UserInfo& user, Action action, const Photo& photo)
{
    json::Builder builder;
    builder << [&](json::ObjectBuilder obj) {
        obj["timestamp"] = std::to_string(maps::chrono::convertToUnixTime(timePoint));
        obj["user"] << [&](json::ObjectBuilder obj) {
            obj["ip"] = user.ip;
            if (user.port.has_value()) {
                obj["port"] = user.port.value();
            }

            if (user.uid.has_value()) {
                obj["uid"] = user.uid.value();
            }
        };

        obj["object"] << [&](json::ObjectBuilder obj) {
            obj["type"] = "photo";
            obj["id"] = photo.id;

            if (photo.showAuthorship.has_value()) {
                obj["show_authorship"] = photo.showAuthorship.value();
            }
        };

        obj["action"] = toString(action);
    };
    return builder.str();
}

} // namespace

Logger::Logger(const std::string& path, std::chrono::seconds rotationPeriod, std::optional<GetCurrentTimestampFunc> customGetCurrentTimestamp)
    : rotatingFileLogger_(path, rotationPeriod)
    , getCurrentTimestamp_(customGetCurrentTimestamp.value_or(getCurrentTimestamp))
{}

void Logger::logEvent(const UserInfo& user, Action action, const Photo& photo)
{
    rotatingFileLogger_.writeLine(serialize(getCurrentTimestamp_(), user, action, photo));
}

} // namespace maps::mrc::ugc_event_logger
