package ru.yandex.webmaster3.storage.util.ydb.querybuilder.typesafe;

import java.util.Collection;


import com.yandex.ydb.table.result.ResultSetReader;

import ru.yandex.webmaster3.core.util.functional.Functions;

/**
 * ishalaru
 * 16.06.2020
 **/
public interface RowMapper<T> {
    Collection<String> getDependencyColumns();

    T get(ResultSetReader row);

    /* Generated combiners */

    default <C1, R> DataMapper<R> combine(RowMapper<C1> m1, Functions.F2<T, C1, R> combiner) {
        RowMapper<T> outer = this;
        return new DataMapper<R>(getDependencyColumns(), m1) {
            @Override
            public R get(ResultSetReader row) {
                return combiner.apply(outer.get(row), m1.get(row));
            }
        };
    }

    default <C1, C2, R> DataMapper<R> combine(RowMapper<C1> m1, RowMapper<C2> m2, Functions.F3<T, C1, C2, R> combiner) {
        RowMapper<T> outer = this;
        return new DataMapper<R>(getDependencyColumns(), m1, m2) {
            @Override
            public R get(ResultSetReader row) {
                return combiner.apply(outer.get(row), m1.get(row), m2.get(row));
            }
        };
    }

    default <C1, C2, C3, R> DataMapper<R> combine(RowMapper<C1> m1, RowMapper<C2> m2, RowMapper<C3> m3, Functions.F4<T, C1, C2, C3, R> combiner) {
        RowMapper<T> outer = this;
        return new DataMapper<R>(getDependencyColumns(), m1, m2, m3) {
            @Override
            public R get(ResultSetReader row) {
                return combiner.apply(outer.get(row), m1.get(row), m2.get(row), m3.get(row));
            }
        };
    }

    default <C1, C2, C3, C4, R> DataMapper<R> combine(RowMapper<C1> m1, RowMapper<C2> m2, RowMapper<C3> m3, RowMapper<C4> m4, Functions.F5<T, C1, C2, C3, C4, R> combiner) {
        RowMapper<T> outer = this;
        return new DataMapper<R>(getDependencyColumns(), m1, m2, m3, m4) {
            @Override
            public R get(ResultSetReader row) {
                return combiner.apply(outer.get(row), m1.get(row), m2.get(row), m3.get(row), m4.get(row));
            }
        };
    }

    default <C1, C2, C3, C4, C5, R> DataMapper<R> combine(RowMapper<C1> m1, RowMapper<C2> m2, RowMapper<C3> m3, RowMapper<C4> m4, RowMapper<C5> m5, Functions.F6<T, C1, C2, C3, C4, C5, R> combiner) {
        RowMapper<T> outer = this;
        return new DataMapper<R>(getDependencyColumns(), m1, m2, m3, m4, m5) {
            @Override
            public R get(ResultSetReader row) {
                return combiner.apply(outer.get(row), m1.get(row), m2.get(row), m3.get(row), m4.get(row), m5.get(row));
            }
        };
    }
}
