/*
 * 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.tinkerpop.gremlin.structure.util.Attachable;

import java.io.Serializable;
import java.util.Set;
import java.util.function.Function;

/**
 * A {@code Traverser} represents the current state of an object flowing through a {@link Traversal}.
 * A traverser maintains a reference to the current object, a traverser-local "sack", a traversal-global sideEffect,
 * a bulk count, and a path history.
 * <p/>
 * Different types of traversers can exist depending on the semantics of the traversal and the desire for
 * space/time optimizations of the developer.
 *
 * @author Marko A. Rodriguez (http://markorodriguez.com)
 */
public interface Traverser<T> extends Serializable, Comparable<Traverser<T>>, Cloneable {

    /**
     * Get the object that the traverser is current at.
     *
     * @return The current object of the traverser
     */
    public T get();

    /**
     * Get the sack local sack object of this traverser.
     *
     * @param <S> the type of the sack object
     * @return the sack object
     */
    public <S> S sack();

    /**
     * Set the traversers sack object to the provided value ("sack the value").
     *
     * @param object the new value of the traverser's sack
     * @param <S>    the type of the object
     */
    public <S> void sack(final S object);

    /**
     * Get the current path of the traverser.
     *
     * @return The path of the traverser
     */
    public Path path();

    /**
     * Get the object associated with the specified step-label in the traverser's path history.
     *
     * @param stepLabel the step-label in the path to access
     * @param <A>       the type of the object
     * @return the object associated with that path label (if more than one object occurs at that step, a list is returned)
     */
    public default <A> A path(final String stepLabel) {
        return this.path().get(stepLabel);
    }

    public default <A> A path(final Pop pop, final String stepLabel) {
        return this.path().get(pop, stepLabel);
    }

    /**
     * Return the number of times the traverser has gone through a looping section of a traversal.
     *
     * @return The number of times the traverser has gone through a loop
     */
    public int loops();

    /**
     * Return the number of times the traverser has gone through the named looping section of a traversal.
     *
     * @param loopName the name applied to the loop or null for the containing loop
     * @return The number of times the traverser has gone through a loop
     * @throws IllegalArgumentException if the loopName is not defined
     */
    public int loops(final String loopName);

    /**
     * A traverser may represent a grouping of traversers to allow for more efficient data propagation.
     *
     * @return the number of traversers represented in this traverser.
     */
    public long bulk();

    /**
     * Get a particular value from the side-effects of the traverser (thus, traversal).
     *
     * @param sideEffectKey the key of the value to get from the sideEffects
     * @param <A>           the type of the returned object
     * @return the object in the sideEffects of the respective key
     */
    public default <A> A sideEffects(final String sideEffectKey) throws IllegalArgumentException {
        return this.asAdmin().getSideEffects().<A>get(sideEffectKey);
    }

    /**
     * Add a particular value to the respective side-effect of the traverser (thus, traversal).
     *
     * @param sideEffectKey   the key of the value to set int the sideEffects
     * @param sideEffectValue the value to set for the sideEffect key
     */
    public default void sideEffects(final String sideEffectKey, final Object sideEffectValue) throws IllegalArgumentException {
        this.asAdmin().getSideEffects().add(sideEffectKey, sideEffectValue);
    }

    /**
     * If the underlying object of the traverser is comparable, compare it with the other traverser.
     *
     * @param other the other traverser that presumably has a comparable internal object
     * @return the comparison of the two objects of the traversers
     * @throws ClassCastException if the object of the traverser is not comparable
     */
    @Override
    public default int compareTo(final Traverser<T> other) throws ClassCastException {
        return ((Comparable) this.get()).compareTo(other.get());
    }

    /**
     * Typecast the traverser to a "system traverser" so {@link Traverser.Admin} methods can be accessed.
     * This is used as a helper method to avoid the awkwardness of <code>((Traverser.Administrative)traverser)</code>.
     * The default implementation simply returns "this" type casted to {@link Traverser.Admin}.
     *
     * @return The type-casted traverser
     */
    public default Admin<T> asAdmin() {
        return (Admin<T>) this;
    }

    /**
     * Traverser cloning is important when splitting a traverser at a bifurcation point in a traversal.
     */
    @SuppressWarnings("CloneDoesntDeclareCloneNotSupportedException")
    public Traverser<T> clone();

    /**
     * The methods in System.Traverser are useful to underlying Step and Traversal implementations.
     * They should not be accessed by the user during lambda-based manipulations.
     */
    public interface Admin<T> extends Traverser<T>, Attachable<T> {

        public static final String HALT = "halt";

