/*
 * 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.catalog.commands;

import static org.apache.ignite.internal.catalog.CatalogParamsValidationUtils.validateIdentifier;
import static org.apache.ignite.internal.catalog.commands.CatalogUtils.schemaOrThrow;
import static org.apache.ignite.internal.catalog.commands.CatalogUtils.tableOrThrow;
import static org.apache.ignite.internal.lang.IgniteStringFormatter.format;

import java.util.List;
import java.util.Objects;
import org.apache.ignite.internal.catalog.Catalog;
import org.apache.ignite.internal.catalog.CatalogCommand;
import org.apache.ignite.internal.catalog.CatalogValidationException;
import org.apache.ignite.internal.catalog.descriptors.CatalogSchemaDescriptor;
import org.apache.ignite.internal.catalog.descriptors.CatalogTableColumnDescriptor;
import org.apache.ignite.internal.catalog.descriptors.CatalogTableDescriptor;
import org.apache.ignite.internal.catalog.storage.AlterColumnEntry;
import org.apache.ignite.internal.catalog.storage.UpdateEntry;
import org.apache.ignite.sql.ColumnType;
import org.jetbrains.annotations.Nullable;

/**
 * A command that changes a column in a particular table.
 */
public class AlterTableAlterColumnCommand extends AbstractTableCommand {
    /** Returns command that changes a column in a particular table. */
    public static AlterTableAlterColumnCommandBuilder builder() {
        return new Builder();
    }

    private static final TypeChangeValidationListener TYPE_CHANGE_VALIDATION_HANDLER = (pattern, originalType, newType) -> {
        throw new CatalogValidationException(format(pattern, originalType, newType));
    };

    private final String columnName;

    private final @Nullable ColumnType type;

    private final @Nullable Integer precision;

    private final @Nullable Integer length;

    private final @Nullable Integer scale;

    private final @Nullable Boolean nullable;

    private final @Nullable DeferredDefaultValue deferredDefault;

    private AlterTableAlterColumnCommand(
            String tableName,
            String schemaName,
            boolean ifTableExists,
            String columnName,
            @Nullable ColumnType type,
            @Nullable Integer precision,
            @Nullable Integer length,
            @Nullable Integer scale,
            @Nullable Boolean nullable,
            @Nullable DeferredDefaultValue deferredDefault
    ) {
        super(schemaName, tableName, ifTableExists);

        this.columnName = columnName;
        this.type = type;
        this.precision = precision;
        this.length = length;
        this.scale = scale;
        this.nullable = nullable;
        this.deferredDefault = deferredDefault;

        validate();
    }

    @Override
    public List<UpdateEntry> get(Catalog catalog) {
        CatalogSchemaDescriptor schema = schemaOrThrow(catalog, schemaName);

        CatalogTableDescriptor table = tableOrThrow(schema, tableName);

        CatalogTableColumnDescriptor origin = table.column(columnName);

        if (origin == null) {
            throw new CatalogValidationException(format(
                    "Column with name '{}' not found in table '{}.{}'", columnName, schemaName, tableName));
        }

        if (table.isPrimaryKeyColumn(origin.name())) {
            validatePkColumnChange(origin);
        } else {
            validateValueColumnChange(origin);
        }

        validateColumnChange(origin);

        CatalogTableColumnDescriptor target = createNewTableColumn(origin);

        if (origin.equals(target)) {
            // No modifications required.
            return List.of();
        }

        return List.of(
                new AlterColumnEntry(table.id(), target)
        );
    }

    private void validate() {
        validateIdentifier(columnName, "Name of the column");
    }

    private CatalogTableColumnDescriptor createNewTableColumn(CatalogTableColumnDescriptor origin) {
        return new CatalogTableColumnDescriptor(
                origin.name(),
                Objects.requireNonNullElse(type, origin.type()),
                Objects.requireNonNullElse(nullable, origin.nullable()),
                Objects.requireNonNullElse(precision, origin.precision()),
                Objects.requireNonNullElse(scale, origin.scale()),
                Objects.requireNonNullElse(length, origin.length()),
                deferredDefault != null ? deferredDefault.derive(origin.type()) : origin.defaultValue()
        );
    }

    private void validatePkColumnChange(CatalogTableColumnDescriptor origin) {
        if (type != null && type != origin.type()) {
            throw new CatalogValidationException("Changing the type of key column is not allowed");
        }
        if (precision != null && precision != origin.precision()) {
            throw new CatalogValidationException("Changing the precision of key column is not allowed");
        }
        if (scale != null && scale != origin.scale()) {
            throw new CatalogValidationException("Changing the scale of key column is not allowed");
        }
        if (nullable != null && nullable) {
            throw new CatalogValidationException("Dropping NOT NULL constraint on key column is not allowed");
        }
        if (deferredDefault != null) {
            DefaultValue defaultValue = deferredDefault.derive(origin.type());

            CatalogUtils.ensureSupportedDefault(columnName, defaultValue);
        }
    }

    private void validateValueColumnChange(CatalogTableColumnDescriptor origin) {
        if (deferredDefault != null) {
            DefaultValue defaultValue = deferredDefault.derive(origin.type());

            CatalogUtils.ensureNonFunctionalDefault(columnName, defaultValue);
        }
    }

    private void validateColumnChange(CatalogTableColumnDescriptor origin) {
        CatalogUtils.validateColumnChange(origin, type, precision, scale, length, TYPE_CHANGE_VALIDATION_HANDLER);

        if (nullable != null && !nullable && origin.nullable()) {
            throw new CatalogValidationException("Adding NOT NULL constraint is not allowed");
        }
    }

    private static class Builder implements AlterTableAlterColumnCommandBuilder {
        private String tableName;
        private String schemaName;
        private boolean ifTableExists;
        private String columnName;
        private @Nullable ColumnType type;
        private @Nullable Integer precision;
        private @Nullable Integer length;
        private @Nullable Integer scale;
        private @Nullable Boolean nullable;
        private @Nullable DeferredDefaultValue deferredDefault;

        @Override
        public Builder tableName(String tableName) {
            this.tableName = tableName;

            return this;
        }

        @Override
        public Builder schemaName(String schemaName) {
            this.schemaName = schemaName;

            return this;
        }

        @Override
        public AlterTableAlterColumnCommandBuilder ifTableExists(boolean ifTableExists) {
            this.ifTableExists = ifTableExists;

            return this;
        }

        @Override
        public Builder columnName(String columnName) {
            this.columnName = columnName;

            return this;
        }

        @Override
        public Builder type(ColumnType type) {
            this.type = type;

            return this;
        }

        @Override
        public Builder precision(int precision) {
            this.precision = precision;

            return this;
        }

        @Override
        public Builder length(int length) {
            this.length = length;

            return this;
        }

        @Override
        public Builder scale(int scale) {
            this.scale = scale;

            return this;
        }

        @Override
        public Builder nullable(boolean nullable) {
            this.nullable = nullable;
            return this;
        }

        @Override
        public Builder deferredDefaultValue(DeferredDefaultValue deferredDefault) {
            this.deferredDefault = deferredDefault;

            return this;
        }

        @Override
        public CatalogCommand build() {
            return new AlterTableAlterColumnCommand(
                    tableName,
                    schemaName,
                    ifTableExists,
                    columnName,
                    type,
                    precision,
                    length,
                    scale,
                    nullable,
                    deferredDefault
            );
        }
    }
}
