#include <maps/libs/cmdline/include/cmdline.h>
#include <maps/libs/log8/include/log8.h>
#include <maps/wikimap/mapspro/libs/sender/include/config.h>
#include <maps/wikimap/mapspro/libs/sqs_client/include/aws_api.h>
#include <maps/wikimap/mapspro/services/tasks_feedback/src/notifications_sender/lib/worker.h>
#include <yandex/maps/wiki/common/default_config.h>
#include <yandex/maps/wiki/common/extended_xml_doc.h>

#include <thread>

namespace json = maps::json;
namespace sender = maps::wiki::sender;


int main(int argc, char* argv[]) try
{
    maps::wiki::sqs::AwsAPI awsApi;
    maps::cmdline::Parser parser;

    auto syslogTag = parser.string("syslog-tag")
        .help("redirect log output to syslog with given tag");

    auto servicesConfigArg = parser.string("services-config")
        .help("path to services config");

    auto senderConfigArg = parser.file("sender-config")
        .help("path to sender configuration");

    parser.parse(argc, argv);

    if (syslogTag.defined()) {
        maps::log8::setBackend(maps::log8::toSyslog(syslogTag));
    }

    std::unique_ptr<maps::wiki::common::ExtendedXmlDoc> servicesConfig;
    if (servicesConfigArg.defined()) {
        servicesConfig = std::make_unique<maps::wiki::common::ExtendedXmlDoc>(servicesConfigArg);
    } else {
        servicesConfig = maps::wiki::common::loadDefaultConfig();
    }

    sender::Config senderConfig = [&]() {
        return senderConfigArg.defined()
            ? sender::Config::fromJson(json::Value::fromFile(senderConfigArg))
            : sender::loadDefaultConfig();
    }();

    maps::wiki::notifications_sender::Worker worker(*servicesConfig, senderConfig);

    while (true) {
        worker.doCycleNoExcept();
        INFO() << "Going to sleep";
        std::this_thread::sleep_for(std::chrono::seconds(10));
    }

    return EXIT_SUCCESS;

} catch (const maps::Exception& ex) {
    FATAL() << "Worker failed: " << ex;
    return EXIT_FAILURE;
} catch (const std::exception& ex) {
    FATAL() << "Worker failed: " << ex.what();
    return EXIT_FAILURE;
} catch (...) {
    FATAL() << "Worker failed: unknown exception";
    return EXIT_FAILURE;
}
