#include <maps/wikimap/mapspro/services/mrc/long_tasks/assignment_object_feedback_tasks_emitter/emitter/magic_strings.h>

#include <maps/libs/chrono/include/time_point.h>
#include <maps/wikimap/mapspro/services/mrc/libs/config/include/config.h>
#include <maps/wikimap/mapspro/services/mrc/libs/db/include/metadata_gateway.h>
#include <maps/libs/log8/include/log8.h>
#include <maps/libs/pgpool/include/pgpool3.h>
#include <yandex/maps/wiki/common/pgpool3_helpers.h>

#include <chrono>
#include <cstdint>
#include <iostream>
#include <string>

namespace {

constexpr std::chrono::hours ERROR_HOURS(24);
constexpr std::chrono::hours WARN_HOURS(6);
const std::string NO_METADATA_ERROR
    = "No mrc-assignment-object-feedback-tasks-emitter metadata found";

namespace db = maps::mrc::db;
namespace social = maps::mrc::social;

auto loadPrevRunTime(db::MetadataGateway& gtw)
{
    auto val = gtw.tryLoadByKey(social::metadataKey(social::TIMESTAMP_KEY));
    if (!val) {
        throw maps::Exception() << NO_METADATA_ERROR;
    }
    return maps::chrono::parseSqlDateTime(*val);
}

size_t loadPostedFeedbackCount(db::MetadataGateway& gtw)
{
    auto val = gtw.tryLoadByKey<int64_t>(
        social::metadataKey(social::POSTED_FEEDBACK_COUNT_KEY), -1);
    if (val < 0) {
        throw maps::Exception() << NO_METADATA_ERROR;
    }
    return val;
}

} // namespace

int main(int /*argc*/, char* /*argv*/ []) try {
    maps::log8::setLevel(maps::log8::Level::FATAL);
    auto cfg = maps::mrc::common::templateConfig();
    auto pool = cfg.makePoolHolder(maps::mrc::common::LONG_READ_DB_ID,
                                   maps::mrc::common::LONG_READ_POOL_ID);
    auto txn = pool.pool().slaveTransaction();
    auto gtw = db::MetadataGateway(*txn);
    auto lag = std::chrono::duration_cast<std::chrono::hours>(
        std::chrono::system_clock::now() - loadPrevRunTime(gtw));
    auto count = loadPostedFeedbackCount(gtw);

    if (lag > ERROR_HOURS) {
        std::cout
            << "2;Error: last successful feedback tasks emitter run happened "
            << lag.count() << " hours ago" << std::endl;
    }
    else if (lag > WARN_HOURS) {
        std::cout << "1;Warning: last successful feedback tasks emitter run "
                     "happened "
                  << lag.count() << " hours ago" << std::endl;
    }
    else {
        std::cout << "0;Ok: " << count << " feedbacks posted " << lag.count()
                  << " hours ago" << std::endl;
    }
    return EXIT_SUCCESS;
}
catch (const std::exception& e) {
    std::cout << "2;Error: " << e.what() << std::endl;
    return EXIT_SUCCESS;
}
