/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.apache.ignite.internal.schema.configuration;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;
import java.util.UUID;
import org.apache.ignite.configuration.NamedListView;
import org.apache.ignite.configuration.schemas.table.ColumnChange;
import org.apache.ignite.configuration.schemas.table.ColumnTypeChange;
import org.apache.ignite.configuration.schemas.table.ColumnTypeView;
import org.apache.ignite.configuration.schemas.table.ColumnView;
import org.apache.ignite.configuration.schemas.table.IndexColumnChange;
import org.apache.ignite.configuration.schemas.table.IndexColumnView;
import org.apache.ignite.configuration.schemas.table.TableChange;
import org.apache.ignite.configuration.schemas.table.TableConfiguration;
import org.apache.ignite.configuration.schemas.table.TableIndexChange;
import org.apache.ignite.configuration.schemas.table.TableIndexView;
import org.apache.ignite.configuration.schemas.table.TableView;
import org.apache.ignite.configuration.schemas.table.TablesChange;
import org.apache.ignite.internal.schema.ColumnImpl;
import org.apache.ignite.internal.schema.HashIndexImpl;
import org.apache.ignite.internal.schema.PartialIndexImpl;
import org.apache.ignite.internal.schema.PrimaryIndexImpl;
import org.apache.ignite.internal.schema.SchemaTableImpl;
import org.apache.ignite.internal.schema.SortedIndexColumnImpl;
import org.apache.ignite.internal.schema.SortedIndexImpl;
import org.apache.ignite.schema.Column;
import org.apache.ignite.schema.ColumnType;
import org.apache.ignite.schema.HashIndex;
import org.apache.ignite.schema.IndexColumn;
import org.apache.ignite.schema.PartialIndex;
import org.apache.ignite.schema.PrimaryIndex;
import org.apache.ignite.schema.SchemaTable;
import org.apache.ignite.schema.SortOrder;
import org.apache.ignite.schema.SortedIndex;
import org.apache.ignite.schema.SortedIndexColumn;
import org.apache.ignite.schema.TableIndex;

/**
 * Configuration to schema and vice versa converter.
 */
public class SchemaConfigurationConverter {
    /** Hash index type. */
    private static final String HASH_TYPE = "HASH";

    /** Sorted index type. */
    private static final String SORTED_TYPE = "SORTED";

    /** Partial index type. */
    private static final String PARTIAL_TYPE = "PARTIAL";

    /** Primary key index type. */
    private static final String PK_TYPE = "PK";

    /** Types map. */
    private static final Map<String, ColumnType> types = new HashMap<>();

    static {
        putType(ColumnType.INT8);
        putType(ColumnType.INT16);
        putType(ColumnType.INT32);
        putType(ColumnType.INT64);
        putType(ColumnType.UINT8);
        putType(ColumnType.UINT16);
        putType(ColumnType.UINT32);
        putType(ColumnType.UINT64);
        putType(ColumnType.FLOAT);
        putType(ColumnType.DOUBLE);
        putType(ColumnType.UUID);
        putType(ColumnType.DATE);
    }

    /**
     * @param type Column type.
     */
    private static void putType(ColumnType type) {
        types.put(type.typeSpec().name(), type);
    }

    /**
     * Convert SortedIndexColumn to IndexColumnChange.
     *
     * @param col IndexColumnChange.
     * @param colInit IndexColumnChange to fulfill.
     * @return IndexColumnChange to get result from.
     */
    public static IndexColumnChange convert(SortedIndexColumn col, IndexColumnChange colInit) {
        colInit.changeName(col.name());

        colInit.changeAsc(col.sortOrder() == SortOrder.ASC);

        return colInit;
    }

    /**
     * Convert IndexColumnView to SortedIndexColumn.
     *
     * @param colCfg IndexColumnView.
     * @return SortedIndexColumn.
     */
    public static SortedIndexColumn convert(IndexColumnView colCfg) {
        return new SortedIndexColumnImpl(colCfg.name(), colCfg.asc() ? SortOrder.ASC : SortOrder.DESC);
    }

