package uk.ac.ebi.quickgo.ontology.traversal;

import uk.ac.ebi.quickgo.ontology.model.AncestorGraph;
import uk.ac.ebi.quickgo.ontology.model.OntologyRelationType;
import uk.ac.ebi.quickgo.ontology.model.OntologyRelationship;

import java.util.Deque;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;

/**
 * @author Tony Wardell
 * Date: 19/06/2017
 * Time: 10:11
 * Created with IntelliJ IDEA.
 */
public class SubGraphCalculator {

    public static Trampoline<AncestorGraph> createTrampoline(Deque<String> targetVertices, Set<String> stopNodes,
            OntologyRelationType[] targetRelations, AncestorGraph ancestorGraph, OntologyGraph ontologyGraph) {

        String target = targetVertices.pollFirst();

        //if target is null, or is a stop node, and we don't have any more to process then don't create any more
        if (Objects.isNull(target) || stopNodes.contains(target) && targetVertices.isEmpty()) {
            return new Trampoline<AncestorGraph>(){
                public AncestorGraph getValue() { return ancestorGraph; }
            };
        }

        //If target has any parents, add to deque
        Set<OntologyRelationship> parents = null;
        try {
            parents = ontologyGraph.parents(target, targetRelations);
        } catch (Exception e) {

            //Finish up if we have an exception
            return new Trampoline<AncestorGraph>(){
                public AncestorGraph getValue() { return ancestorGraph; }
            };
        }

        //Add parents to work queue
        if (!parents.isEmpty()) {
            parents.stream()
                   .map(p -> p.parent)
                   .forEach(parent -> targetVertices.addLast(parent));
        }

        //Add this vertex, and edges from this vertex to result
        ancestorGraph.vertices.add(target);
        ancestorGraph.edges.addAll(parents);

        //Create new Trampoline with current work queue.
        return new Trampoline<AncestorGraph>() {
            public Optional<Trampoline<AncestorGraph>> nextTrampoline() {
                return Optional.of(createTrampoline(targetVertices, stopNodes, targetRelations, ancestorGraph, ontologyGraph));
            }
        };
    }
}

@@ -324,16 +324,159 @@
 t;%0A%0A/**%0A
+ * Encapsulates the calculation of a edges for a single vertex, and the creation of further instances for vertexes%0A * attached to those edges.%0A
  * @auth
@@ -561,23 +561,16 @@
 EA.%0A */%0A
-public 
 class Su
@@ -593,23 +593,16 @@
  %7B%0A%0A    
-public 
 static T
@@ -858,24 +858,120 @@
 llFirst();%0A%0A
+        if(Objects.nonNull(target))%7B%0A            ancestorGraph.vertices.add(target);%0A        %7D%0A%0A
         //if
@@ -1156,33 +1156,32 @@
 tices.isEmpty())
- 
 %7B%0A            re
@@ -1330,264 +1330,246 @@
     
-//If target has any parents, add to deque%0A        Set%3COntologyRelationship%3E parents = null;%0A        try %7B%0A            parents = ontologyGraph.parents(target, targetRelations);%0A        %7D catch (Exception e) %7B%0A%0A            //Finish up if we have an e
+try %7B%0A            Set%3COntologyRelationship%3E parents = ontologyGraph.parents(target, targetRelations);%0A            ancestorGraph.edges.addAll(parents);%0A            addParentsToWorkQueue(targetVertices, parents);%0A%0A        %7D catch (E
 xception
 %0A   
@@ -1564,16 +1564,21 @@
 xception
+ e) %7B
 %0A       
@@ -1726,439 +1726,8 @@
  %7D%0A%0A
-        //Add parents to work queue%0A        if (!parents.isEmpty()) %7B%0A            parents.stream()%0A                   .map(p -%3E p.parent)%0A                   .forEach(parent -%3E targetVertices.addLast(parent));%0A        %7D%0A%0A        //Add this vertex, and edges from this vertex to result%0A        ancestorGraph.vertices.add(target);%0A        ancestorGraph.edges.addAll(parents);%0A%0A        //Create new Trampoline with current work queue.%0A
     
@@ -2003,11 +2003,241 @@
 %7D;%0A    %7D
+%0A%0A    private static void addParentsToWorkQueue(Deque%3CString%3E targetVertices, Set%3COntologyRelationship%3E parents) %7B%0A        parents.stream()%0A               .map(p -%3E p.parent)%0A               .forEach(targetVertices::addLast);%0A    %7D
 %0A%7D%0A

Add javadoc. Only add to vertex to ancestor graph if not null.