package org.neo4j.docs.driver;

// tag::=pass-bookmarks-import[]
import java.util.ArrayList;
import java.util.List;

import org.neo4j.driver.v1.AccessMode;
import org.neo4j.driver.v1.Record;
import org.neo4j.driver.v1.Session;
import org.neo4j.driver.v1.StatementResult;
import org.neo4j.driver.v1.Transaction;

import static org.neo4j.driver.v1.Values.parameters;
// end::=pass-bookmarks-import[]

public class PassBookmarkExample extends BaseApplication
{

    public PassBookmarkExample( String uri, String user, String password )
    {
        super( uri, user, password );
    }

    // tag::pass-bookmarks[]
    // Create a company node
    private StatementResult addCompany( final Transaction tx, final String name )
    {
        return tx.run( "CREATE (:Company {name: $name})", parameters( "name", name ) );
    }

    // Create a person node
    private StatementResult addPerson( final Transaction tx, final String name )
    {
        return tx.run( "CREATE (:Person {name: $name})", parameters( "name", name ) );
    }

    // Create an employment relationship to a pre-existing company node.
    // This relies on the person first having been created.
    private StatementResult employ( final Transaction tx, final String person, final String company )
    {
        return tx.run( "MATCH (person:Person {name: $person_name}) " +
                        "MATCH (company:Company {name: $company_name}) " +
                        "CREATE (person)-[:WORKS_FOR]->(company)",
                parameters( "person_name", person, "company_name", company ) );
    }

    // Create a friendship between two people.
    private StatementResult makeFriends( final Transaction tx, final String person1, final String person2 )
    {
        return tx.run( "MATCH (a:Person {name: $person_1}) " +
                        "MATCH (b:Person {name: $person_2}) " +
                        "MERGE (a)-[:KNOWS]->(b)",
                parameters( "person_1", person1, "person_2", person2 ) );
    }

    // Match and display all friendships.
    private StatementResult printFriends( final Transaction tx )
    {
        StatementResult result = tx.run( "MATCH (a)-[:KNOWS]->(b) RETURN a.name, b.name" );
        while ( result.hasNext() )
        {
            Record record = result.next();
            System.out.println( String.format( "%s knows %s", record.get( "a.name" ).asString(), record.get( "b.name" ).toString() ) );
        }
        return result;
    }

    public void addEmployAndMakeFriends()
    {
        // To collect the session bookmarks
        List<String> savedBookmarks = new ArrayList<>();

        // Create the first person and employment relationship.
        try ( Session session1 = driver.session( AccessMode.WRITE ) )
        {
            session1.writeTransaction( tx -> addCompany( tx, "Wayne Enterprises" ) );
            session1.writeTransaction( tx -> addPerson( tx, "Alice" ) );
            session1.writeTransaction( tx -> employ( tx, "Alice", "Wayne Enterprises" ) );

            savedBookmarks.add( session1.lastBookmark() );
        }

        // Create the second person and employment relationship.
        try ( Session session2 = driver.session( AccessMode.WRITE ) )
        {
            session2.writeTransaction( tx -> addCompany( tx, "LexCorp" ) );
            session2.writeTransaction( tx -> addPerson( tx, "Bob" ) );
            session2.writeTransaction( tx -> employ( tx, "Bob", "LexCorp" ) );

            savedBookmarks.add( session2.lastBookmark() );
        }

        // Create a friendship between the two people created above.
        try ( Session session3 = driver.session( AccessMode.WRITE, savedBookmarks ) )
        {
            session3.writeTransaction( tx -> makeFriends( tx, "Alice", "Bob" ) );

            session3.readTransaction( this::printFriends );
        }
    }
    // end::pass-bookmarks[]
}

@@ -1,8 +1,720 @@
+/*%0A * Copyright (c) 2002-2017 %22Neo Technology,%22%0A * Network Engine for Objects in Lund AB %5Bhttp://neotechnology.com%5D%0A *%0A * This file is part of Neo4j.%0A *%0A * Licensed under the Apache License, Version 2.0 (the %22License%22);%0A * you may not use this file except in compliance with the License.%0A * You may obtain a copy of the License at%0A *%0A *     http://www.apache.org/licenses/LICENSE-2.0%0A *%0A * Unless required by applicable law or agreed to in writing, software%0A * distributed under the License is distributed on an %22AS IS%22 BASIS,%0A * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.%0A * See the License for the specific language governing permissions and%0A * limitations under the License.%0A */%0A
 package 

add license header