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

import org.apache.tinkerpop.gremlin.process.traversal.P;
import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
import org.apache.tinkerpop.gremlin.process.traversal.Traverser;
import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__;
import org.apache.tinkerpop.gremlin.process.traversal.step.StepTest;
import org.apache.tinkerpop.gremlin.process.traversal.step.filter.CoinStep;
import org.apache.tinkerpop.gremlin.process.traversal.step.filter.ConnectiveStep;
import org.apache.tinkerpop.gremlin.process.traversal.step.filter.WherePredicateStep;
import org.apache.tinkerpop.gremlin.process.traversal.step.filter.WhereTraversalStep;
import org.apache.tinkerpop.gremlin.process.traversal.step.util.EmptyStep;
import org.apache.tinkerpop.gremlin.process.traversal.traverser.B_LP_O_P_S_SE_SL_TraverserGenerator;
import org.apache.tinkerpop.gremlin.process.traversal.traverser.util.EmptyTraverser;
import org.apache.tinkerpop.gremlin.structure.T;
import org.junit.Test;

import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.function.Consumer;

import static org.apache.tinkerpop.gremlin.process.traversal.P.eq;
import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.and;
import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.as;
import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.in;
import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.match;
import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.or;
import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.out;
import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.where;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

/**
 * @author Marko A. Rodriguez (http://markorodriguez.com)
 */
public class MatchStepTest extends StepTest {
    @Override
    protected List<Traversal> getTraversals() {
        return Arrays.asList(
                __.match(as("a").out("knows").as("b")),
                __.match(as("a").out().as("b")),
                ////
                __.match(where(as("a").out("knows").as("b"))),
                __.match(as("a").where(out().as("b"))),
                ///
                match(__.as("a").out().as("b"), __.as("b").out().as("c")),
                match(__.as("b").out().as("c"), __.as("a").out().as("d"))
        );
    }

    @Test
    public void testPreCompilationOfStartAndEnds() {
        final Traversal.Admin<?, ?> traversal = __.match(as("a").out().as("b"), as("c").path().as("d")).asAdmin();
        final MatchStep<?, ?> matchStep = (MatchStep<?, ?>) traversal.getStartStep();
        assertEquals(MatchStep.class, traversal.getStartStep().getClass());
        assertEquals(2, matchStep.getGlobalChildren().size());
        Traversal.Admin<Object, Object> pattern = matchStep.getGlobalChildren().get(0);
        assertEquals("a", ((MatchStep.MatchStartStep) pattern.getStartStep()).getSelectKey().get());
        assertEquals(VertexStep.class, pattern.getStartStep().getNextStep().getClass());
        assertEquals("b", ((MatchStep.MatchEndStep) pattern.getEndStep()).getMatchKey().get());
        //
        pattern = matchStep.getGlobalChildren().get(1);
        assertEquals("c", ((MatchStep.MatchStartStep) pattern.getStartStep()).getSelectKey().get());
        assertEquals(PathStep.class, pattern.getStartStep().getNextStep().getClass());
        assertEquals("d", ((MatchStep.MatchEndStep) pattern.getEndStep()).getMatchKey().get());
    }

