package eu.dnetlib.r2d2.neo4j.dao;

import org.neo4j.graphdb.Direction;
import org.neo4j.graphdb.Node;
import org.neo4j.graphdb.Relationship;

/**
 * When deleting a node from the database, all of its relations must be also
 * deleted. What happens for the other end of each relation depends on the
 * node type.
 * 
 * This class defines what will happen with each related node.
 * 
 * Name courtesy of Katerina :)
 *  
 * @author antleb
 *
 */
public abstract class ExterminationPolicy {
	/**
	 * While deleting thisNode, a relation rel was found with the otherNode, 
	 * with direction dir (focused on thisNode).
	 *  
	 * @param thisNode
	 * @param otherNode
	 * @param direction
	 * @param rel
	 * 
	 * @return true if otherNode should be deleted, false otherwise.
	 */
	public abstract boolean encounteredRelation(Node thisNode, Node otherNode, Direction direction, Relationship rel);
	
	public abstract String getName();
	
	public static ExterminationPolicy DO_NOTHING = new ExterminationPolicy() {
		public boolean encounteredRelation(Node thisNode, Node otherNode, Direction direction, Relationship rel) {
			return false;
		}

		public String getName() {
			return "DO_NOTHING";
		}
	};
	
	public static ExterminationPolicy CASCADE = new ExterminationPolicy() {
		public boolean encounteredRelation(Node thisNode, Node otherNode, Direction direction, Relationship rel) {
			return true;
		}
		
		public String getName() {
			return "CASCADE";
		}
	};
	
	public static ExterminationPolicy CASCADE_INCOMING = new ExterminationPolicy() {
		public boolean encounteredRelation(Node thisNode, Node otherNode, Direction direction, Relationship rel) {
			
			if (direction.equals(Direction.INCOMING)) {
				return true;
			}
			
			return false;
		}
		
		public String getName() {
			return "CASCADE_INCOMING";
		}
	};
	
	public static ExterminationPolicy CASCADE_OUTGOING = new ExterminationPolicy() {
		public boolean encounteredRelation(Node thisNode, Node otherNode, Direction direction, Relationship rel) {
			
			if (direction.equals(Direction.OUTGOING)) {
				return true;
			}
			
			return false;
		}
		
		public String getName() {
			return "CASCADE_OUTGOING";
		}
	};
}