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

namespace maps::mrc::eye::datasets {

namespace {

constexpr maps::enum_io::Representations<Action> ACTION_ENUM_REPRESENTATION {
    {Action::Download, "download"},
    {Action::Upload, "upload"},
};


void downloadFromYT(
    NYT::IClientPtr client, DatasetType datasetType,
    const std::string& jsonPath, const std::string& tablePath)
{
    switch (datasetType) {
        case DatasetType::Images:
            ImagesDataset::downloadFromYT(client, jsonPath, tablePath);
            break;
        case DatasetType::Objects:
            ObjectsDataset::downloadFromYT(client, jsonPath, tablePath);
            break;
        case DatasetType::Matches:
            MatchesDataset::downloadFromYT(client, jsonPath, tablePath);
            break;
        case DatasetType::Clusters:
            ClustersDataset::downloadFromYT(client, jsonPath, tablePath);
            break;
        default:
            throw maps::RuntimeError() << "Unknown dataset type: " << toString(datasetType);
    }
}

void uploadToYT(
    NYT::IClientPtr client, DatasetType datasetType,
    const std::string& jsonPath, const std::string& tablePath)
{
    switch (datasetType) {
        case DatasetType::Images:
            ImagesDataset::uploadToYT(client, jsonPath, tablePath);
            break;
        case DatasetType::Objects:
            ObjectsDataset::uploadToYT(client, jsonPath, tablePath);
            break;
        case DatasetType::Matches:
            MatchesDataset::uploadToYT(client, jsonPath, tablePath);
            break;
        case DatasetType::Clusters:
            ClustersDataset::uploadToYT(client, jsonPath, tablePath);
            break;
        default:
            throw maps::RuntimeError() << "Unknown dataset type: " << toString(datasetType);
    }
}

} // namespace

DEFINE_ENUM_IO(Action, ACTION_ENUM_REPRESENTATION);

DatasetManager::DatasetManager(NYT::IClientPtr client)
    : client_(client)
{}

void DatasetManager::perform(
    Action action, DatasetType datasetType,
    const std::string& jsonPath, const std::string& tablePath)
{
    switch (action) {
        case Action::Download:
            downloadFromYT(client_, datasetType, jsonPath, tablePath);
            break;
        case Action::Upload:
            uploadToYT(client_, datasetType, jsonPath, tablePath);
            break;
        default:
            throw maps::RuntimeError() << "Unknown action: " << toString(action);
    };
}

} // namespace maps::mrc::eye::datasets