    @Test
    public void testPreCompilationOfOr() {
        final List<Traversal.Admin<?, ?>> traversals = Arrays.asList(
                __.match(as("a").out().as("b"), or(as("c").path().as("d"), as("e").coin(0.5).as("f"))).asAdmin(),
                __.match(as("a").out().as("b"), as("c").path().as("d").or().as("e").coin(0.5).as("f")).asAdmin());
        assertEquals(1, new HashSet<>(traversals).size()); // the two patterns should pre-compile to the same traversal
        traversals.forEach(traversal -> {
            final MatchStep<?, ?> matchStep = (MatchStep<?, ?>) traversal.getStartStep();
            assertEquals(2, matchStep.getGlobalChildren().size());
            Traversal.Admin<Object, Object> pattern = matchStep.getGlobalChildren().get(0);
            assertEquals("a", ((MatchStep.MatchStartStep) pattern.getStartStep()).getSelectKey().get());
            assertEquals(VertexStep.class, pattern.getStartStep().getNextStep().getClass());
            assertEquals("b", ((MatchStep.MatchEndStep) pattern.getEndStep()).getMatchKey().get());
            //
            pattern = matchStep.getGlobalChildren().get(1);
            assertEquals(MatchStep.class, pattern.getStartStep().getClass());
            assertEquals(ConnectiveStep.Connective.OR, ((MatchStep<?, ?>) pattern.getStartStep()).getConnective());
            assertEquals("c", ((MatchStep.MatchStartStep) ((MatchStep<?, ?>) pattern.getStartStep()).getGlobalChildren().get(0).getStartStep()).getSelectKey().get());
            assertEquals(PathStep.class, ((MatchStep<?, ?>) pattern.getStartStep()).getGlobalChildren().get(0).getStartStep().getNextStep().getClass());
            assertEquals("d", ((MatchStep.MatchEndStep) ((MatchStep<?, ?>) pattern.getStartStep()).getGlobalChildren().get(0).getEndStep()).getMatchKey().get());
            assertEquals("e", ((MatchStep.MatchStartStep) ((MatchStep<?, ?>) pattern.getStartStep()).getGlobalChildren().get(1).getStartStep()).getSelectKey().get());
            assertEquals(CoinStep.class, ((MatchStep<?, ?>) pattern.getStartStep()).getGlobalChildren().get(1).getStartStep().getNextStep().getClass());
            assertEquals("f", ((MatchStep.MatchEndStep) ((MatchStep<?, ?>) pattern.getStartStep()).getGlobalChildren().get(1).getEndStep()).getMatchKey().get());
        });
    }

    @Test
    public void testPreCompilationOfAnd() {
        final List<Traversal.Admin<?, ?>> traversals = Arrays.asList(
                __.match(as("a").out().as("b"), and(as("c").path().as("d"), as("e").barrier())).asAdmin(),
                __.match(as("a").out().as("b"), as("c").path().as("d").and().as("e").barrier()).asAdmin());
        assertEquals(1, new HashSet<>(traversals).size());   // the two patterns should pre-compile to the same traversal
        traversals.forEach(traversal -> {
            final MatchStep<?, ?> matchStep = (MatchStep<?, ?>) traversal.getStartStep();
            assertEquals(2, matchStep.getGlobalChildren().size());
            Traversal.Admin<Object, Object> pattern = matchStep.getGlobalChildren().get(0);
            assertEquals("a", ((MatchStep.MatchStartStep) pattern.getStartStep()).getSelectKey().get());
            assertEquals(VertexStep.class, pattern.getStartStep().getNextStep().getClass());
            assertEquals("b", ((MatchStep.MatchEndStep) pattern.getEndStep()).getMatchKey().get());
            //
            pattern = matchStep.getGlobalChildren().get(1);
            assertEquals(MatchStep.class, pattern.getStartStep().getClass());
            assertEquals(ConnectiveStep.Connective.AND, ((MatchStep<?, ?>) pattern.getStartStep()).getConnective());
            assertEquals("c", ((MatchStep.MatchStartStep) ((MatchStep<?, ?>) pattern.getStartStep()).getGlobalChildren().get(0).getStartStep()).getSelectKey().get());
            assertEquals(PathStep.class, ((MatchStep<?, ?>) pattern.getStartStep()).getGlobalChildren().get(0).getStartStep().getNextStep().getClass());
            assertEquals("d", ((MatchStep.MatchEndStep) ((MatchStep<?, ?>) pattern.getStartStep()).getGlobalChildren().get(0).getEndStep()).getMatchKey().get());
            assertEquals("e", ((MatchStep.MatchStartStep) ((MatchStep<?, ?>) pattern.getStartStep()).getGlobalChildren().get(1).getStartStep()).getSelectKey().get());
            assertEquals(NoOpBarrierStep.class, ((MatchStep<?, ?>) pattern.getStartStep()).getGlobalChildren().get(1).getStartStep().getNextStep().getClass());
            assertFalse(((MatchStep.MatchEndStep) ((MatchStep<?, ?>) pattern.getStartStep()).getGlobalChildren().get(1).getEndStep()).getMatchKey().isPresent());
        });
    }

