#include <maps/wikimap/mapspro/libs/acl/include/aclgateway.h>

#include <yandex/maps/wiki/common/string_utils.h>
#include <yandex/maps/wiki/common/extended_xml_doc.h>
#include <yandex/maps/wiki/common/default_config.h>
#include <yandex/maps/wiki/common/pgpool3_helpers.h>

#include <maps/libs/cmdline/include/cmdline.h>

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

#include <iostream>

namespace common = maps::wiki::common;

namespace maps::wiki {

void checkQueueSize(
    pgpool3::Pool& pool,
    size_t warnLimit,
    size_t critLimit)
{
    auto txn = pool.masterReadOnlyTransaction();

    auto size = acl::ACLGateway(*txn).clustersUpdateQueueSize();

    if (size > critLimit) {
        std::cout << "2;Error: clusters update queue size " << size << std::endl;
    } else if (size > warnLimit) {
        std::cout << "1;Warning: clusters update queue size " << size << std::endl;
    } else {
        std::cout << "0;OK: clusters update queue size " << size << std::endl;
    }
}

} //namespace maps::wiki

int main(int argc, char* argv[])
try {
    maps::log8::setLevel(maps::log8::Level::FATAL);

    maps::cmdline::Parser parser;
    auto configPath = parser
        .file("config")
        .help("Path to services.xml");
    auto warnLimit = parser
        .size_t("warn")
        .help("Warning limit: clusters update queue size")
        .required();
    auto critLimit = parser
        .size_t("crit")
        .help("Critical limit: clusters update queue size")
        .required();
    parser.parse(argc, argv);

    auto configDocPtr =
        configPath.defined()
        ? std::make_unique<common::ExtendedXmlDoc>(configPath)
        : common::loadDefaultConfig();

    common::PoolHolder coreDbHolder(*configDocPtr, "core", "grinder");

    maps::wiki::checkQueueSize(
        coreDbHolder.pool(),
        warnLimit,
        critLimit);

    return EXIT_SUCCESS;
} catch (const maps::Exception& e) {
    std::cout << "2;Error: " << e.what() << std::endl;
    return EXIT_FAILURE;
} catch (const std::exception& e) {
    std::cout << "2;Error: " << e.what() << std::endl;
    return EXIT_FAILURE;
}
