// Path: src/main/java/com/maxdemarzi/processing/labelpropagation/LabelPropagation.java
// public interface LabelPropagation extends Algorithm {
// 
//     void compute(String label, String type, int iterations);
//     double getResult(long node);
//     long numberOfNodes();
//     default public String getPropertyName() {
//         return "label";
//     }
// 
// }
// 
// Path: src/main/java/com/maxdemarzi/processing/labelpropagation/LabelPropagationMapStorage.java
// public class LabelPropagationMapStorage implements LabelPropagation {
//     private final GraphDatabaseService db;
//     private final long nodes;
//     private Long2DoubleOpenHashMap labelMap;
// 
//     public LabelPropagationMapStorage(GraphDatabaseService db) {
//         this.db = db;
//         this.nodes = new NodeCounter().getNodeCount(db);
//     }
// 
//     @Override
//     public void compute(String label, String type, int iterations) {
//         RelationshipType relationshipType = RelationshipType.withName(type);
//         labelMap = new Long2DoubleOpenHashMap();
//         boolean done = false;
//         int iteration = 0;
//         try ( Transaction tx = db.beginTx()) {
//             ResourceIterator<Node> nodes = db.findNodes(DynamicLabel.label(label));
//             while (nodes.hasNext()) {
//                 Node node = nodes.next();
//                 labelMap.put(node.getId(), node.getId());
//             }
// 
//             while (!done) {
//                 done = true;
//                 iteration++;
// 
//                 for( Relationship relationship : db.getAllRelationships()) {
//                     if (relationship.isType(relationshipType)) {
//                         long x = relationship.getStartNode().getId();
//                         long y = relationship.getEndNode().getId();
//                         if (x == y) { continue; }
//                         if (labelMap.get(x) > labelMap.get(y)){
//                             labelMap.put(x, labelMap.get(y));
//                             done = false;
//                         } else if (labelMap.get(x) < labelMap.get(y)) {
//                             labelMap.put(y, labelMap.get(x));
//                             done = false;
//                         }
//                     }
//                 }
// 
//                 if (iteration > iterations) {
//                     done = true;
//                 }
//             }
//         }
//     }
// 
//     @Override
//     public double getResult(long node) {
//         return labelMap != null ? labelMap.getOrDefault(node, -1D) : -1;
//     }
// 
//     @Override
//     public long numberOfNodes() {
//         return nodes;
//     };
// 
// }


import com.maxdemarzi.processing.labelpropagation.LabelPropagation;
import com.maxdemarzi.processing.labelpropagation.LabelPropagationMapStorage;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.neo4j.graphdb.GraphDatabaseService;
import org.neo4j.graphdb.Result;
import org.neo4j.graphdb.Transaction;
import org.neo4j.test.TestGraphDatabaseFactory;
import java.io.IOException;
import java.util.Collections;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import static org.junit.Assert.assertEquals;
    static ExecutorService pool = Utils.createPool(CPUS, CPUS*25);

    @Before
    public void setUp() {
        db = new TestGraphDatabaseFactory().newImpermanentDatabase();
        service = new Service();
        populateDb(db);
    }

    private void populateDb(GraphDatabaseService db) {
        try ( Transaction tx = db.beginTx()) {
            db.execute(TestObjects.MOVIES_QUERY);
            db.execute(TestObjects.KNOWS_QUERY);
            tx.success();
        }
    }

    @After
    public void tearDown() throws Exception {
        db.shutdown();
    }

    @Test
    public void shouldPropagateLabels() throws IOException {
        String response = service.labelPropagation("Person", "KNOWS", 20, db);
        assertEquals("LabelPropagation for Person and KNOWS Completed!", response);
    }

    @Test
    public void shouldGetPropagateLabelsMapStorage() throws IOException {
// Path: src/main/java/com/maxdemarzi/processing/labelpropagation/LabelPropagation.java
// public interface LabelPropagation extends Algorithm {
// 
//     void compute(String label, String type, int iterations);
//     double getResult(long node);
//     long numberOfNodes();
//     default public String getPropertyName() {
//         return "label";
//     }
// 
// }
// 
// Path: src/main/java/com/maxdemarzi/processing/labelpropagation/LabelPropagationMapStorage.java
// public class LabelPropagationMapStorage implements LabelPropagation {
//     private final GraphDatabaseService db;
//     private final long nodes;
//     private Long2DoubleOpenHashMap labelMap;
// 
//     public LabelPropagationMapStorage(GraphDatabaseService db) {
//         this.db = db;
//         this.nodes = new NodeCounter().getNodeCount(db);
//     }
// 
//     @Override
//     public void compute(String label, String type, int iterations) {
//         RelationshipType relationshipType = RelationshipType.withName(type);
//         labelMap = new Long2DoubleOpenHashMap();
//         boolean done = false;
//         int iteration = 0;
//         try ( Transaction tx = db.beginTx()) {
//             ResourceIterator<Node> nodes = db.findNodes(DynamicLabel.label(label));
//             while (nodes.hasNext()) {
//                 Node node = nodes.next();
//                 labelMap.put(node.getId(), node.getId());
//             }
// 
//             while (!done) {
//                 done = true;
//                 iteration++;
// 
//                 for( Relationship relationship : db.getAllRelationships()) {
//                     if (relationship.isType(relationshipType)) {
//                         long x = relationship.getStartNode().getId();
//                         long y = relationship.getEndNode().getId();
//                         if (x == y) { continue; }
//                         if (labelMap.get(x) > labelMap.get(y)){
//                             labelMap.put(x, labelMap.get(y));
//                             done = false;
//                         } else if (labelMap.get(x) < labelMap.get(y)) {
//                             labelMap.put(y, labelMap.get(x));
//                             done = false;
//                         }
//                     }
//                 }
// 
//                 if (iteration > iterations) {
//                     done = true;
//                 }
//             }
//         }
//     }
// 
//     @Override
//     public double getResult(long node) {
//         return labelMap != null ? labelMap.getOrDefault(node, -1D) : -1;
//     }
// 
//     @Override
//     public long numberOfNodes() {
//         return nodes;
//     };
// 
// }


// Path: src/test/java/com/maxdemarzi/processing/LabelPropagationTest.java
import com.maxdemarzi.processing.labelpropagation.LabelPropagation;
import com.maxdemarzi.processing.labelpropagation.LabelPropagationMapStorage;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.neo4j.graphdb.GraphDatabaseService;
import org.neo4j.graphdb.Result;
import org.neo4j.graphdb.Transaction;
import org.neo4j.test.TestGraphDatabaseFactory;
import java.io.IOException;
import java.util.Collections;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import static org.junit.Assert.assertEquals;

    static ExecutorService pool = Utils.createPool(CPUS, CPUS*25);

    @Before
    public void setUp() {
        db = new TestGraphDatabaseFactory().newImpermanentDatabase();
        service = new Service();
        populateDb(db);
    }

    private void populateDb(GraphDatabaseService db) {
        try ( Transaction tx = db.beginTx()) {
            db.execute(TestObjects.MOVIES_QUERY);
            db.execute(TestObjects.KNOWS_QUERY);
            tx.success();
        }
    }

    @After
    public void tearDown() throws Exception {
        db.shutdown();
    }

    @Test
    public void shouldPropagateLabels() throws IOException {
        String response = service.labelPropagation("Person", "KNOWS", 20, db);
        assertEquals("LabelPropagation for Person and KNOWS Completed!", response);
    }

    @Test
    public void shouldGetPropagateLabelsMapStorage() throws IOException {
        LabelPropagation labelPropagation = new LabelPropagationMapStorage(db);