    @Test
    public void testPreCompilationOfWhereTraversal() {
        final List<Traversal.Admin<?, ?>> traversals = Arrays.asList(
                __.match(as("a").out().as("b"), as("c").where(in().as("d"))).asAdmin(),
                __.match(as("a").out().as("b"), where(as("c").in().as("d"))).asAdmin());
        assertEquals(1, new HashSet<>(traversals).size()); // the two patterns should pre-compile to the same traversal
        traversals.forEach(traversal -> {
            final MatchStep<?, ?> matchStep = (MatchStep<?, ?>) traversal.getStartStep();
            //assertFalse(matchStep.getStartLabel().isPresent());
            assertEquals(2, matchStep.getGlobalChildren().size());
            Traversal.Admin<Object, Object> pattern = matchStep.getGlobalChildren().get(0);
            assertEquals("a", ((MatchStep.MatchStartStep) pattern.getStartStep()).getSelectKey().get());
            assertEquals(VertexStep.class, pattern.getStartStep().getNextStep().getClass());
            assertEquals("b", ((MatchStep.MatchEndStep) pattern.getEndStep()).getMatchKey().get());
            //
            pattern = matchStep.getGlobalChildren().get(1);
            assertEquals(MatchStep.MatchStartStep.class, pattern.getStartStep().getClass());
            assertEquals("c", ((MatchStep.MatchStartStep) pattern.getStartStep()).getSelectKey().get());
            assertEquals(WhereTraversalStep.class, pattern.getStartStep().getNextStep().getClass());
            assertEquals(MatchStep.MatchEndStep.class, pattern.getStartStep().getNextStep().getNextStep().getClass());
            assertEquals(1, ((WhereTraversalStep<?>) pattern.getStartStep().getNextStep()).getLocalChildren().size());
            Traversal.Admin<?, ?> whereTraversal = ((WhereTraversalStep<?>) pattern.getStartStep().getNextStep()).getLocalChildren().get(0);
            assertEquals(WhereTraversalStep.WhereStartStep.class, whereTraversal.getStartStep().getClass());
            assertTrue(((WhereTraversalStep.WhereStartStep) whereTraversal.getStartStep()).getScopeKeys().isEmpty());
            assertEquals(VertexStep.class, whereTraversal.getStartStep().getNextStep().getClass());
            assertEquals(WhereTraversalStep.WhereEndStep.class, whereTraversal.getStartStep().getNextStep().getNextStep().getClass());
            assertEquals(1, ((WhereTraversalStep.WhereEndStep) whereTraversal.getStartStep().getNextStep().getNextStep()).getScopeKeys().size());
            assertEquals("d", ((WhereTraversalStep.WhereEndStep) whereTraversal.getStartStep().getNextStep().getNextStep()).getScopeKeys().iterator().next());
        });
    }

    @Test
    public void testPreCompilationOfWherePredicate() {
        final List<Traversal.Admin<?, ?>> traversals = Arrays.asList(
                __.match(as("a").out().as("b"), as("c").where(P.neq("d"))).asAdmin(),
                __.match(as("a").out().as("b"), where("c", P.neq("d"))).asAdmin());
        assertEquals(1, new HashSet<>(traversals).size()); // the two patterns should pre-compile to the same traversal
        traversals.forEach(traversal -> {
            final MatchStep<?, ?> matchStep = (MatchStep<?, ?>) traversal.getStartStep();
            //assertFalse(matchStep.getStartLabel().isPresent());
            assertEquals(2, matchStep.getGlobalChildren().size());
            Traversal.Admin<Object, Object> pattern = matchStep.getGlobalChildren().get(0);
            assertEquals("a", ((MatchStep.MatchStartStep) pattern.getStartStep()).getSelectKey().get());
            assertEquals(VertexStep.class, pattern.getStartStep().getNextStep().getClass());
            assertEquals("b", ((MatchStep.MatchEndStep) pattern.getEndStep()).getMatchKey().get());
            //
            pattern = matchStep.getGlobalChildren().get(1);
            assertEquals(MatchStep.MatchStartStep.class, pattern.getStartStep().getClass());
            assertEquals("c", ((MatchStep.MatchStartStep) pattern.getStartStep()).getSelectKey().get());
            assertEquals(WherePredicateStep.class, pattern.getStartStep().getNextStep().getClass());
            assertEquals(MatchStep.MatchEndStep.class, pattern.getStartStep().getNextStep().getNextStep().getClass());
            assertFalse(((WherePredicateStep<?>) pattern.getStartStep().getNextStep()).getStartKey().isPresent());
            assertEquals("d", ((WherePredicateStep<?>) pattern.getStartStep().getNextStep()).getPredicate().get().getOriginalValue());
        });
    }

