/*
 * 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.tinkerpop.gremlin.process.traversal;

import org.apache.commons.configuration.BaseConfiguration;
import org.apache.commons.configuration.Configuration;
import org.apache.tinkerpop.gremlin.process.traversal.strategy.decoration.PartitionStrategy;
import org.apache.tinkerpop.gremlin.process.traversal.strategy.finalization.ProfileStrategy;
import org.apache.tinkerpop.gremlin.process.traversal.strategy.optimization.CountStrategy;
import org.apache.tinkerpop.gremlin.process.traversal.strategy.verification.LambdaRestrictionStrategy;

import java.io.Serializable;
import java.util.Collections;
import java.util.Set;

/**
 * A {@link TraversalStrategy} defines a particular atomic operation for mutating a {@link Traversal} prior to its evaluation.
 * There are 5 pre-defined "traversal categories": {@link DecorationStrategy}, {@link OptimizationStrategy}, {@link ProviderOptimizationStrategy}, {@link FinalizationStrategy}, and {@link VerificationStrategy}.
 * Strategies within a category are sorted amongst themselves and then category sorts are applied in the ordered specified previous.
 * That is, decorations are applied, then optimizations, then provider optimizations, then finalizations, and finally, verifications.
 * If a strategy does not fit within the specified categories, then it can simply implement {@link TraversalStrategy} and can have priors/posts that span categories.
 * <p/>
 * A traversal strategy should be a final class as various internal operations on a strategy are based on its ability to be assigned to more general classes.
 * A traversal strategy should typically be stateless with a public static <code>instance()</code> method.
 * However, at limit, a traversal strategy can have a state defining constructor (typically via a "builder"), but that state can not mutate once instantiated.
 *
 * @author Marko A. Rodriguez (http://markorodriguez.com)
 * @author Matthias Broecheler (me@matthiasb.com)
 */
public interface TraversalStrategy<S extends TraversalStrategy> extends Serializable, Comparable<Class<? extends TraversalStrategy>> {

    public static final String STRATEGY = "strategy";

    public void apply(final Traversal.Admin<?, ?> traversal);

    /**
     * The set of strategies that must be executed before this strategy is executed.
     * If there are no ordering requirements, the default implementation returns an empty set.
     *
     * @return the set of strategies that must be executed prior to this one.
     */
    public default Set<Class<? extends S>> applyPrior() {
        return Collections.emptySet();
    }

    /**
     * The set of strategies that must be executed after this strategy is executed.
     * If there are no ordering requirements, the default implementation returns an empty set.
     *
     * @return the set of strategies that must be executed post this one
     */
    public default Set<Class<? extends S>> applyPost() {
        return Collections.emptySet();
    }

    /**
     * The type of traversal strategy -- i.e. {@link DecorationStrategy}, {@link OptimizationStrategy}, {@link FinalizationStrategy}, or {@link VerificationStrategy}.
     *
     * @return the traversal strategy category class
     */
    public default Class<S> getTraversalCategory() {
        return (Class) TraversalStrategy.class;
    }

    /**
     * Get the configuration representation of this strategy.
     * This is useful for converting a strategy into a serialized form.
     *
     * @return the configuration used to create this strategy
     */
    public default Configuration getConfiguration() {
        return new BaseConfiguration();
    }

    @Override
    public default int compareTo(final Class<? extends TraversalStrategy> otherTraversalCategory) {
        return 0;
    }

    /**
     * Implemented by strategies that adds "application logic" to the traversal (e.g. {@link PartitionStrategy}).
     */
    public interface DecorationStrategy extends TraversalStrategy<DecorationStrategy> {

        @Override
        public default Class<DecorationStrategy> getTraversalCategory() {
            return DecorationStrategy.class;
        }

        @Override
        public default int compareTo(final Class<? extends TraversalStrategy> otherTraversalCategory) {
            if (otherTraversalCategory.equals(DecorationStrategy.class))
                return 0;
            else if (otherTraversalCategory.equals(OptimizationStrategy.class))
                return -1;
            else if (otherTraversalCategory.equals(ProviderOptimizationStrategy.class))
                return -1;
            else if (otherTraversalCategory.equals(FinalizationStrategy.class))
                return -1;
            else if (otherTraversalCategory.equals(VerificationStrategy.class))
                return -1;
            else
                return 0;
        }
    }

