package beaform.dao;

import java.util.ArrayList;
import java.util.List;

import org.neo4j.graphdb.GraphDatabaseService;
import org.neo4j.graphdb.Label;
import org.neo4j.graphdb.Node;
import org.neo4j.graphdb.ResourceIterator;
import org.neo4j.graphdb.Transaction;

import beaform.entities.FormulaTag;

/**
 * This class handles all DB access for tags.
 *
 * @author Steven Post
 *
 */
public final class FormulaTagDAO {

	public static final String NAME = "name";

	private static final Label LABEL = Label.label("FormulaTag");

	private FormulaTagDAO() {
		// Utility classes should not have a public constructor.
	}

	public static List<FormulaTag> listAllTags() {
		final GraphDatabaseService graphDb = GraphDbHandler.getDbService();
		List<FormulaTag> tags = new ArrayList<>();

		try ( Transaction tx = graphDb.beginTx() ) {
			try ( ResourceIterator<Node> formulas = graphDb.findNodes(LABEL)) {
				while ( formulas.hasNext()) {
					final FormulaTag tag = nodeToTag(formulas.next());
					tags.add(tag);

				}
			}
			tx.success();
		}

		return tags;
	}

	public static Node findOrCreate(String tag) {
		final GraphDatabaseService graphDb = GraphDbHandler.getDbService();
		Node tagNode;
		try (Transaction tx = graphDb.beginTx()) {

			// See if the tag exist in the DB, if so, use it, otherwise create it
			tagNode = graphDb.findNode(LABEL, NAME, tag);
			if (tagNode == null) {
				tagNode = graphDb.createNode(LABEL);
				tagNode.setProperty(NAME, tag);
			}
			tx.success();
		}
		return tagNode;
	}

	public static Node findOrCreate(FormulaTag tag) {
		return findOrCreate(tag.getName());
	}

	public static Node findByName(String name) {
		final GraphDatabaseService graphDb = GraphDbHandler.getDbService();
		Node tagNode;
		try (Transaction tx = graphDb.beginTx()) {
			tagNode = graphDb.findNode(LABEL, NAME, name);
			tx.success();
		}
		return tagNode;
	}

	public static FormulaTag nodeToTag(Node tag) {

		if (!tagNodeHasCorrectLabel(tag)) {
			throw new InvalidFormulaException();
		}

		String name = (String) tag.getProperty(NAME);

		return new FormulaTag(name);
	}

	private static boolean tagNodeHasCorrectLabel(Node tagNode) {
		final Iterable<Label> labelIt = tagNode.getLabels();
		for (Label label : labelIt) {
			if (label.name().equals(LABEL.name())) {
				return true;
			}
		}
		return false;
	}

}

@@ -733,16 +733,22 @@
 ce();%0A%09%09
+final 
 List%3CFor
@@ -764,28 +764,8 @@
 tags
- = new ArrayList%3C%3E()
 ;%0A%0A%09
@@ -842,23 +842,23 @@
 r%3CNode%3E 
-formula
+tagNode
 s = grap
@@ -889,43 +889,322 @@
 %09%09%09%09
-while ( formulas.hasNext()) %7B%0A%09%09%09
+tags = listFromResourceIterator(tagNodes);%0A%09%09%09%7D%0A%09%09%09tx.success();%0A%09%09%7D%0A%0A%09%09return tags;%0A%09%7D%0A%0A%09private static List%3CFormulaTag%3E listFromResourceIterator(ResourceIterator%3CNode%3E tagNodes) %7B%0A%09%09final List%3CFormulaTag%3E tags = new ArrayList%3C%3E();%0A%0A%09%09while ( tagNodes.hasNext()) %7B%0A%09%09%09final Node formulaNode = tagNodes.next();%0A
 %09%09
+%09
 fina
@@ -1243,24 +1243,18 @@
 mula
-s.next()
+Node
 );%0A%09%09%09
-%09%09
 tags
@@ -1267,37 +1267,8 @@
 ag);
-%0A%0A%09%09%09%09%7D%0A%09%09%09%7D%0A%09%09%09tx.success();
 %0A%09%09%7D

Move the conversion from a ResourceIterator to a List into a separate function