#include <maps/wikimap/mapspro/services/mrc/tools/features_deleter/magic_strings.h>

#include <maps/libs/log8/include/log8.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/pgpool/include/pgpool3.h>
#include <yandex/maps/wiki/common/pgpool3_helpers.h>

#include <cstdint>
#include <memory>

using namespace maps::mrc;
namespace fd = maps::mrc::features_deleter;

namespace {

const std::chrono::hours WARN_HOURS{25};
const std::chrono::hours ERROR_HOURS{2 * WARN_HOURS};

using TimePoint = std::chrono::system_clock::time_point ;

TimePoint loadPrevRunTime(db::MetadataGateway& gtw)
{
    auto val = gtw.tryLoadByKey<int64_t>(fd::metadataKey(fd::TIMESTAMP_KEY), -1);
    if (val < 0) {
        throw maps::Exception() << "No features deleter metadata found";
    }

    return TimePoint(std::chrono::seconds(val));
}

size_t loadDeletedFeaturesCount(db::MetadataGateway& gtw)
{
    auto val = gtw.tryLoadByKey<int64_t>(fd::metadataKey(fd::DELETED_COUNT_KEY), -1);
    if (val < 0) {
        throw maps::Exception() << "No features deleter metadata found";
    }
    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();

    auto txn = pool.pool().masterReadOnlyTransaction();
    db::MetadataGateway gtw(*txn);

    const auto lag = std::chrono::duration_cast<std::chrono::hours>(
        std::chrono::system_clock::now() - loadPrevRunTime(gtw)
    );
    auto count = loadDeletedFeaturesCount(gtw);

    if (lag > ERROR_HOURS) {
        std::cout << "2;Error: last successful redundant features deletion "
                  << "happened " << lag.count() << " hours ago" << std::endl;
    }
    else if (lag > WARN_HOURS) {
        std::cout << "1;Warning: last successful redundant features deletion "
                  << "happened " << lag.count() << " hours ago" << std::endl;
    }
    else {
        std::cout << "0;Ok: " << count << " redundant features deleted "
                  << 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;
}
catch (...) {
    std::cout << "2;Error: unknown exception" << std::endl;
    return EXIT_SUCCESS;
}