    /**
     * Implemented by strategies that rewrite the traversal to be more efficient, but with the same semantics
     * (e.g. {@link CountStrategy}). During a re-write ONLY TinkerPop steps should be used.
     * For strategies that utilize provider specific steps, use {@link ProviderOptimizationStrategy}.
     */
    public interface OptimizationStrategy extends TraversalStrategy<OptimizationStrategy> {

        @Override
        public default Class<OptimizationStrategy> getTraversalCategory() {
            return OptimizationStrategy.class;
        }

        @Override
        public default int compareTo(final Class<? extends TraversalStrategy> otherTraversalCategory) {
            if (otherTraversalCategory.equals(DecorationStrategy.class))
                return 1;
            else if (otherTraversalCategory.equals(OptimizationStrategy.class))
                return 0;
            else if (otherTraversalCategory.equals(ProviderOptimizationStrategy.class))
                return -1;
            else if (otherTraversalCategory.equals(FinalizationStrategy.class))
                return -1;
            else if (otherTraversalCategory.equals(VerificationStrategy.class))
                return -1;
            else
                return 0;
        }
    }

    /**
     * Implemented by strategies that rewrite the traversal to be more efficient, but with the same semantics.
     * This is for graph system/language/driver providers that want to rewrite a traversal using provider specific steps.
     */
    public interface ProviderOptimizationStrategy extends TraversalStrategy<ProviderOptimizationStrategy> {

        @Override
        public default Class<ProviderOptimizationStrategy> getTraversalCategory() {
            return ProviderOptimizationStrategy.class;
        }

        @Override
        public default int compareTo(final Class<? extends TraversalStrategy> otherTraversalCategory) {
            if (otherTraversalCategory.equals(DecorationStrategy.class))
                return 1;
            else if (otherTraversalCategory.equals(OptimizationStrategy.class))
                return 1;
            else if (otherTraversalCategory.equals(ProviderOptimizationStrategy.class))
                return 0;
            else if (otherTraversalCategory.equals(FinalizationStrategy.class))
                return -1;
            else if (otherTraversalCategory.equals(VerificationStrategy.class))
                return -1;
            else
                return 0;
        }
    }

    /**
     * Implemented by strategies that do final behaviors that require a fully compiled traversal to work (e.g.
     * {@link ProfileStrategy}).
     */
    public interface FinalizationStrategy extends TraversalStrategy<FinalizationStrategy> {

        @Override
        public default Class<FinalizationStrategy> getTraversalCategory() {
            return FinalizationStrategy.class;
        }

        @Override
        public default int compareTo(final Class<? extends TraversalStrategy> otherTraversalCategory) {
            if (otherTraversalCategory.equals(DecorationStrategy.class))
                return 1;
            else if (otherTraversalCategory.equals(OptimizationStrategy.class))
                return 1;
            else if (otherTraversalCategory.equals(ProviderOptimizationStrategy.class))
                return 1;
            else if (otherTraversalCategory.equals(FinalizationStrategy.class))
                return 0;
            else if (otherTraversalCategory.equals(VerificationStrategy.class))
                return -1;
            else
                return 0;
        }
    }

    /**
     * Implemented by strategies where there is no more behavioral tweaking of the traversal required.  Strategies that
     * implement this category will simply analyze the traversal and throw exceptions if the traversal is not correct
     * for the execution context (e.g. {@link LambdaRestrictionStrategy}).
     */
    public interface VerificationStrategy extends TraversalStrategy<VerificationStrategy> {

        @Override
        public default Class<VerificationStrategy> getTraversalCategory() {
            return VerificationStrategy.class;
        }

        @Override
        public default int compareTo(final Class<? extends TraversalStrategy> otherTraversalCategory) {
            if (otherTraversalCategory.equals(DecorationStrategy.class))
                return 1;
            else if (otherTraversalCategory.equals(OptimizationStrategy.class))
                return 1;
            else if (otherTraversalCategory.equals(ProviderOptimizationStrategy.class))
                return 1;
            else if (otherTraversalCategory.equals(FinalizationStrategy.class))
                return 1;
            else
                return 0;
        }
    }
}