    /**
     * Convert TableIndex to TableIndexChange.
     *
     * @param idx TableIndex.
     * @param idxChg TableIndexChange to fulfill.
     * @return TableIndexChange to get result from.
     */
    public static TableIndexChange convert(TableIndex idx, TableIndexChange idxChg) {
        idxChg.changeName(idx.name());
        idxChg.changeType(idx.type());

        switch (idx.type().toUpperCase()) {
            case HASH_TYPE:
                HashIndex hashIdx = (HashIndex)idx;

                String[] colNames = hashIdx.columns().stream().map(IndexColumn::name).toArray(String[]::new);

                idxChg.changeColNames(colNames);

                break;

            case PARTIAL_TYPE:
                PartialIndex partIdx = (PartialIndex)idx;

                idxChg.changeUniq(partIdx.unique());
                idxChg.changeExpr(partIdx.expr());

                idxChg.changeColumns(colsChg -> {
                    int colIdx = 0;

                    for (SortedIndexColumn col : partIdx.columns())
                        colsChg.create(String.valueOf(colIdx++), colInit -> convert(col, colInit));
                });

                break;

            case SORTED_TYPE:
                SortedIndex sortIdx = (SortedIndex)idx;
                idxChg.changeUniq(sortIdx.unique());

                idxChg.changeColumns(colsInit -> {
                    int colIdx = 0;

                    for (SortedIndexColumn col : sortIdx.columns())
                        colsInit.create(String.valueOf(colIdx++), colInit -> convert(col, colInit));
                });

                break;

            case PK_TYPE:
                PrimaryIndex primIdx = (PrimaryIndex)idx;

                idxChg.changeColumns(colsInit -> {
                    int colIdx = 0;

                    for (SortedIndexColumn col : primIdx.columns())
                        colsInit.create(String.valueOf(colIdx++), colInit -> convert(col, colInit));
                });

                idxChg.changeAffinityColumns(primIdx.affinityColumns().toArray(
                    new String[primIdx.affinityColumns().size()]));

                break;

            default:
                throw new IllegalArgumentException("Unknown index type " + idx.type());
        }

        return idxChg;
    }

    /**
     * Convert TableIndexView into TableIndex.
     *
     * @param idxView TableIndexView.
     * @return TableIndex.
     */
    public static TableIndex convert(TableIndexView idxView) {
        String name = idxView.name();
        String type = idxView.type();

        switch (type.toUpperCase()) {
            case HASH_TYPE:
                String[] hashCols = idxView.colNames();

                return new HashIndexImpl(name, hashCols);

            case SORTED_TYPE:
                boolean sortedUniq = idxView.uniq();

                SortedMap<Integer, SortedIndexColumn> sortedCols = new TreeMap<>();

                for (String key : idxView.columns().namedListKeys()) {
                    SortedIndexColumn col = convert(idxView.columns().get(key));

                    sortedCols.put(Integer.valueOf(key), col);
                }

                return new SortedIndexImpl(name, new ArrayList<>(sortedCols.values()), sortedUniq);

            case PARTIAL_TYPE:
                boolean partialUniq = idxView.uniq();
                String expr = idxView.expr();

                NamedListView<? extends IndexColumnView> colsView = idxView.columns();
                SortedMap<Integer, SortedIndexColumn> partialCols = new TreeMap<>();

                for (String key : idxView.columns().namedListKeys()) {
                    SortedIndexColumn col = convert(colsView.get(key));

                    partialCols.put(Integer.valueOf(key), col);
                }

                return new PartialIndexImpl(name, new ArrayList<>(partialCols.values()), partialUniq, expr);

            case PK_TYPE:
                SortedMap<Integer, SortedIndexColumn> cols = new TreeMap<>();

                for (String key : idxView.columns().namedListKeys()) {
                    SortedIndexColumn col = convert(idxView.columns().get(key));

                    cols.put(Integer.valueOf(key), col);
                }

                String[] affCols = idxView.affinityColumns();

                return new PrimaryIndexImpl(new ArrayList<>(cols.values()), List.of(affCols));

            default:
                throw new IllegalArgumentException("Unknown type " + type);
        }
    }

    /**
     * Convert ColumnType to ColumnTypeChange.
     *
     * @param colType ColumnType.
     * @param colTypeChg ColumnTypeChange to fulfill.
     * @return ColumnTypeChange to get result from
     */
    public static ColumnTypeChange convert(ColumnType colType, ColumnTypeChange colTypeChg) {
        String typeName = colType.typeSpec().name().toUpperCase();

        if (types.containsKey(typeName))
            colTypeChg.changeType(typeName);
        else {
            colTypeChg.changeType(typeName);

            switch (typeName) {
                case "BITMASK":
                case "BLOB":
                case "STRING":
                    ColumnType.VarLenColumnType varLenColType = (ColumnType.VarLenColumnType)colType;

                    colTypeChg.changeLength(varLenColType.length());

                    break;

                case "DECIMAL":
                    ColumnType.DecimalColumnType numColType = (ColumnType.DecimalColumnType)colType;

                    colTypeChg.changePrecision(numColType.precision());
                    colTypeChg.changeScale(numColType.scale());

                    break;

                case "NUMBER":
                    ColumnType.NumberColumnType numType = (ColumnType.NumberColumnType)colType;

                    colTypeChg.changePrecision(numType.precision());

                    break;

                case "TIME":
                case "DATETIME":
                case "TIMESTAMP":
                    ColumnType.TemporalColumnType temporalColType = (ColumnType.TemporalColumnType)colType;

                    colTypeChg.changePrecision(temporalColType.precision());

                    break;

                default:
                    throw new IllegalArgumentException("Unknown type " + colType.typeSpec().name());
            }
        }

        return colTypeChg;
    }

