#pragma once

#include <maps/wikimap/mapspro/services/editor/src/common.h>
#include <maps/wikimap/mapspro/services/editor/src/execution_state.h>
#include <maps/libs/pgpool/include/pgpool3.h>
#include <boost/optional.hpp>

namespace maps::wiki::tool {

struct SyncTableQueries
{
    std::string searchPath;
    std::string dropIndexes;
    std::string createData;
    StringMap   indexName2definition;
    std::string addPrimaryKey;
};

SyncTableQueries
buildSyncTableQueries(
    pgpool3::Pool& pgPool,
    const std::string& sourceSchemaName,
    const std::string& targetSchemaName,
    const std::string& tableName);


class SyncTable
{
public:
    enum class DisplayRows { Yes, No };

    typedef std::function<boost::optional<size_t>()> Runner;

    SyncTable(
        ExecutionStatePtr executionState,
        const std::string& tableContext,
        DisplayRows displayRows,
        Runner runner);

    void operator() () const;

private:
    void handleError(const char* errorMessage) const;

    ExecutionStatePtr executionState_;
    std::string tableContext_;
    DisplayRows displayRows_;
    Runner runner_;
};

class SyncTableQuery : public SyncTable
{
public:
    SyncTableQuery(
        pgpool3::Pool& pgPool,
        ExecutionStatePtr executionState,
        const std::string& tableContext,
        const std::string& searchPath,
        const std::string& query,
        DisplayRows displayRows = DisplayRows::No);
};


class SyncTableRevisionMeta : public SyncTable
{
public:
    SyncTableRevisionMeta(
        pgpool3::Pool& pgPool,
        ExecutionStatePtr executionState,
        TBranchId sourceBranchId,
        TBranchId targetBranchId);
};

} // namespace maps::wiki::tool
