/*
 * 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.cassandra.cql3.statements;

import java.util.*;
import java.util.stream.Collectors;

import com.google.common.collect.Iterables;

import org.apache.cassandra.auth.Permission;
import org.apache.cassandra.config.*;
import org.apache.cassandra.cql3.CFName;
import org.apache.cassandra.cql3.CQL3Type;
import org.apache.cassandra.cql3.ColumnIdentifier;
import org.apache.cassandra.db.ColumnFamilyStore;
import org.apache.cassandra.db.Keyspace;
import org.apache.cassandra.db.marshal.AbstractType;
import org.apache.cassandra.db.marshal.CollectionType;
import org.apache.cassandra.db.marshal.CounterColumnType;
import org.apache.cassandra.db.marshal.ReversedType;
import org.apache.cassandra.db.view.View;
import org.apache.cassandra.exceptions.*;
import org.apache.cassandra.schema.IndexMetadata;
import org.apache.cassandra.schema.Indexes;
import org.apache.cassandra.schema.TableParams;
import org.apache.cassandra.service.ClientState;
import org.apache.cassandra.service.MigrationManager;
import org.apache.cassandra.transport.Event;

import static org.apache.cassandra.thrift.ThriftValidation.validateColumnFamily;

public class AlterTableStatement extends SchemaAlteringStatement
{
    public enum Type
    {
        ADD, ALTER, DROP, OPTS, RENAME
    }

    public final Type oType;
    private final TableAttributes attrs;
    private final Map<ColumnDefinition.Raw, ColumnDefinition.Raw> renames;
    private final List<AlterTableStatementColumn> colNameList;

    public AlterTableStatement(CFName name,
                               Type type,
                               List<AlterTableStatementColumn> colDataList,
                               TableAttributes attrs,
                               Map<ColumnDefinition.Raw, ColumnDefinition.Raw> renames)
    {
        super(name);
        this.oType = type;
        this.colNameList = colDataList;
        this.attrs = attrs;
        this.renames = renames;
    }

    public void checkAccess(ClientState state) throws UnauthorizedException, InvalidRequestException
    {
        state.hasColumnFamilyAccess(keyspace(), columnFamily(), Permission.ALTER);
    }

    public void validate(ClientState state)
    {
        // validated in announceMigration()
    }

    public Event.SchemaChange announceMigration(boolean isLocalOnly) throws RequestValidationException
    {
        CFMetaData meta = validateColumnFamily(keyspace(), columnFamily());
        if (meta.isView())
            throw new InvalidRequestException("Cannot use ALTER TABLE on Materialized View");

        CFMetaData cfm = meta.copy();
        ColumnIdentifier columnName = null;
        ColumnDefinition def = null;
        CQL3Type.Raw dataType = null;
        boolean isStatic = false;
        CQL3Type validator = null;
        ColumnDefinition.Raw rawColumnName = null;

        List<ViewDefinition> viewUpdates = null;
        Iterable<ViewDefinition> views = View.findAll(keyspace(), columnFamily());

        switch (oType)
        {
            case ADD:
                for (AlterTableStatementColumn colData : colNameList)
                {
                    rawColumnName = colData.getColumnName();
                    if (rawColumnName != null)
                    {
                        columnName = rawColumnName.getIdentifier(cfm);
                        def =  cfm.getColumnDefinition(columnName);
                        dataType = colData.getColumnType();
                        isStatic = colData.getStaticType();
                        validator = dataType == null ? null : dataType.prepare(keyspace());
                    }

                    assert columnName != null;
                    if (cfm.isDense())
                        throw new InvalidRequestException("Cannot add new column to a COMPACT STORAGE table");

                    if (isStatic)
                    {
                        if (!cfm.isCompound())
                            throw new InvalidRequestException("Static columns are not allowed in COMPACT STORAGE tables");
                        if (cfm.clusteringColumns().isEmpty())
                            throw new InvalidRequestException("Static columns are only useful (and thus allowed) if the table has at least one clustering column");
                    }

                    if (def != null)
                    {
                        switch (def.kind)
                        {
                            case PARTITION_KEY:
                            case CLUSTERING:
                                throw new InvalidRequestException(String.format("Invalid column name %s because it conflicts with a PRIMARY KEY part", columnName));
                            default:
                                throw new InvalidRequestException(String.format("Invalid column name %s because it conflicts with an existing column", columnName));
                        }
                    }

                    // Cannot re-add a dropped counter column. See #7831.
                    if (meta.isCounter() && meta.getDroppedColumns().containsKey(columnName.bytes))
                        throw new InvalidRequestException(String.format("Cannot re-add previously dropped counter column %s", columnName));

                    AbstractType<?> type = validator.getType();
                    if (type.isCollection() && type.isMultiCell())
                    {
                        if (!cfm.isCompound())
                            throw new InvalidRequestException("Cannot use non-frozen collections in COMPACT STORAGE tables");
                        if (cfm.isSuper())
                            throw new InvalidRequestException("Cannot use non-frozen collections with super column families");

                        // If there used to be a non-frozen collection column with the same name (that has been dropped),
                        // we could still have some data using the old type, and so we can't allow adding a collection
                        // with the same name unless the types are compatible (see #6276).
                        CFMetaData.DroppedColumn dropped = cfm.getDroppedColumns().get(columnName.bytes);
                        if (dropped != null && dropped.type instanceof CollectionType
                            && dropped.type.isMultiCell() && !type.isCompatibleWith(dropped.type))
                        {
                            String message =
                                String.format("Cannot add a collection with the name %s because a collection with the same name"
                                              + " and a different type (%s) has already been used in the past",
                                              columnName,
                                              dropped.type.asCQL3Type());
                            throw new InvalidRequestException(message);
                        }
                    }

                    cfm.addColumnDefinition(isStatic
                                            ? ColumnDefinition.staticDef(cfm, columnName.bytes, type)
                                            : ColumnDefinition.regularDef(cfm, columnName.bytes, type));

                    // Adding a column to a table which has an include all view requires the column to be added to the view
                    // as well
                    if (!isStatic)
                    {
                        for (ViewDefinition view : views)
                        {
                            if (view.includeAllColumns)
                            {
                                ViewDefinition viewCopy = view.copy();
                                viewCopy.metadata.addColumnDefinition(ColumnDefinition.regularDef(viewCopy.metadata, columnName.bytes, type));
                                if (viewUpdates == null)
                                    viewUpdates = new ArrayList<>();
                                viewUpdates.add(viewCopy);
                            }
                        }
                    }
                }
                break;

            case ALTER:
                rawColumnName = colNameList.get(0).getColumnName();
                if (rawColumnName != null)
                {
                    columnName = rawColumnName.getIdentifier(cfm);
                    def = cfm.getColumnDefinition(columnName);
                    dataType = colNameList.get(0).getColumnType();
                    validator = dataType == null ? null : dataType.prepare(keyspace());
                }

                assert columnName != null;
                if (def == null)
                    throw new InvalidRequestException(String.format("Column %s was not found in table %s", columnName, columnFamily()));

                AbstractType<?> validatorType = def.isReversedType() && !validator.getType().isReversed()
                                                ? ReversedType.getInstance(validator.getType())
                                                : validator.getType();
                validateAlter(cfm, def, validatorType);
                // In any case, we update the column definition
                cfm.addOrReplaceColumnDefinition(def.withNewType(validatorType));

                // We also have to validate the view types here. If we have a view which includes a column as part of
                // the clustering key, we need to make sure that it is indeed compatible.
                for (ViewDefinition view : views)
                {
                    if (!view.includes(columnName)) continue;
                    ViewDefinition viewCopy = view.copy();
                    ColumnDefinition viewDef = view.metadata.getColumnDefinition(columnName);
                    AbstractType viewType = viewDef.isReversedType() && !validator.getType().isReversed()
                                            ? ReversedType.getInstance(validator.getType())
                                            : validator.getType();
                    validateAlter(view.metadata, viewDef, viewType);
                    viewCopy.metadata.addOrReplaceColumnDefinition(viewDef.withNewType(viewType));

                    if (viewUpdates == null)
                        viewUpdates = new ArrayList<>();
                    viewUpdates.add(viewCopy);
                }
                break;

            case DROP:
                for (AlterTableStatementColumn colData : colNameList)
                {
                    columnName = null;
                    rawColumnName = colData.getColumnName();
                    if (rawColumnName != null)
                    {
                        columnName = rawColumnName.getIdentifier(cfm);
                        def = cfm.getColumnDefinition(columnName);
                    }
                    assert columnName != null;
                    if (!cfm.isCQLTable())
                        throw new InvalidRequestException("Cannot drop columns from a non-CQL3 table");
                    if (def == null)
                        throw new InvalidRequestException(String.format("Column %s was not found in table %s", columnName, columnFamily()));

                    switch (def.kind)
                    {
                         case PARTITION_KEY:
                         case CLUSTERING:
                              throw new InvalidRequestException(String.format("Cannot drop PRIMARY KEY part %s", columnName));
                         case REGULAR:
                         case STATIC:
                              ColumnDefinition toDelete = null;
                              for (ColumnDefinition columnDef : cfm.partitionColumns())
                              {
                                   if (columnDef.name.equals(columnName))
                                      {
                                        toDelete = columnDef;
                                        break;
                                      }
                               }
                        assert toDelete != null;
                        cfm.removeColumnDefinition(toDelete);
                        cfm.recordColumnDrop(toDelete);
                        break;
                    }

                    // If the dropped column is required by any secondary indexes
                    // we reject the operation, as the indexes must be dropped first
                    Indexes allIndexes = cfm.getIndexes();
                    if (!allIndexes.isEmpty())
                    {
                        ColumnFamilyStore store = Keyspace.openAndGetStore(cfm);
                        Set<IndexMetadata> dependentIndexes = store.indexManager.getDependentIndexes(def);
                        if (!dependentIndexes.isEmpty())
                            throw new InvalidRequestException(String.format("Cannot drop column %s because it has " +
                                                                            "dependent secondary indexes (%s)",
                                                                            def,
                                                                            dependentIndexes.stream()
                                                                                            .map(i -> i.name)
                                                                                            .collect(Collectors.joining(","))));
                    }

                    // If a column is dropped which is included in a view, we don't allow the drop to take place.
                    boolean rejectAlter = false;
                    StringBuilder builder = new StringBuilder();
                    for (ViewDefinition view : views)
                    {
                        if (!view.includes(columnName)) continue;
                        if (rejectAlter)
                            builder.append(',');
                        rejectAlter = true;
                        builder.append(view.viewName);
                    }
                    if (rejectAlter)
                        throw new InvalidRequestException(String.format("Cannot drop column %s, depended on by materialized views (%s.{%s})",
                                                                        columnName.toString(),
                                                                        keyspace(),
                                                                        builder.toString()));
                }
                break;
            case OPTS:
                if (attrs == null)
                    throw new InvalidRequestException("ALTER TABLE WITH invoked, but no parameters found");
                attrs.validate();

                TableParams params = attrs.asAlteredTableParams(cfm.params);

                if (!Iterables.isEmpty(views) && params.gcGraceSeconds == 0)
                {
                    throw new InvalidRequestException("Cannot alter gc_grace_seconds of the base table of a " +
                                                      "materialized view to 0, since this value is used to TTL " +
                                                      "undelivered updates. Setting gc_grace_seconds too low might " +
                                                      "cause undelivered updates to expire " +
                                                      "before being replayed.");
                }

                if (meta.isCounter() && params.defaultTimeToLive > 0)
                    throw new InvalidRequestException("Cannot set default_time_to_live on a table with counters");

                cfm.params(params);

                break;
            case RENAME:
                for (Map.Entry<ColumnDefinition.Raw, ColumnDefinition.Raw> entry : renames.entrySet())
                {
                    ColumnIdentifier from = entry.getKey().getIdentifier(cfm);
                    ColumnIdentifier to = entry.getValue().getIdentifier(cfm);
                    cfm.renameColumn(from, to);

                    // If the view includes a renamed column, it must be renamed in the view table and the definition.
                    for (ViewDefinition view : views)
                    {
                        if (!view.includes(from)) continue;

                        ViewDefinition viewCopy = view.copy();
                        ColumnIdentifier viewFrom = entry.getKey().getIdentifier(viewCopy.metadata);
                        ColumnIdentifier viewTo = entry.getValue().getIdentifier(viewCopy.metadata);
                        viewCopy.renameColumn(viewFrom, viewTo);

                        if (viewUpdates == null)
                            viewUpdates = new ArrayList<>();
                        viewUpdates.add(viewCopy);
                    }
                }
                break;
        }

        MigrationManager.announceColumnFamilyUpdate(cfm, isLocalOnly);

        if (viewUpdates != null)
        {
            for (ViewDefinition viewUpdate : viewUpdates)
                MigrationManager.announceViewUpdate(viewUpdate, isLocalOnly);
        }
        return new Event.SchemaChange(Event.SchemaChange.Change.UPDATED, Event.SchemaChange.Target.TABLE, keyspace(), columnFamily());
    }

    private static void validateAlter(CFMetaData cfm, ColumnDefinition def, AbstractType<?> validatorType)
    {
        switch (def.kind)
        {
            case PARTITION_KEY:
                if (validatorType instanceof CounterColumnType)
                    throw new InvalidRequestException(String.format("counter type is not supported for PRIMARY KEY part %s", def.name));

                AbstractType<?> currentType = cfm.getKeyValidatorAsClusteringComparator().subtype(def.position());
                if (!validatorType.isValueCompatibleWith(currentType))
                    throw new ConfigurationException(String.format("Cannot change %s from type %s to type %s: types are incompatible.",
                                                                   def.name,
                                                                   currentType.asCQL3Type(),
                                                                   validatorType.asCQL3Type()));
                break;
            case CLUSTERING:
                if (!cfm.isCQLTable())
                    throw new InvalidRequestException(String.format("Cannot alter clustering column %s in a non-CQL3 table", def.name));

                AbstractType<?> oldType = cfm.comparator.subtype(def.position());
                // Note that CFMetaData.validateCompatibility already validate the change we're about to do. However, the error message it
                // sends is a bit cryptic for a CQL3 user, so validating here for a sake of returning a better error message
                // Do note that we need isCompatibleWith here, not just isValueCompatibleWith.
                if (!validatorType.isCompatibleWith(oldType))
                {
                    throw new ConfigurationException(String.format("Cannot change %s from type %s to type %s: types are not order-compatible.",
                                                                   def.name,
                                                                   oldType.asCQL3Type(),
                                                                   validatorType.asCQL3Type()));
                }
                break;
            case REGULAR:
            case STATIC:
                // Thrift allows to change a column validator so CFMetaData.validateCompatibility will let it slide
                // if we change to an incompatible type (contrarily to the comparator case). But we don't want to
                // allow it for CQL3 (see #5882) so validating it explicitly here. We only care about value compatibility
                // though since we won't compare values (except when there is an index, but that is validated by
                // ColumnDefinition already).
                if (!validatorType.isValueCompatibleWith(def.type))
                    throw new ConfigurationException(String.format("Cannot change %s from type %s to type %s: types are incompatible.",
                                                                   def.name,
                                                                   def.type.asCQL3Type(),
                                                                   validatorType.asCQL3Type()));
                break;
        }
    }

    @Override
    public String toString()
    {
        return String.format("AlterTableStatement(name=%s, type=%s)",
                             cfName,
                             oType);
    }
}
