/*
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 examples;

import org.apache.tinkerpop.gremlin.driver.Cluster;
import org.apache.tinkerpop.gremlin.driver.remote.DriverRemoteConnection;
import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource;
import org.apache.tinkerpop.gremlin.structure.Edge;
import org.apache.tinkerpop.gremlin.structure.Vertex;

import java.util.List;

import static org.apache.tinkerpop.gremlin.process.traversal.AnonymousTraversalSource.traversal;
import static org.apache.tinkerpop.gremlin.process.traversal.P.within;
import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.*;
import static org.apache.tinkerpop.gremlin.structure.T.id;

public class ModernTraversals {
    static final String SERVER_HOST = System.getProperty("GREMLIN_SERVER_HOST", "localhost");
    static final int SERVER_PORT = Integer.parseInt(System.getProperty("GREMLIN_SERVER_PORT", "8182"));

    public static void main(String[] args) throws Exception {
        // Performs basic traversals on the Modern toy graph loaded on the server
        Cluster cluster = Cluster.build(SERVER_HOST).port(SERVER_PORT).create();
        GraphTraversalSource g = traversal().withRemote(DriverRemoteConnection.using(cluster, "gmodern"));

        List<Edge> e1 = g.V(1).bothE().toList(); // (1)
        List<Edge> e2 = g.V(1).bothE().where(otherV().hasId(2)).toList(); // (2)
        Vertex v1 = g.V(1).next();
        Vertex v2 = g.V(2).next();
        List<Edge> e3 = g.V(v1).bothE().where(otherV().id().is(v2)).toList(); // (3)
        List<Edge> e4 = g.V(v1).outE().where(inV().id().is(v2)).toList(); // (4)
        List<Edge> e5 = g.V(1).outE().where(inV().has(id, within(2,3))).toList(); // (5)
        List<Vertex> e6 = g.V(1).out().where(in().hasId(6)).toList(); // (6)

        System.out.println("1: " + e1.toString());
        System.out.println("2: " + e2.toString());
        System.out.println("3: " + e3.toString());
        System.out.println("4: " + e4.toString());
        System.out.println("5: " + e5.toString());
        System.out.println("6: " + e6.toString());

        // Cleanup
        cluster.close();
        g.close();

        /*
        1. There are three edges from the vertex with the identifier of "1".
        2. Filter those three edges using the where()-step using the identifier of the vertex returned by otherV() to
           ensure it matches on the vertex of concern, which is the one with an identifier of "2".
        3. Note that the same traversal will work if there are actual Vertex instances rather than just vertex
           identifiers.
        4. The vertex with identifier "1" has all outgoing edges, so it would also be acceptable to use the directional
           steps of outE() and inV() since the schema allows it.
        5. There is also no problem with filtering the terminating side of the traversal on multiple vertices, in this
           case, vertices with identifiers "2" and "3".
        6. There’s no reason why the same pattern of exclusion used for edges with where() can’t work for a vertex
           between two vertices.
        */
    }
}


