/*
 * 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 {@code 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.
 * <p/>
 *
 * @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;
    }
}