    /**
     * Convert ColumnTypeView to ColumnType.
     *
     * @param colTypeView ColumnTypeView.
     * @return ColumnType.
     */
    public static ColumnType convert(ColumnTypeView colTypeView) {
        String typeName = colTypeView.type().toUpperCase();
        ColumnType res = types.get(typeName);

        if (res != null)
            return res;
        else {
            switch (typeName) {
                case "BITMASK":
                    int bitmaskLen = colTypeView.length();

                    return ColumnType.bitmaskOf(bitmaskLen);

                case "STRING":
                    int strLen = colTypeView.length();

                    return ColumnType.stringOf(strLen);

                case "BLOB":
                    int blobLen = colTypeView.length();

                    return ColumnType.blobOf(blobLen);

                case "DECIMAL":
                    int prec = colTypeView.precision();
                    int scale = colTypeView.scale();

                    return ColumnType.decimalOf(prec, scale);

                case "NUMBER":
                    return ColumnType.numberOf(colTypeView.precision());

                case "TIME":
                    return ColumnType.time(colTypeView.precision());

                case "DATETIME":
                    return ColumnType.datetime(colTypeView.precision());

                case "TIMESTAMP":
                    return ColumnType.timestamp(colTypeView.precision());

                default:
                    throw new IllegalArgumentException("Unknown type " + typeName);
            }
        }
    }

    /**
     * Convert column to column change.
     *
     * @param col Column to convert.
     * @param colChg Column
     * @return ColumnChange to get result from.
     */
    public static ColumnChange convert(Column col, ColumnChange colChg) {
        colChg.changeName(col.name());
        colChg.changeType(colTypeInit -> convert(col.type(), colTypeInit));

        if (col.defaultValue() != null)
            colChg.changeDefaultValue(col.defaultValue().toString());

        colChg.changeNullable(col.nullable());

        return colChg;
    }

    /**
     * Convert column view to Column.
     *
     * @param colView Column view.
     * @return Column.
     */
    public static Column convert(ColumnView colView) {
        return new ColumnImpl(
            colView.name(),
            convert(colView.type()),
            colView.nullable(),
            colView.defaultValue());
    }

    /**
     * Convert schema table to schema table change.
     *
     * @param tbl Schema table to convert.
     * @param tblChg Change to fulfill.
     * @return TableChange to get result from.
     */
    public static TableChange convert(SchemaTable tbl, TableChange tblChg) {
        tblChg.changeName(tbl.canonicalName());

        tblChg.changeIndices(idxsChg -> {
            int idxIdx = 0;

            for (TableIndex idx : tbl.indices())
                idxsChg.create(String.valueOf(idxIdx++), idxInit -> convert(idx, idxInit));
        });

        tblChg.changeColumns(colsChg -> {
            int colIdx = 0;

            for (Column col : tbl.keyColumns())
                colsChg.create(String.valueOf(colIdx++), colChg -> convert(col, colChg));

            for (Column col : tbl.valueColumns())
                colsChg.create(String.valueOf(colIdx++), colChg -> convert(col, colChg));
        });

        return tblChg;
    }

    /**
     * Convert TableConfiguration to SchemaTable.
     *
     * @param tblCfg TableConfiguration to convert.
     * @return SchemaTable.
     */
    public static SchemaTable convert(TableConfiguration tblCfg) {
        return convert(tblCfg.value());
    }

    /**
     * Convert configuration to SchemaTable.
     *
     * @param tblView TableView to convert.
     * @return SchemaTable.
     */
    public static SchemaTableImpl convert(TableView tblView) {
        String canonicalName = tblView.name();
        int sepPos = canonicalName.indexOf('.');
        String schemaName = canonicalName.substring(0, sepPos);
        String tableName = canonicalName.substring(sepPos + 1);

        NamedListView<? extends ColumnView> colsView = tblView.columns();

        SortedMap<Integer, Column> columns = new TreeMap<>();

        for (String key : colsView.namedListKeys()) {
            ColumnView colView = colsView.get(key);

            if (colView != null) {
                Column col = convert(colView);

                columns.put(Integer.valueOf(key), col);
            }
        }

        NamedListView<? extends TableIndexView> idxsView = tblView.indices();

        Map<String, TableIndex> indices = new HashMap<>(idxsView.size());

        for (String key : idxsView.namedListKeys()) {
            TableIndexView idxView = idxsView.get(key);
            TableIndex idx = convert(idxView);

            indices.put(idx.name(), idx);
        }

        LinkedHashMap<String, Column> colsMap = new LinkedHashMap<>(colsView.size());

        columns.forEach((i, v) -> colsMap.put(v.name(), v));

        return new SchemaTableImpl(schemaName, tableName, colsMap, indices);
    }