    @Test
    public void testCountMatchAlgorithm() {
        // MAKE SURE THE SORT ORDER CHANGES AS MORE RESULTS ARE RETURNED BY ONE OR THE OTHER TRAVERSAL
        Traversal.Admin<?, ?> traversal = __.match(as("a").out().as("b"), as("c").in().as("d")).asAdmin();
        MatchStep.CountMatchAlgorithm countMatchAlgorithm = new MatchStep.CountMatchAlgorithm();
        countMatchAlgorithm.initialize(false, ((MatchStep<?, ?>) traversal.getStartStep()).getGlobalChildren());
        Traversal.Admin<Object, Object> firstPattern = ((MatchStep<?, ?>) traversal.getStartStep()).getGlobalChildren().get(0);
        Traversal.Admin<Object, Object> secondPattern = ((MatchStep<?, ?>) traversal.getStartStep()).getGlobalChildren().get(1);
        //
        assertEquals(2, countMatchAlgorithm.bundles.size());
        countMatchAlgorithm.bundles.stream().forEach(bundle -> assertEquals(0.0d, bundle.multiplicity, 0.0d));
        assertEquals(firstPattern, countMatchAlgorithm.bundles.get(0).traversal);
        assertEquals(secondPattern, countMatchAlgorithm.bundles.get(1).traversal);
        countMatchAlgorithm.recordStart(EmptyTraverser.instance(), firstPattern);
        countMatchAlgorithm.recordStart(EmptyTraverser.instance(), firstPattern);
        countMatchAlgorithm.recordStart(EmptyTraverser.instance(), secondPattern);
        countMatchAlgorithm.recordStart(EmptyTraverser.instance(), secondPattern);
        countMatchAlgorithm.recordStart(EmptyTraverser.instance(), secondPattern);
        assertEquals(firstPattern, countMatchAlgorithm.bundles.get(0).traversal);
        assertEquals(secondPattern, countMatchAlgorithm.bundles.get(1).traversal);
        assertEquals(MatchStep.TraversalType.MATCH_TRAVERSAL, countMatchAlgorithm.getBundle(firstPattern).traversalType);
        assertEquals(MatchStep.TraversalType.MATCH_TRAVERSAL, countMatchAlgorithm.getBundle(secondPattern).traversalType);
        assertEquals(2l, countMatchAlgorithm.getBundle(firstPattern).startsCount);
        assertEquals(3l, countMatchAlgorithm.getBundle(secondPattern).startsCount);
        assertEquals(0l, countMatchAlgorithm.getBundle(firstPattern).endsCount);
        assertEquals(0l, countMatchAlgorithm.getBundle(secondPattern).endsCount);
        ////
        countMatchAlgorithm.recordEnd(EmptyTraverser.instance(), firstPattern);
        countMatchAlgorithm.recordEnd(EmptyTraverser.instance(), secondPattern);
        countMatchAlgorithm.recordEnd(EmptyTraverser.instance(), secondPattern);
        countMatchAlgorithm.recordEnd(EmptyTraverser.instance(), secondPattern);
        assertEquals(2l, countMatchAlgorithm.getBundle(firstPattern).startsCount);
        assertEquals(3l, countMatchAlgorithm.getBundle(secondPattern).startsCount);
        assertEquals(1l, countMatchAlgorithm.getBundle(firstPattern).endsCount);
        assertEquals(3l, countMatchAlgorithm.getBundle(secondPattern).endsCount);
        assertEquals(0.5d, countMatchAlgorithm.getBundle(firstPattern).multiplicity, 0.01d);
        assertEquals(1.0d, countMatchAlgorithm.getBundle(secondPattern).multiplicity, 0.01d);
        assertEquals(firstPattern, countMatchAlgorithm.bundles.get(0).traversal);
        assertEquals(secondPattern, countMatchAlgorithm.bundles.get(1).traversal);
        // CHECK RE-SORTING AS MORE DATA COMES IN
        countMatchAlgorithm.recordEnd(EmptyTraverser.instance(), firstPattern);
        countMatchAlgorithm.recordEnd(EmptyTraverser.instance(), firstPattern);
        assertEquals(1.5d, countMatchAlgorithm.getBundle(firstPattern).multiplicity, 0.01d);
        assertEquals(1.0d, countMatchAlgorithm.getBundle(secondPattern).multiplicity, 0.01d);
        assertEquals(secondPattern, countMatchAlgorithm.bundles.get(0).traversal);
        assertEquals(firstPattern, countMatchAlgorithm.bundles.get(1).traversal);


        ///////  MAKE SURE WHERE PREDICATE TRAVERSALS ARE ALWAYS FIRST AS THEY ARE SIMPLY .hasNext() CHECKS
        traversal = __.match(as("a").out().as("b"), as("c").in().as("d"), where("a", P.eq("b"))).asAdmin();
        countMatchAlgorithm = new MatchStep.CountMatchAlgorithm();
        countMatchAlgorithm.initialize(false, ((MatchStep<?, ?>) traversal.getStartStep()).getGlobalChildren());
        assertEquals(3, countMatchAlgorithm.bundles.size());
        firstPattern = ((MatchStep<?, ?>) traversal.getStartStep()).getGlobalChildren().get(0);
        secondPattern = ((MatchStep<?, ?>) traversal.getStartStep()).getGlobalChildren().get(1);
        Traversal.Admin<Object, Object> thirdPattern = ((MatchStep<?, ?>) traversal.getStartStep()).getGlobalChildren().get(2);
        ///
        countMatchAlgorithm.bundles.stream().forEach(bundle -> assertEquals(0.0d, bundle.multiplicity, 0.0d));
        assertEquals(MatchStep.TraversalType.MATCH_TRAVERSAL, countMatchAlgorithm.getBundle(firstPattern).traversalType);
        assertEquals(MatchStep.TraversalType.MATCH_TRAVERSAL, countMatchAlgorithm.getBundle(secondPattern).traversalType);
        assertEquals(MatchStep.TraversalType.WHERE_PREDICATE, countMatchAlgorithm.getBundle(thirdPattern).traversalType);
        assertEquals(firstPattern, countMatchAlgorithm.bundles.get(0).traversal);
        assertEquals(secondPattern, countMatchAlgorithm.bundles.get(1).traversal);
        assertEquals(thirdPattern, countMatchAlgorithm.bundles.get(2).traversal);
        countMatchAlgorithm.recordStart(EmptyTraverser.instance(), firstPattern);
        countMatchAlgorithm.recordEnd(EmptyTraverser.instance(), firstPattern);
        assertEquals(1l, countMatchAlgorithm.getBundle(firstPattern).startsCount);
        assertEquals(0l, countMatchAlgorithm.getBundle(secondPattern).startsCount);
        assertEquals(0l, countMatchAlgorithm.getBundle(thirdPattern).startsCount);
        assertEquals(1l, countMatchAlgorithm.getBundle(firstPattern).endsCount);
        assertEquals(0l, countMatchAlgorithm.getBundle(secondPattern).endsCount);
        assertEquals(0l, countMatchAlgorithm.getBundle(thirdPattern).endsCount);
        assertEquals(1.0d, countMatchAlgorithm.getBundle(firstPattern).multiplicity, 0.01d);
        assertEquals(0.0d, countMatchAlgorithm.getBundle(secondPattern).multiplicity, 0.01d);
        assertEquals(0.0d, countMatchAlgorithm.getBundle(thirdPattern).multiplicity, 0.01d);
        assertEquals(thirdPattern, countMatchAlgorithm.bundles.get(0).traversal);
        assertEquals(secondPattern, countMatchAlgorithm.bundles.get(1).traversal);
        assertEquals(firstPattern, countMatchAlgorithm.bundles.get(2).traversal);
        //
        countMatchAlgorithm.recordStart(EmptyTraverser.instance(), thirdPattern);
        countMatchAlgorithm.recordStart(EmptyTraverser.instance(), thirdPattern);
        countMatchAlgorithm.recordStart(EmptyTraverser.instance(), thirdPattern);
        countMatchAlgorithm.recordEnd(EmptyTraverser.instance(), thirdPattern);
        countMatchAlgorithm.recordEnd(EmptyTraverser.instance(), thirdPattern);
        countMatchAlgorithm.recordEnd(EmptyTraverser.instance(), thirdPattern);
        countMatchAlgorithm.recordEnd(EmptyTraverser.instance(), thirdPattern);
        countMatchAlgorithm.recordEnd(EmptyTraverser.instance(), thirdPattern);
        countMatchAlgorithm.recordEnd(EmptyTraverser.instance(), thirdPattern);
        assertEquals(1l, countMatchAlgorithm.getBundle(firstPattern).startsCount);
        assertEquals(0l, countMatchAlgorithm.getBundle(secondPattern).startsCount);
        assertEquals(3l, countMatchAlgorithm.getBundle(thirdPattern).startsCount);
        assertEquals(1l, countMatchAlgorithm.getBundle(firstPattern).endsCount);
        assertEquals(0l, countMatchAlgorithm.getBundle(secondPattern).endsCount);
        assertEquals(6l, countMatchAlgorithm.getBundle(thirdPattern).endsCount);
        assertEquals(1.0d, countMatchAlgorithm.getBundle(firstPattern).multiplicity, 0.01d);
        assertEquals(0.0d, countMatchAlgorithm.getBundle(secondPattern).multiplicity, 0.01d);
        assertEquals(2.0d, countMatchAlgorithm.getBundle(thirdPattern).multiplicity, 0.01d);
        assertEquals(thirdPattern, countMatchAlgorithm.bundles.get(0).traversal);
        assertEquals(secondPattern, countMatchAlgorithm.bundles.get(1).traversal);
        assertEquals(firstPattern, countMatchAlgorithm.bundles.get(2).traversal);
        //
        countMatchAlgorithm.recordStart(EmptyTraverser.instance(), secondPattern);
        countMatchAlgorithm.recordStart(EmptyTraverser.instance(), secondPattern);
        countMatchAlgorithm.recordStart(EmptyTraverser.instance(), secondPattern);
        countMatchAlgorithm.recordStart(EmptyTraverser.instance(), secondPattern);
        countMatchAlgorithm.recordEnd(EmptyTraverser.instance(), secondPattern);
        countMatchAlgorithm.recordEnd(EmptyTraverser.instance(), secondPattern);
        countMatchAlgorithm.recordEnd(EmptyTraverser.instance(), secondPattern);
        countMatchAlgorithm.recordEnd(EmptyTraverser.instance(), secondPattern);
        countMatchAlgorithm.recordEnd(EmptyTraverser.instance(), secondPattern);
        countMatchAlgorithm.recordEnd(EmptyTraverser.instance(), secondPattern);
        assertEquals(1l, countMatchAlgorithm.getBundle(firstPattern).startsCount);
        assertEquals(4l, countMatchAlgorithm.getBundle(secondPattern).startsCount);
        assertEquals(3l, countMatchAlgorithm.getBundle(thirdPattern).startsCount);
        assertEquals(1l, countMatchAlgorithm.getBundle(firstPattern).endsCount);
        assertEquals(6l, countMatchAlgorithm.getBundle(secondPattern).endsCount);
        assertEquals(6l, countMatchAlgorithm.getBundle(thirdPattern).endsCount);
        assertEquals(1.0d, countMatchAlgorithm.getBundle(firstPattern).multiplicity, 0.01d);
        assertEquals(1.5d, countMatchAlgorithm.getBundle(secondPattern).multiplicity, 0.01d);
        assertEquals(2.0d, countMatchAlgorithm.getBundle(thirdPattern).multiplicity, 0.01d);
        assertEquals(thirdPattern, countMatchAlgorithm.bundles.get(0).traversal);
        assertEquals(firstPattern, countMatchAlgorithm.bundles.get(1).traversal);
        assertEquals(secondPattern, countMatchAlgorithm.bundles.get(2).traversal);
    }

