package ru.yandex.webmaster3.storage.util.yt;

import java.util.Collection;
import java.util.List;

import com.fasterxml.jackson.databind.JsonNode;

import org.jetbrains.annotations.Nullable;
import ru.yandex.webmaster3.core.util.functional.ThrowingConsumer;

/**
 * @author aherman
 */
public interface YtCypressService {

    String getTransactionId();

    YtNode getNode(YtPath path) throws YtException;

    boolean exists(YtPath path) throws YtException;

    YtNode create(YtPath path, YtNode.NodeType nodeType, boolean recursive) throws YtException;

    YtNode create(YtPath path, YtNode.NodeType nodeType, boolean recursive, YtNodeAttributes attributes) throws YtException;

    YtNode create(YtPath path, YtNode.NodeType nodeType, boolean recursive, YtNodeAttributes attributes,
                  boolean ignoreExisting) throws YtException;

    //  Создание на мета-кластере специального объекта replicated_table, хранящего информацию о репликах и статусе репликации
    YtNode createReplicatedTable(YtPath replicatedTablePath, YtSchema schema, boolean ignoreExisting, boolean mountTable) throws YtException;

    // Регистрация реплики на мета-кластере в replicated_table и создание собственно реплицированной таблицы
    YtReplicaId setupReplication(YtPath replicatedTablePath, YtPath replicaPath, YtSchema schema,
                                 boolean ignoreExisting, boolean mountReplica) throws YtException;

    // Управление репликацией (вкл/выкл, режим) для уже существующей реплики
    void alterTableReplica(YtReplicaId replicaId, @Nullable Boolean isEnabled,
                           @Nullable YtAlterTableReplicaCommand.ReplicationMode replicationMode) throws YtException;

    // Делает из статической таблицы динамическую
    void convertTableToDynamic(YtPath path) throws YtException;

    YtReplicaId createReplica(YtPath tablePath, YtPath replicaPath, YtNodeAttributes attributes) throws YtException;

    void mount(YtPath path) throws YtException;

    List<YtPath> list(YtPath path) throws YtException;

    void remove(YtPath path) throws YtException;

    void remove(YtPath path, boolean recursive) throws YtException;

    void remove(YtPath path, boolean recursive, boolean force) throws YtException;

    void copy(YtPath sourcePath, YtPath destinationPath, boolean recursive) throws YtException;

    default void move(YtPath sourcePath, YtPath destinationPath, boolean recursive) throws YtException {
        move(sourcePath, destinationPath, recursive, false);
    }

    void move(YtPath sourcePath, YtPath destinationPath, boolean recursive, boolean force) throws YtException;

    void link(YtPath targetPath, YtPath linkPath, boolean force) throws YtException;

    void set(YtPath path, JsonNode data) throws YtException;

    YtOperationId sort(YtPath sourcePaths, YtPath destinationPath, String... sortBy) throws YtException;

    YtOperationId sort(YtPath sourcePaths, YtPath destinationPath, List<String> sortBy) throws YtException;

    YtOperationId sort(List<YtPath> sourcePaths, YtPath destinationPath, String... sortBy) throws YtException;

    YtOperationId sort(List<YtPath> sourcePaths, YtPath destinationPath, List<String> sortBy) throws YtException;

    YtOperationId merge(YtPath sourceTable, YtPath destinationTable, String... mergeBy) throws YtException;

    YtOperationId merge(List<YtPath> sourceTables, YtPath destinationTable, String... mergeBy) throws YtException;

    YtOperationId map(YtMapCommand command) throws YtException;

    YtOperationId mapReduce(YtMapReduceCommand command) throws YtException;

    YtOperationId reduce(YtReduceCommand command) throws YtException;

    YtOperationId erase(YtPath table, Collection<YtTableRange> ranges) throws YtException;

    YtOperationId startOperation(AbstractYtJob command);

    public <E extends Exception> void writeTable(YtPath path, ThrowingConsumer<TableWriter, E> writerConsumer) throws YtException, E;
    void writeTable(YtPath path, YtTableData tableData) throws YtException;
    void writeTable(YtPath path, YtTableData tableData, boolean append) throws YtException;

    YtOperation getOperation(YtOperationId operationId) throws YtException;

    void abortOperation(YtOperationId operationId) throws YtException;
    void completeOperation(YtOperationId operationId) throws YtException;

    boolean waitFor(YtOperationId operationId) throws YtException;

    List<JsonNode> selectRows(YtPath path, String where, String... fields) throws YtException;

    <T> List<T> getRows(YtPath path, List<Object> keyValues, Class<T> rowClass) throws YtException;

    <T> List<T> getRows(YtPath path, List<Object> keyValues, YtRowMapper<T> rowMapper) throws YtException;

    void lock(YtPath path, YtLockMode mode) throws YtException;
}