    /**
     * Create table.
     *
     * @param tbl Table to create.
     * @param tblsChange Tables change to fulfill.
     * @return TablesChange to get result from.
     */
    public static TablesChange createTable(SchemaTable tbl, TablesChange tblsChange) {
        return tblsChange.changeTables(tblsChg -> tblsChg.create(tbl.canonicalName(), tblChg -> convert(tbl, tblChg)));
    }

    /**
     * Drop table.
     *
     * @param tbl table to drop.
     * @param tblsChange TablesChange change to fulfill.
     * @return TablesChange to get result from.
     */
    public static TablesChange dropTable(SchemaTable tbl, TablesChange tblsChange) {
        return tblsChange.changeTables(schmTblChange -> schmTblChange.delete(tbl.canonicalName()));
    }

    /**
     * Add index.
     *
     * @param idx Index to add.
     * @param tblChange TableChange to fulfill.
     * @return TableChange to get result from.
     */
    public static TableChange addIndex(TableIndex idx, TableChange tblChange) {
        return tblChange.changeIndices(idxsChg -> idxsChg.create(idx.name(), idxChg -> convert(idx, idxChg)));
    }

    /**
     * Drop index.
     *
     * @param indexName Index name to drop.
     * @param tblChange Table change to fulfill.
     * @return TableChange to get result from.
     */
    public static TableChange dropIndex(String indexName, TableChange tblChange) {
        return tblChange.changeIndices(idxChg -> idxChg.delete(indexName));
    }

    /**
     * Add table column.
     *
     * @param column Column to add.
     * @param tblChange TableChange to fulfill.
     * @return TableChange to get result from.
     */
    public static TableChange addColumn(Column column, TableChange tblChange) {
        return tblChange.changeColumns(colsChg -> colsChg.create(column.name(), colChg -> convert(column, colChg)));
    }

    /**
     * Drop table column.
     *
     * @param columnName column name to drop.
     * @param tblChange TableChange to fulfill.
     * @return TableChange to get result from.
     */
    public static TableChange dropColumn(String columnName, TableChange tblChange) {
        return tblChange.changeColumns(colChg -> colChg.delete(columnName));
    }

    /**
     * Gets ColumnType type for given class.
     *
     * @param cls Class.
     * @return ColumnType type or null.
     */
    public static ColumnType columnType(Class<?> cls) {
        assert cls != null;

        // Primitives.
        if (cls == byte.class)
            return ColumnType.INT8;
        else if (cls == short.class)
            return ColumnType.INT16;
        else if (cls == int.class)
            return ColumnType.INT32;
        else if (cls == long.class)
            return ColumnType.INT64;
        else if (cls == float.class)
            return ColumnType.FLOAT;
        else if (cls == double.class)
            return ColumnType.DOUBLE;

        // Boxed primitives.
        else if (cls == Byte.class)
            return ColumnType.INT8;
        else if (cls == Short.class)
            return ColumnType.INT16;
        else if (cls == Integer.class)
            return ColumnType.INT32;
        else if (cls == Long.class)
            return ColumnType.INT64;
        else if (cls == Float.class)
            return ColumnType.FLOAT;
        else if (cls == Double.class)
            return ColumnType.DOUBLE;

        // Temporal types.
        else if (cls == LocalDate.class)
            return ColumnType.DATE;
        else if (cls == LocalTime.class)
            return ColumnType.time(ColumnType.TemporalColumnType.DEFAULT_PRECISION);
        else if (cls == LocalDateTime.class)
            return ColumnType.datetime(ColumnType.TemporalColumnType.DEFAULT_PRECISION);
        else if (cls == Instant.class)
            return ColumnType.timestamp(ColumnType.TemporalColumnType.DEFAULT_PRECISION);

        // Other types
        else if (cls == String.class)
            return ColumnType.string();
        else if (cls == UUID.class)
            return ColumnType.UUID;
        else if (cls == BigInteger.class)
            return ColumnType.numberOf();
        else if (cls == BigDecimal.class)
            return ColumnType.decimalOf();

        return null;
    }

}