    @Test
    public void testComputerAwareCountMatchAlgorithm() {
        // MAKE SURE OLAP JOBS ARE BIASED TOWARDS STAR GRAPH DATA
        final Consumer doNothing = s -> {
        };
        final Traversal.Admin<?, ?> traversal = __.match(
                as("a").sideEffect(doNothing).as("b"),    // 1
                as("b").sideEffect(doNothing).as("c"),    // 2
                as("a").sideEffect(doNothing).as("d"),    // 5
                as("c").sideEffect(doNothing).as("e"),    // 4
                as("c").sideEffect(doNothing).as("f"))    // 3
                .asAdmin();
        traversal.applyStrategies(); // necessary to enure step ids are unique
        final MatchStep.CountMatchAlgorithm countMatchAlgorithm = new MatchStep.CountMatchAlgorithm();
        countMatchAlgorithm.initialize(true, ((MatchStep<?, ?>) traversal.getStartStep()).getGlobalChildren());
        Traversal.Admin<Object, Object> firstPattern = ((MatchStep<?, ?>) traversal.getStartStep()).getGlobalChildren().get(0);
        Traversal.Admin<Object, Object> secondPattern = ((MatchStep<?, ?>) traversal.getStartStep()).getGlobalChildren().get(1);
        Traversal.Admin<Object, Object> thirdPattern = ((MatchStep<?, ?>) traversal.getStartStep()).getGlobalChildren().get(2);
        Traversal.Admin<Object, Object> forthPattern = ((MatchStep<?, ?>) traversal.getStartStep()).getGlobalChildren().get(3);
        Traversal.Admin<Object, Object> fifthPattern = ((MatchStep<?, ?>) traversal.getStartStep()).getGlobalChildren().get(4);
        countMatchAlgorithm.bundles.stream().forEach(bundle -> assertEquals(0.0d, bundle.multiplicity, 0.0d));
        assertEquals(MatchStep.TraversalType.MATCH_TRAVERSAL, countMatchAlgorithm.getBundle(firstPattern).traversalType);
        assertEquals(MatchStep.TraversalType.MATCH_TRAVERSAL, countMatchAlgorithm.getBundle(secondPattern).traversalType);
        assertEquals(MatchStep.TraversalType.MATCH_TRAVERSAL, countMatchAlgorithm.getBundle(thirdPattern).traversalType);
        assertEquals(MatchStep.TraversalType.MATCH_TRAVERSAL, countMatchAlgorithm.getBundle(forthPattern).traversalType);
        assertEquals(MatchStep.TraversalType.MATCH_TRAVERSAL, countMatchAlgorithm.getBundle(fifthPattern).traversalType);
        assertEquals(firstPattern, countMatchAlgorithm.bundles.get(0).traversal);
        assertEquals(secondPattern, countMatchAlgorithm.bundles.get(1).traversal);
        assertEquals(thirdPattern, countMatchAlgorithm.bundles.get(2).traversal);
        assertEquals(forthPattern, countMatchAlgorithm.bundles.get(3).traversal);
        assertEquals(fifthPattern, countMatchAlgorithm.bundles.get(4).traversal);
        // MAKE THE SECOND PATTERN EXPENSIVE
        countMatchAlgorithm.recordStart(EmptyTraverser.instance(), secondPattern);
        countMatchAlgorithm.recordEnd(EmptyTraverser.instance(), secondPattern);
        countMatchAlgorithm.recordEnd(EmptyTraverser.instance(), secondPattern);
        countMatchAlgorithm.recordEnd(EmptyTraverser.instance(), secondPattern);
        countMatchAlgorithm.recordEnd(EmptyTraverser.instance(), secondPattern);
        countMatchAlgorithm.recordEnd(EmptyTraverser.instance(), secondPattern);
        countMatchAlgorithm.recordEnd(EmptyTraverser.instance(), secondPattern);
        // MAKE THE THIRD PATTERN MORE EXPENSIVE THAN FORTH
        countMatchAlgorithm.recordStart(EmptyTraverser.instance(), thirdPattern);
        countMatchAlgorithm.recordEnd(EmptyTraverser.instance(), thirdPattern);
        countMatchAlgorithm.recordEnd(EmptyTraverser.instance(), thirdPattern);
        countMatchAlgorithm.recordEnd(EmptyTraverser.instance(), thirdPattern);
        // MAKE THE FORTH PATTERN EXPENSIVE
        countMatchAlgorithm.recordStart(EmptyTraverser.instance(), forthPattern);
        countMatchAlgorithm.recordEnd(EmptyTraverser.instance(), forthPattern);
        countMatchAlgorithm.recordEnd(EmptyTraverser.instance(), forthPattern);
        //
        Traverser.Admin traverser = B_LP_O_P_S_SE_SL_TraverserGenerator.instance().generate(1, EmptyStep.instance(), 1l);
        traverser.addLabels(Collections.singleton("a"));
        assertEquals(firstPattern, countMatchAlgorithm.apply(traverser));
        traverser = traverser.split(1, EmptyStep.instance());
        traverser.getTags().add(firstPattern.getStartStep().getId());
        traverser.addLabels(Collections.singleton("b"));
        //
        assertEquals(secondPattern, countMatchAlgorithm.apply(traverser));
        traverser = traverser.split(1, EmptyStep.instance());
        traverser.getTags().add(secondPattern.getStartStep().getId());
        traverser.addLabels(Collections.singleton("c"));
        //
        assertEquals(fifthPattern, countMatchAlgorithm.apply(traverser));
        traverser = traverser.split(1, EmptyStep.instance());
        traverser.getTags().add(fifthPattern.getStartStep().getId());
        traverser.addLabels(Collections.singleton("f"));
        //
        assertEquals(forthPattern, countMatchAlgorithm.apply(traverser));
        traverser = traverser.split(1, EmptyStep.instance());
        traverser.getTags().add(forthPattern.getStartStep().getId());
        traverser.addLabels(Collections.singleton("e"));
        //
        assertEquals(thirdPattern, countMatchAlgorithm.apply(traverser));
        traverser = traverser.split(1, EmptyStep.instance());
        traverser.getTags().add(thirdPattern.getStartStep().getId());
        traverser.addLabels(Collections.singleton("d"));
    }

    @Test
    public void shouldCalculateStartLabelCorrectly() {
        Traversal.Admin<?, ?> traversal = match(
                where(and(
                        as("a").out("created").as("b"),
                        as("b").in("created").count().is(eq(3)))),
                as("a").both().as("b"),
                where(as("b").in())).asAdmin();
        assertEquals("a", MatchStep.Helper.computeStartLabel(((MatchStep<?, ?>) traversal.getStartStep()).getGlobalChildren()));
        /////
        traversal = match(
                where("a", P.neq("c")),
                as("a").out("created").as("b"),
                or(
                        as("a").out("knows").has("name", "vadas"),
                        as("a").in("knows").and().as("a").has(T.label, "person")
                ),
                as("b").in("created").as("c"),
                as("b").in("created").count().is(P.gt(1))).asAdmin();
        assertEquals("a", MatchStep.Helper.computeStartLabel(((MatchStep<?, ?>) traversal.getStartStep()).getGlobalChildren()));
    }

}
