/*
 * 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.db.filter;

import java.io.IOException;

import org.apache.cassandra.db.*;
import org.apache.cassandra.db.partitions.CachedPartition;
import org.apache.cassandra.db.partitions.Partition;
import org.apache.cassandra.db.rows.*;
import org.apache.cassandra.io.sstable.format.SSTableReader;
import org.apache.cassandra.io.util.DataInputPlus;
import org.apache.cassandra.io.util.DataOutputPlus;
import org.apache.cassandra.schema.TableMetadata;

/**
 * A filter that selects a subset of the rows of a given partition by using the "clustering index".
 * <p>
 * In CQL terms, this correspond to the clustering columns selection and correspond to what
 * the storage engine can do without filtering (and without 2ndary indexes). This does not include
 * the restrictions on non-PK columns which can be found in {@link RowFilter}.
 */
public interface ClusteringIndexFilter
{
    public static final Serializer serializer = AbstractClusteringIndexFilter.serializer;

    public enum Kind
    {
        SLICE (ClusteringIndexSliceFilter.deserializer),
        NAMES (ClusteringIndexNamesFilter.deserializer);

        protected final InternalDeserializer deserializer;

        private Kind(InternalDeserializer deserializer)
        {
            this.deserializer = deserializer;
        }
    }

    static interface InternalDeserializer
    {
        public ClusteringIndexFilter deserialize(DataInputPlus in, int version, TableMetadata metadata, boolean reversed) throws IOException;
    }

    /**
     * Whether the filter query rows in reversed clustering order or not.
     *
     * @return whether the filter query rows in reversed clustering order or not.
     */
    public boolean isReversed();

    public boolean isEmpty(ClusteringComparator comparator);

    /**
     * Returns a filter for continuing the paging of this filter given the last returned clustering prefix.
     *
     * @param comparator the comparator for the table this is a filter for.
     * @param lastReturned the last clustering that was returned for the query we are paging for. The
     * resulting filter will be such that results coming after {@code lastReturned} are returned
     * (where coming after means "greater than" if the filter is not reversed, "lesser than" otherwise;
     * futher, whether the comparison is strict or not depends on {@code inclusive}).
     * @param inclusive whether or not we want to include the {@code lastReturned} in the newly returned
     * page of results.
     *
     * @return a new filter that selects results coming after {@code lastReturned}.
     */
    public ClusteringIndexFilter forPaging(ClusteringComparator comparator, Clustering<?> lastReturned, boolean inclusive);

    /**
     * Returns whether we can guarantee that a given cached partition contains all the data selected by this filter.
     *
     * @param partition the cached partition. This method assumed that the rows of this partition contains all the table columns.
     *
     * @return whether we can guarantee that all data selected by this filter are in {@code partition}.
     */
    public boolean isFullyCoveredBy(CachedPartition partition);

    /**
     * Whether this filter selects the head of a partition (i.e. it isn't reversed and selects all rows up to a certain point).
     *
     * @return whether this filter selects the head of a partition.
     */
    public boolean isHeadFilter();

    /**
     * Whether this filter selects all the row of a partition (it's an "identity" filter).
     *
     * @return whether this filter selects all the row of a partition (it's an "identity" filter).
     */
    public boolean selectsAllPartition();

    /**
     * Whether a given row is selected by this filter.
     *
     * @param clustering the clustering of the row to test the selection of.
     *
     * @return whether the row with clustering {@code clustering} is selected by this filter.
     */
    public boolean selects(Clustering<?> clustering);

    /**
     * Returns an iterator that only returns the rows of the provided iterator that this filter selects.
     * <p>
     * This method is the "dumb" counterpart to {@link #getSlices(TableMetadata)} in that it has no way to quickly get
     * to what is actually selected, so it simply iterate over it all and filters out what shouldn't be returned. This should
     * be avoided in general.
     * Another difference with {@link #getSlices(TableMetadata)} is that this method also filter the queried
     * columns in the returned result, while the former assumes that the provided iterator has already done it.
     *
     * @param columnFilter the columns to include in the rows of the result iterator.
     * @param iterator the iterator for which we should filter rows.
     *
     * @return an iterator that only returns the rows (or rather Unfilted) from {@code iterator} that are selected by this filter.
     */
    public UnfilteredRowIterator filterNotIndexed(ColumnFilter columnFilter, UnfilteredRowIterator iterator);

    public Slices getSlices(TableMetadata metadata);

    /**
     * Given a partition, returns a row iterator for the rows of this partition that are selected by this filter.
     *
     * @param columnFilter the columns to include in the rows of the result iterator.
     * @param partition the partition containing the rows to filter.
     *
     * @return a unfiltered row iterator returning those rows (or rather Unfiltered) from {@code partition} that are selected by this filter.
     */
    public UnfilteredRowIterator getUnfilteredRowIterator(ColumnFilter columnFilter, Partition partition);

    /**
     * Whether the provided sstable may contain data that is selected by this filter (based on the sstable metadata).
     *
     * @param sstable the sstable for which we want to test the need for inclusion.
     *
     * @return whether {@code sstable} should be included to answer this filter.
     */
    public boolean shouldInclude(SSTableReader sstable);

    public Kind kind();

    public String toString(TableMetadata metadata);
    public String toCQLString(TableMetadata metadata);

    public interface Serializer
    {
        public void serialize(ClusteringIndexFilter filter, DataOutputPlus out, int version) throws IOException;
        public ClusteringIndexFilter deserialize(DataInputPlus in, int version, TableMetadata metadata) throws IOException;
        public long serializedSize(ClusteringIndexFilter filter, int version);
    }
}
