#include <maps/wikimap/mapspro/services/mrc/eye/experiments/signs_map/lib/datasets/include/manager.h>

#include <maps/libs/cmdline/include/cmdline.h>
#include <maps/libs/log8/include/log8.h>
#include <mapreduce/yt/interface/client.h>

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

using namespace maps::mrc::eye::datasets;

std::tuple<Action, DatasetType> parseArgs(const std::vector<std::string>& args) {
    REQUIRE(args.size() == 2, "Wrong cmd arguments count");

    Action action;
    fromString(args[0], action);
    DatasetType datasetType;
    fromString(args[1], datasetType);

    return {action, datasetType};
}

int main(int argc, const char** argv) try {
    NYT::Initialize(argc, argv);

    maps::cmdline::Parser parser("Dataset manager:\n"
        "  Action:\n"
        "    1) download - download dataset from YT and save to JSON.\n"
        "    2) upload - upload dataset from JSON to YT.\n"
        "\n"
        "  Dataset type:\n"
        "    1) images - dataset with images\n"
        "    2) objects - dataset with detected objects on images\n"
        "    3) matches - dataset with matches on pairs of features\n"
        "    4) clusters - dataset with clusters of objects on images\n"
        "\n"
        "  Examples:\n"
        "    - Download images dataset from table '//home/images' to JSON file 'images.json'.\n"
        "      dataset_manager download images --table //home/images --json images.json\n"
        "    - Upload matches dataset from JSON file 'matches.json' to YT table '//home/matches'.\n"
        "      dataset_manager upload matches --json matches.json --table //home/matches");

    auto jsonPath = parser.string("json").help("Path to JSON file").required();
    auto tablePath = parser.string("table").help("Path to YT table").required();
    parser.parse(argc, const_cast<char**>(argv));
    const auto& args = parser.argv();

    Action action;
    DatasetType datasetType;
    try {
        std::tie(action, datasetType) = parseArgs(args);
    } catch (const std::exception& e) {
        FATAL() << e.what();
        parser.printUsageAndExit();
    }

    DatasetManager manager(NYT::CreateClient("hahn"));

    manager.perform(action, datasetType, jsonPath, tablePath);

    return EXIT_SUCCESS;
} catch (const maps::Exception& ex) {
    FATAL() << "Failed: " << ex;
    return EXIT_FAILURE;
} catch (const std::exception& ex) {
    FATAL() << "Failed: " << ex.what();
    return EXIT_FAILURE;
} catch (...) {
    FATAL() << "Unknown error!";
}
