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

import org.apache.tinkerpop.gremlin.process.traversal.Step;
import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
import org.apache.tinkerpop.gremlin.process.traversal.TraversalStrategy;
import org.apache.tinkerpop.gremlin.process.traversal.step.TraversalParent;
import org.apache.tinkerpop.gremlin.process.traversal.step.filter.ConnectiveStep;
import org.apache.tinkerpop.gremlin.process.traversal.step.filter.NotStep;
import org.apache.tinkerpop.gremlin.process.traversal.step.filter.RangeGlobalStep;
import org.apache.tinkerpop.gremlin.process.traversal.step.filter.TraversalFilterStep;
import org.apache.tinkerpop.gremlin.process.traversal.step.filter.WhereTraversalStep;
import org.apache.tinkerpop.gremlin.process.traversal.step.map.CountGlobalStep;
import org.apache.tinkerpop.gremlin.process.traversal.step.map.PropertiesStep;
import org.apache.tinkerpop.gremlin.process.traversal.step.map.VertexStep;
import org.apache.tinkerpop.gremlin.process.traversal.strategy.AbstractTraversalStrategy;
import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalHelper;
import org.apache.tinkerpop.gremlin.structure.Edge;
import org.apache.tinkerpop.gremlin.structure.PropertyType;

import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * This strategy looks for vertex- and value-emitting steps followed by a {@link CountGlobalStep} and replaces the
 * pattern with an edge- or property-emitting step followed by a {@link CountGlobalStep}. Furthermore, if a vertex-
 * or value-emitting step is the last step in a {@code .has(traversal)}, {@code .and(traversal, ...)} or
 * {@code .or(traversal, ...)} child traversal, it is replaced by an appropriate edge- or property-emitting step.
 * Performing this replacement removes situations where the more expensive trip to an adjacent graph element (e.g.
 * the vertex on the other side of an edge) can be satisfied by trips to incident graph elements (e.g. just the edge
 * itself).
 *
 * @author Daniel Kuppitz (http://gremlin.guru)
 * @example <pre>
 * __.out().count()            // is replaced by __.outE().count()
 * __.in().limit(3).count()    // is replaced by __.inE().limit(3).count()
 * __.values("name").count()   // is replaced by __.properties("name").count()
 * __.where(__.out())          // is replaced by __.where(__.outE())
 * __.where(__.values())       // is replaced by __.where(__.properties())
 * __.and(__.in(), __.out())   // is replaced by __.and(__.inE(), __.outE())
 * </pre>
 */
public final class AdjacentToIncidentStrategy extends AbstractTraversalStrategy<TraversalStrategy.OptimizationStrategy>
        implements TraversalStrategy.OptimizationStrategy {

    private static final AdjacentToIncidentStrategy INSTANCE = new AdjacentToIncidentStrategy();
    private static final Set<Class<? extends OptimizationStrategy>> PRIORS = new HashSet<>(Arrays.asList(IdentityRemovalStrategy.class, IncidentToAdjacentStrategy.class));

    private AdjacentToIncidentStrategy() {
    }

    @Override
    public void apply(final Traversal.Admin<?, ?> traversal) {
        final List<Step> steps = traversal.getSteps();
        final int size = steps.size() - 1;
        Step prev = null;
        for (int i = 0; i <= size; i++) {
            final Step curr = steps.get(i);
            if (i == size && isOptimizable(curr)) {
                final TraversalParent parent = curr.getTraversal().getParent();
                if (parent instanceof NotStep || parent instanceof TraversalFilterStep || parent instanceof WhereTraversalStep || parent instanceof ConnectiveStep) {
                    optimizeStep(traversal, curr);
                }
            } else if (isOptimizable(prev)) {
                if (curr instanceof CountGlobalStep) {
                    optimizeStep(traversal, prev);
                }
            }
            if (!(curr instanceof RangeGlobalStep)) {
                prev = curr;
            }
        }
    }

    @Override
    public Set<Class<? extends OptimizationStrategy>> applyPrior() {
        return PRIORS;
    }

    /**
     * Checks whether a given step is optimizable or not.
     *
     * @param step the step to check
     * @return <code>true</code> if the step is optimizable, otherwise <code>false</code>
     */
    private static boolean isOptimizable(final Step step) {
        return ((step instanceof VertexStep && ((VertexStep) step).returnsVertex()) ||
                (step instanceof PropertiesStep && PropertyType.VALUE.equals(((PropertiesStep) step).getReturnType()))) && (step.getTraversal().getEndStep().getLabels().isEmpty() || step.getNextStep() instanceof CountGlobalStep);
    }

    /**
     * Optimizes the given step if possible. Basically this method converts <code>.out()</code> to <code>.outE()</code>
     * and <code>.values()</code> to <code>.properties()</code>.
     *
     * @param traversal the traversal that holds the given step
     * @param step      the step to replace
     */
    private static void optimizeStep(final Traversal.Admin traversal, final Step step) {
        final Step newStep;
        if (step instanceof VertexStep) {
            final VertexStep vs = (VertexStep) step;
            newStep = new VertexStep<>(traversal, Edge.class, vs.getDirection(), vs.getEdgeLabels());
        } else if (step instanceof PropertiesStep) {
            final PropertiesStep ps = (PropertiesStep) step;
            newStep = new PropertiesStep(traversal, PropertyType.PROPERTY, ps.getPropertyKeys());
        } else {
            return;
        }
        TraversalHelper.replaceStep(step, newStep, traversal);
    }

    public static AdjacentToIncidentStrategy instance() {
        return INSTANCE;
    }
}