        /**
         * When two traversers are have equality with each other, then they can be merged.
         * This method is used to merge the traversers into a single traverser.
         * This is used for optimization where instead of enumerating all traversers, they can be counted.
         *
         * @param other the other traverser to merge into this traverser. Once merged, the other can be garbage collected.
         */
        public void merge(final Admin<?> other);

        /**
         * Generate a child traverser of the current traverser for current as step and new object location.
         * The child has the path history, future, and loop information of the parent.
         * The child extends that path history with the current as and provided R-object.
         *
         * @param r    The current object of the child
         * @param step The step yielding the split
         * @param <R>  The current object type of the child
         * @return The split traverser
         */
        public <R> Admin<R> split(final R r, final Step<T, R> step);

        /**
         * Generate a sibling traverser of the current traverser with a full copy of all state within the sibling.
         *
         * @return The split traverser
         */
        public Admin<T> split();

        public void addLabels(final Set<String> labels);

        /**
         * Drop all path information not associated with specified labels.
         * This is an optimization method that allows a traverser to save memory and increase the likelihood of bulking.
         *
         * @param labels the labels to keep path information for.
         */
        public void keepLabels(final Set<String> labels);

        /**
         * Drop all path information associated with specified labels.
         * This is an optimization method that allows a traverser to save memory and increase the likelihood of bulking.
         *
         * @param labels the labels to drop path information for.
         */
        public void dropLabels(final Set<String> labels);

        /**
         * Drop the path of the traverser.
         * This is an optimization method that allows a traverser to save memory and increase the likelihood of bulking.
         */
        public void dropPath();

        /**
         * Set the current object location of the traverser.
         *
         * @param t The current object of the traverser
         */
        public void set(final T t);

        /**
         * Initialise a loop by setting up the looping construct.
         * The step label is important to create a stack of loop counters when within a nested context.
         * If the provided label is not the same as the current label on the stack, add a new loop counter.
         * The loopName can be used to refer to the loops counter via the {@link LoopsStep}
         *
         * @param stepLabel the label of the step that is being set-up.
         * @param loopName the user defined name for referencing the loop counter or null if not set
         */
        public void initialiseLoops(final String stepLabel, final String loopName);

        /**
         * Increment the number of times the traverser has gone through a looping section of traversal.
         */
        public void incrLoops();

        /**
         * Set the number of times the traverser has gone through a loop back to 0.
         * When a traverser exits a looping construct, this method should be called.
         * In a nested loop context, the highest stack loop counter should be removed.
         */
        public void resetLoops();

        /**
         * Get the step id of where the traverser is located.
         * This is typically used in multi-machine systems that require the movement of
         * traversers between different traversal instances.
         *
         * @return The future step for the traverser
         */
        public String getStepId();

        /**
         * Set the step id of where the traverser is located.
         * If the future is {@link Traverser.Admin#HALT}, then {@link Traverser.Admin#isHalted()} is true.
         *
         * @param stepId The future step of the traverser
         */
        public void setStepId(final String stepId);

        /**
         * If the traverser has "no future" then it is done with its lifecycle.
         * This does not mean that the traverser is "dead," only that it has successfully passed through a
         * {@link Traversal}.
         *
         * @return Whether the traverser is done executing or not
         */
        public default boolean isHalted() {
            return getStepId().equals(HALT);
        }

        /**
         * Set the number of traversers represented by this traverser.
         *
         * @param count the number of traversers
         */
        public void setBulk(final long count);

        /**
         * Prepare the traverser for migration across a JVM boundary.
         *
         * @return The deflated traverser
         */
        public Admin<T> detach();

        /**
         * Regenerate the detached traverser given its location at a particular vertex.
         *
         * @param method The method by which to attach a {@code Traverser} to an vertex.
         * @return The inflated traverser
         */
        @Override
        public T attach(final Function<Attachable<T>, T> method);

        /**
         * Set the sideEffects of the {@link Traversal}. Given that traversers can move between machines,
         * it may be important to re-set this when the traverser crosses machine boundaries.
         *
         * @param sideEffects the sideEffects of the traversal.
         */
        public void setSideEffects(final TraversalSideEffects sideEffects);

        /**
         * Get the sideEffects associated with the traversal of the traverser.
         *
         * @return the traversal sideEffects of the traverser
         */
        public TraversalSideEffects getSideEffects();

        /**
         * Get the tags associated with the traverser.
         * Tags are used to categorize historic behavior of a traverser.
         * The returned set is mutable.
         *
         * @return the set of tags associated with the traverser.
         */
        public Set<String> getTags();
    }
}
