#include <metadata_keys.h>

#include <maps/wikimap/mapspro/services/mrc/libs/db/include/feature_gateway.h>
#include <maps/wikimap/mapspro/services/mrc/libs/db/include/metadata_gateway.h>
#include <maps/wikimap/mapspro/services/mrc/libs/config/include/config.h>

#include <maps/libs/log8/include/log8.h>
#include <maps/libs/pgpool/include/pgpool3.h>
#include <yandex/maps/wiki/common/pgpool3_helpers.h>
#include <maps/libs/chrono/include/time_point.h>

#include <cstdint>

using namespace maps::mrc;

namespace {

const std::chrono::hours WARN_HOURS{4};
const std::chrono::hours ERROR_HOURS{8};
const std::size_t WARN_UNPROCESSED_COUNT = 100000;
const std::size_t ERROR_UNPROCESSED_COUNT = 200000;

} // 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();
    auto txn = pool.pool().slaveTransaction();

    auto lastRunTime = db::MetadataGateway{*txn}.tryLoadByKey(
        image_analyzer::LAST_RUN_TIME);
    if (!lastRunTime) {
        std::cout << "2;Error: YT image analyzer has never run" << std::endl;
        return EXIT_SUCCESS;
    }

    const auto lag = std::chrono::duration_cast<std::chrono::hours>(
        maps::chrono::TimePoint::clock::now()
        - maps::chrono::parseSqlDateTime(*lastRunTime));

    auto unprocessedCount = db::FeatureGateway{*txn}.count(
            db::table::Feature::quality.isNull()
            && db::table::Feature::roadProbability.isNull()
            && db::table::Feature::forbiddenProbability.isNull());

    if (lag > ERROR_HOURS || unprocessedCount > ERROR_UNPROCESSED_COUNT) {
        std::cout << "2;Error: YT image analyzer ran " << lag.count()
                  << " hours ago. Unprocessed images: " << unprocessedCount
                  << std::endl;
    }
    else if (lag > WARN_HOURS || unprocessedCount > WARN_UNPROCESSED_COUNT) {
        std::cout << "1;Warning: YT image analyzer ran " << lag.count()
                  << " hours ago. Unprocessed images: " << unprocessedCount
                  << std::endl;
    }
    else {
        std::cout << "0;Ok: YT image analyzer up to date"
                  << ". Unprocessed images: " << unprocessedCount << std::endl;
    }
    return EXIT_SUCCESS;
}
catch (const std::exception& e) {
    std::cout << "2;Error: " << e.what() << std::endl;
    return EXIT_SUCCESS;
}
catch (...) {
    std::cout << "2;Error: unknown exception" << std::endl;
    return EXIT_SUCCESS;
}
