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

import java.util.List;

import org.apache.cassandra.config.ColumnDefinition;
import org.apache.cassandra.cql3.Operator;
import org.apache.cassandra.cql3.Term;
import org.apache.cassandra.cql3.functions.Function;
import org.apache.cassandra.cql3.statements.Bound;
import org.apache.cassandra.index.Index;

public final class TermSlice
{
    /**
     * The slice boundaries.
     */
    private final Term[] bounds;

    /**
     * Specifies if a slice boundary is inclusive or not.
     */
    private final boolean[] boundInclusive;

    /**
     * Creates a new <code>TermSlice</code> with the specified boundaries.
     *
     * @param start the lower boundary
     * @param includeStart <code>true</code> if the lower boundary is inclusive
     * @param end the upper boundary
     * @param includeEnd <code>true</code> if the upper boundary is inclusive
     */
    private TermSlice(Term start, boolean includeStart, Term end, boolean includeEnd)
    {
        bounds = new Term[]{start, end};
        boundInclusive = new boolean[]{includeStart, includeEnd};
    }

    /**
     * Creates a new <code>TermSlice</code> with the specified boundary.
     *
     * @param bound the boundary type
     * @param include <code>true</code> if the boundary is inclusive
     * @param term the value
     * @return a new <code>TermSlice</code> instance
     */
    public static TermSlice newInstance(Bound bound, boolean include, Term term)
    {
        return  bound.isStart() ? new TermSlice(term, include, null, false) 
                                : new TermSlice(null, false, term, include);
    }

    /**
     * Returns the boundary value.
     *
     * @param bound the boundary type
     * @return the boundary value
     */
    public Term bound(Bound bound)
    {
        return bounds[bound.idx];
    }

    /**
     * Checks if this slice has a boundary for the specified type.
     *
     * @param b the boundary type
     * @return <code>true</code> if this slice has a boundary for the specified type, <code>false</code> otherwise.
     */
    public boolean hasBound(Bound b)
    {
        return bounds[b.idx] != null;
    }

    /**
     * Checks if this slice boundary is inclusive for the specified type.
     *
     * @param b the boundary type
     * @return <code>true</code> if this slice boundary is inclusive for the specified type,
     * <code>false</code> otherwise.
     */
    public boolean isInclusive(Bound b)
    {
        return bounds[b.idx] == null || boundInclusive[b.idx];
    }

    /**
     * Merges this slice with the specified one.
     *
     * @param otherSlice the slice to merge to
     * @return the new slice resulting from the merge
     */
    public TermSlice merge(TermSlice otherSlice)
    {
        if (hasBound(Bound.START))
        {
            assert !otherSlice.hasBound(Bound.START);

            return new TermSlice(bound(Bound.START), 
                                  isInclusive(Bound.START),
                                  otherSlice.bound(Bound.END),
                                  otherSlice.isInclusive(Bound.END));
        }
        assert !otherSlice.hasBound(Bound.END);

        return new TermSlice(otherSlice.bound(Bound.START), 
                              otherSlice.isInclusive(Bound.START),
                              bound(Bound.END),
                              isInclusive(Bound.END));
    }

    @Override
    public String toString()
    {
        return String.format("(%s %s, %s %s)", boundInclusive[0] ? ">=" : ">",
                             bounds[0],
                             boundInclusive[1] ? "<=" : "<",
                             bounds[1]);
    }

    /**
     * Returns the index operator corresponding to the specified boundary.
     *
     * @param b the boundary type
     * @return the index operator corresponding to the specified boundary
     */
    public Operator getIndexOperator(Bound b)
    {
        if (b.isStart())
            return boundInclusive[b.idx] ? Operator.GTE : Operator.GT;

        return boundInclusive[b.idx] ? Operator.LTE : Operator.LT;
    }

    /**
     * Check if this <code>TermSlice</code> is supported by the specified index.
     *
     * @param index the secondary index
     * @return <code>true</code> this type of <code>TermSlice</code> is supported by the specified index,
     * <code>false</code> otherwise.
     */
    public boolean isSupportedBy(ColumnDefinition column, Index index)
    {
        boolean supported = false;

        if (hasBound(Bound.START))
            supported |= isInclusive(Bound.START) ? index.supportsExpression(column, Operator.GTE)
                    : index.supportsExpression(column, Operator.GT);
        if (hasBound(Bound.END))
            supported |= isInclusive(Bound.END) ? index.supportsExpression(column, Operator.LTE)
                    : index.supportsExpression(column, Operator.LT);

        return supported;
    }

    public void addFunctionsTo(List<Function> functions)
    {
        if (hasBound(Bound.START))
            bound(Bound.START).addFunctionsTo(functions);

        if (hasBound(Bound.END))
            bound(Bound.END).addFunctionsTo(functions);
    }
}
