#include <maps/libs/cmdline/include/cmdline.h>
#include <maps/libs/log8/include/log8.h>
#include <maps/libs/pgpool/include/pgpool3.h>

#include <maps/libs/common/include/exception.h>
#include <yandex/maps/wiki/common/robot.h>
#include <yandex/maps/wiki/common/batch.h>
#include <yandex/maps/wiki/common/default_config.h>
#include <yandex/maps/wiki/common/pgpool3_helpers.h>
#include <yandex/maps/wiki/common/robot.h>
#include <yandex/maps/wiki/social/common.h>
#include <yandex/maps/wiki/social/feedback/gateway_rw.h>
#include <yandex/maps/wiki/social/feedback/agent.h>

using namespace maps;
using namespace maps::wiki::common;
using namespace maps::wiki::social;

int main(int argc, char* argv[]) try
{
    // Parsing args
    //
    cmdline::Parser parser;

    auto servicesConfigArg = parser.string("config")
        .help("path to service configuration file");

    auto taskOperation = parser.string("operation")
        .required()
        .help("only 'deploy' supported now.");

    auto isDryRun = parser.flag("dry-run")
        .help("don't modify database")
        .defaultValue(false);

    parser.parse(argc, argv);
    auto argvVector = parser.argv();
    REQUIRE(argvVector.size() >= 1, "pass one or more feedback ids");

    const auto servicesConfig = [&]() {
        if (servicesConfigArg.defined()) {
            return std::make_unique<ExtendedXmlDoc>(servicesConfigArg);
        } else {
            return loadDefaultConfig();
        }
    }();

    PoolHolder socialTxnPool(*servicesConfig, "social", "social");
    auto txnHandle = socialTxnPool.pool().masterWriteableTransaction();
    auto& txn = txnHandle.get();

    feedback::Agent agent(txn, ROBOT_UID);
    for (const auto& taskIdString : argvVector) {
        auto taskId = std::stol(taskIdString);
        INFO() << "Applying operation '" << taskOperation
            << "' on task " << taskId;
        if (taskOperation == "deploy") {
            agent.deployTaskByIdCascade(taskId, std::chrono::system_clock::now());
        } else {
            REQUIRE(false, "Unknown operation '" << taskOperation << "'");
        }
    }
    if (isDryRun) {
        INFO() << "DRY-RUN successfully finished.";
    } else {
        txn.commit();
        INFO() << "Database modified. All successfully done.";
    }
    return EXIT_SUCCESS;

} catch (const Exception& e) {
    ERROR() << e;
    return EXIT_FAILURE;
} catch (const std::exception& e) {
    ERROR() << e.what();
    return EXIT_FAILURE;
} catch (...) {
    ERROR() << "Unknown exeption";
    return EXIT_FAILURE;
}
