package ru.yandex.qe.dispenser.domain.util.clickhouse;

import java.util.Arrays;
import java.util.stream.Collectors;

/**
 * Created by inikifor on 16.09.16.
 * <p>
 * Note: not all engines are provided
 */
public enum ClickHouseEngineFactory {
    TINY_LOG("TinyLog"),
    LOG("Log"),
    MEMORY("Memory"),
    MERGE_TREE("MergeTree");

    private final String name;

    ClickHouseEngineFactory(final String name) {
        this.name = name;
    }

    public ClickHouseEngine create(final Object... params) {
        switch (this) {
            case TINY_LOG:
            case LOG:
            case MEMORY: {
                if (params.length != 0) {
                    throw new ClickHouseClientException(this.name + " doesn't support parameters!");
                }
                return new ClickHouseEngine(this.name);
            }
            case MERGE_TREE:
                if (params.length != 3 && params.length != 4) {
                    throw new ClickHouseClientException(this.name + " takes 3 or 4 parameters!");
                }
                if (!(params[0] instanceof String)
                        || !(params[1] instanceof String)
                        || !(params[params.length - 2] instanceof String)
                        || !(params[params.length - 1] instanceof Integer)) {
                    throw new ClickHouseClientException(this.name + " takes (String, String, Integer) or (String, String, String, Integer)!");
                }
                if (params.length == 3) {
                    return new ClickHouseEngine(String.format("%1$s(%2$s,%3$s,%4$d)", this.name, params[0], params[1], (Integer) params[2]));
                } else {
                    return new ClickHouseEngine(String.format("%1$s(%2$s,%3$s,%4$s,%5$d)", this.name, params[0], params[1], params[2], (Integer) params[3]));
                }
            default:
                throw new ClickHouseClientException("Unknown ClickHouseEngineFactory enum constant!");
        }
    }

    public static String paramsTuple(final String... params) {
        return String.format("(%s)", Arrays.stream(params).collect(Collectors.joining(",")));
    }

}
