package org.eclipse.emf.henshin.variability.matcher;

import java.util.BitSet;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.henshin.model.And;
import org.eclipse.emf.henshin.model.Attribute;
import org.eclipse.emf.henshin.model.Edge;
import org.eclipse.emf.henshin.model.Formula;
import org.eclipse.emf.henshin.model.Graph;
import org.eclipse.emf.henshin.model.GraphElement;
import org.eclipse.emf.henshin.model.HenshinFactory;
import org.eclipse.emf.henshin.model.HenshinPackage;
import org.eclipse.emf.henshin.model.Mapping;
import org.eclipse.emf.henshin.model.NestedCondition;
import org.eclipse.emf.henshin.model.Node;
import org.eclipse.emf.henshin.model.Not;
import org.eclipse.emf.henshin.model.Rule;
import org.eclipse.emf.henshin.variability.matcher.VariabilityAwareEngine.RuleInfo;
import org.eclipse.emf.henshin.variability.wrapper.VariabilityFactory;
import org.eclipse.emf.henshin.variability.wrapper.VariabilityGraphElement;

import aima.core.logic.propositional.parsing.ast.Sentence;

/**
 * This class prepares a variability-based rule for variability-based
 * application and matching. If the rule is expected to be used later, it is
 * required to call the undo() method after the application has been performed.
 * 
 * @author Daniel Str�ber
 *
 */
public class RulePreparator {
	public Rule rule;
	public boolean checkDangling;
	private boolean injectiveMatching;
	private boolean injectiveMatchingOriginal;
	private boolean baseRule;
	
	public HashSet<Node> removeNodes;
	public HashSet<Edge> removeEdges;
	public HashSet<Attribute> removeAttributes;
	public Map<Edge, Node> removeEdgeSources;
	public Map<Edge, Node> removeEdgeTargets;
	public Set<Mapping> removeMappings;
	public HashMap<EObject, EObject> removeElementContainers;
	public HashSet<Formula> removeFormulas;
	public HashMap<Mapping, EStructuralFeature> removeMappingContainingRef;
	public HashMap<Formula, EStructuralFeature> removeFormulaContainingRef;
	public HashMap<Formula, EObject> pulledUpFormulasToContainer;
	public HashMap<Formula, EStructuralFeature> pulledUpFormulasToContainingRef;
	public HashMap<Formula, EObject> pulledUpFormulasToOldContainer;
	public HashMap<Formula, EStructuralFeature> pulledUpFormulasToOldContainingRef;
	

	public RulePreparator(Rule rule) {
		this.rule = rule;
		this.checkDangling = rule.isCheckDangling();
	}
	
	
	/**
	 * Prepares the rule for variability-based merging and rule application:
	 * rejected elements and removed and the "injective" flag is set. Assumes
	 * that the reject() method has been invoked method before.
	 * 
	 * @param rule
	 * @param ruleInfo
	 * @param rejected
	 * @param executed
	 * @return
	 */
	public BitSet prepare(RuleInfo ruleInfo, Set<Sentence> rejected,
			boolean injectiveMatching, boolean baseRule) {
		this.baseRule = baseRule;
		this.injectiveMatching = injectiveMatching;
		injectiveMatchingOriginal = ruleInfo.rule.isInjectiveMatching();
		removeElementContainers = new HashMap<EObject, EObject>();
		removeNodes = new HashSet<Node>();
		removeEdges = new HashSet<Edge>();
		removeAttributes = new HashSet<Attribute>();
		removeEdgeSources = new HashMap<Edge, Node>();
		removeEdgeTargets = new HashMap<Edge, Node>();
		removeMappings = new HashSet<Mapping>();
		removeMappingContainingRef = new HashMap<Mapping, EStructuralFeature>();
		removeFormulaContainingRef = new HashMap<Formula, EStructuralFeature>();
		removeFormulas = new HashSet<Formula>();

		fillMaps(ruleInfo, rejected);

		BitSet bs = getRepresentation(rule, removeAttributes, removeNodes,
				removeEdges, removeFormulas, injectiveMatching);

		doPreparation();
		return bs;
	}
	
	private <T extends GraphElement> void addElementToRemoveList(boolean geIsVariabilityAware, GraphElement ge, Collection<T> list) {
		if (geIsVariabilityAware) {
			list.add((T) ((VariabilityGraphElement)ge).getGraphElement());
		} else {
			list.add((T)ge);
		}
	}

	private void fillMaps(RuleInfo ruleInfo, Set<Sentence> rejected) {
		
		for (Sentence expr : rejected) {
			Set<GraphElement> elements = ruleInfo.getPc2Elem().get(expr);
			if (elements == null)
				continue;
			
			for (GraphElement ge : elements) {
				boolean geIsVariabilityAware = ge instanceof VariabilityGraphElement;
				
				if (ge instanceof Node) {
					addElementToRemoveList(geIsVariabilityAware, ge, removeNodes);
					Set<Mapping> mappings = ruleInfo.getNode2Mapping().get(
							(Node) ge);
					if (mappings != null) {
						removeMappings.addAll(mappings);
					}
					((Node) ge).getAllEdges().forEach(edge -> addElementToRemoveList(geIsVariabilityAware, edge, removeEdges));
				} else if (ge instanceof Edge) {
					addElementToRemoveList(geIsVariabilityAware, ge, removeEdges);
				} else if (ge instanceof Attribute) {
					addElementToRemoveList(geIsVariabilityAware, ge, removeAttributes);
				}
			
			}
		}
		
		if (baseRule && rule.getLhs().getFormula() != null) {
			removeFormulas.add(rule.getLhs().getFormula());
			removeElementContainers.put(rule.getLhs().getFormula(), rule.getLhs());
			removeFormulaContainingRef.put(rule.getLhs().getFormula(), rule.getLhs().getFormula().eContainingFeature());
		} else {
			for (NestedCondition ac : rule.getLhs().getNestedConditions()) {
				Sentence acPC = ruleInfo.getExpressions().get(VariabilityFactory.createVariabilityNestedCondition(ac).getPresenceCondition());
				if (rejected.contains(acPC)) {
					Formula removeFormula = null;
					if (ac.isNAC())
						removeFormula = (Formula) ac.eContainer();
					else if (ac.isPAC())
						removeFormula = ac;

					removeFormulas.add(removeFormula);
					removeElementContainers.put(removeFormula, removeFormula.eContainer());
					removeFormulaContainingRef.put(removeFormula, removeFormula.eContainingFeature());
				}	
			}	
		}
	}

	/**
	 * Prepares the rule for variability-based merging and rule application:
	 * rejected elements and removed and the "injective" flag is set. Assumes
	 * that the reject() method has been invoked method before.
	 */
	public void doPreparation() {
		if (removeNodes == null) {
			throw new IllegalStateException(
					"This method may only be invoked after reject() has been invoked.");
		}

		removeFormulas();

		for (Mapping m : removeMappings) {
			EStructuralFeature feature = m.eContainingFeature();
			removeMappingContainingRef.put(m, feature);
			removeElementContainers.put(m, m.eContainer());
			((EList) m.eContainer().eGet(feature)).remove(m);
		}
		for (Attribute a : removeAttributes) {
			removeElementContainers.put(a, a.getNode());
			a.getNode().getAttributes().remove(a);
		}
		for (Edge e : removeEdges) {
			removeElementContainers.put(e, e.getGraph());
			removeEdgeSources.put(e, e.getSource());
			removeEdgeTargets.put(e, e.getTarget());
			e.getGraph().getEdges().remove(e);
			e.getSource().getOutgoing().remove(e);
			e.getTarget().getIncoming().remove(e);
		}
		for (Node n : removeNodes) {
			removeElementContainers.put(n, n.getGraph());
			n.getGraph().getNodes().remove(n);
		}
		rule.setInjectiveMatching(injectiveMatching);
		rule.setCheckDangling(false); // Dangling edges are allowed in a partial
										// match.

	}

	/**
	 * Removes the formulas in the previously determined order.
	 */
	private void removeFormulas() {
		for (Formula formula : removeFormulas) {
			removeElementContainers.get(formula).eUnset(removeFormulaContainingRef.get(formula));
			removeElementContainers.get(formula).eSet(removeFormulaContainingRef.get(formula), HenshinFactory.eINSTANCE.createTrue());
		}		
	}

	/**
	 * Puts the rule back in its original state: rejected elements and
	 * "injectiveMatching" flag are restored.
	 */
	public void undo() {
		rule.setCheckDangling(checkDangling);
		rule.setInjectiveMatching(injectiveMatchingOriginal);

		for (Node n : removeNodes) {
			((Graph) removeElementContainers.get(n)).getNodes().add(n);
		}
		for (Edge e : removeEdges) {
			((Graph) removeElementContainers.get(e)).getEdges().add(e);
			removeEdgeSources.get(e).getOutgoing().add(e);
			removeEdgeTargets.get(e).getIncoming().add(e);
		}

		for (Attribute a : removeAttributes) {
			((Node) removeElementContainers.get(a)).getAttributes().add(a);
		}

		for (Mapping m : removeMappings) {
			EStructuralFeature feature = removeMappingContainingRef.get(m);
			@SuppressWarnings("unchecked")
			EList<Mapping> list = (EList<Mapping>) removeElementContainers.get(
					m).eGet(feature);
			list.add(m);
		}

		restoreFormulas();

	}

	/**
	 * Restores the formulas in the previously determined order.
	 */
	private void restoreFormulas() {
		for (Formula formula : removeFormulas) {
			removeElementContainers.get(formula).eSet(removeFormulaContainingRef.get(formula), formula);
		}
//		fix
//		for (Formula f:pulledUpFormulasToOldContainingRef.keySet()) {
//			EObject container = pulledUpFormulasToOldContainer.get(f);
//			container.eSet(pulledUpFormulasToOldContainingRef.get(f), f);
//		}
//		for (Formula f:removeFormulaContainingRef.keySet()) {
//			EObject container = removeElementContainers.get(f);
//			container.eSet(removeFormulaContainingRef.get(f), f);
//		}
	}
	/**
	 * Calling this method ensures that the elements to be removed can later be
	 * added in the correct order to produce the original rule.
	 * 
	 * @param formulas
	 *            All instances must be either a NestedCondition (i.e., a Graph)
	 *            or a NOT
	 */
	private void determineRemoveOrder(Set<Formula> formulas) {
		Formula outer = rule.getLhs().getFormula(); //
		if (outer instanceof Not || outer instanceof NestedCondition) {
			Formula formula = formulas.iterator().next();
			if (formula == outer) {
				removeElementContainers.put(formula, rule.getLhs());
				removeFormulaContainingRef.put(formula,
						HenshinPackage.Literals.GRAPH__FORMULA);
			}
		} else if (outer instanceof And) {
			determineRemoverOrder((And) outer, formulas, rule.getLhs(),
					HenshinPackage.Literals.GRAPH__FORMULA);
		} else {
			throw new IllegalArgumentException(
					"TODO: Only AND-based nesting of applications conditions supported yet.");
		}
	}

	private void determineRemoverOrder(And and, Set<Formula> formulas, EObject container,
			EReference feature) {
		if (formulas.contains(and.getLeft())
				&& formulas.contains(and.getRight())) {
			removeFormulaContainingRef.put(and, feature);
			removeElementContainers.put(and, container);
		}
		if (!formulas.contains(and.getLeft())
				&& formulas.contains(and.getRight())) {
			designatePullupChild(and.getLeft(), and, HenshinPackage.Literals.BINARY_FORMULA__LEFT, container, feature);
		}
		if (formulas.contains(and.getLeft())
				&& !formulas.contains(and.getRight())) {
			designatePullupChild(and.getRight(), and, HenshinPackage.Literals.BINARY_FORMULA__RIGHT, container, feature);

		}
		if (!formulas.contains(and.getLeft())
				&& !formulas.contains(and.getRight())) {
			if (and.getLeft() instanceof And) {
				determineRemoverOrder((And) and.getLeft(), formulas, and,
						HenshinPackage.Literals.BINARY_FORMULA__LEFT);
			}
			if (and.getRight() instanceof And) {
				determineRemoverOrder((And) and.getRight(), formulas, and,
						HenshinPackage.Literals.BINARY_FORMULA__RIGHT);
			}
		}
	}

	private void designatePullupChild(Formula formula, And oldContainer,
			EReference oldFeature, EObject newContainer, EReference newFeature) {
		removeFormulaContainingRef.put(oldContainer, newFeature);
		removeElementContainers.put(oldContainer, newContainer);
		pulledUpFormulasToContainingRef.put(formula, newFeature);
		pulledUpFormulasToContainer.put(formula, newContainer);
		pulledUpFormulasToOldContainingRef.put(formula, oldFeature);
		pulledUpFormulasToOldContainer.put(formula, oldContainer);
	}


	/**
	 * A representation of the removed elements in a rule as a bit set. Aims at
	 * avoiding to match the same sub-rule on the same input twice.
	 * 
	 * @param rule
	 * @param deleteAttributes
	 * @param deleteNodes
	 * @param deleteEdges
	 * @param deleteFormula
	 * @param injectiveMatching
	 * @return
	 */
	private BitSet getRepresentation(Rule rule,
			Set<Attribute> deleteAttributes, Set<Node> deleteNodes,
			Set<Edge> deleteEdges, Set<Formula> deleteFormula,
			boolean injectiveMatching) {
		BitSet result = new BitSet(rule.getLhs().getNodes().size()
				+ rule.getLhs().getEdges().size()
				+ rule.getLhs().getNestedConditions().size() + 1);

		result.set(0, injectiveMatching);
		int i = 1;

		for (NestedCondition nc : rule.getLhs().getNestedConditions()) {
			result.set(i, !deleteFormula.contains(nc));
			i++;
		}

		for (Node n : rule.getLhs().getNodes()) {
			result.set(i, !deleteNodes.contains(n));
			i++;
			for (Attribute a : n.getAttributes()) {
				result.set(i, !deleteAttributes.contains(a));
				i++;
			}
		}
		for (Edge e : rule.getLhs().getEdges()) {
			result.set(i, !deleteEdges.contains(e));
			i++;
		}

		for (Node n : rule.getRhs().getNodes()) {
			result.set(i, !deleteNodes.contains(n));
			i++;
			for (Attribute a : n.getAttributes()) {
				result.set(i, !deleteAttributes.contains(a));
				i++;
			}
		}
		for (Edge e : rule.getRhs().getEdges()) {
			result.set(i, !deleteEdges.contains(e));
			i++;
		}

		return result;
	}

	public RulePreparator getSnapShot() {
		RulePreparator result = new RulePreparator(rule);
		result.removeNodes = new HashSet<Node>(removeNodes);
		result.removeEdges = new HashSet<Edge>(removeEdges);
		result.removeAttributes = new HashSet<Attribute>(removeAttributes);
		result.removeEdgeSources = new HashMap<Edge, Node>(removeEdgeSources);
		result.removeEdgeTargets = new HashMap<Edge, Node>(removeEdgeTargets);
		result.removeElementContainers = new HashMap<EObject, EObject>(
				removeElementContainers);
		result.removeFormulas = new HashSet<Formula>(removeFormulas);
		result.removeFormulaContainingRef = new HashMap<Formula, EStructuralFeature>(
				removeFormulaContainingRef);
//		result.pulledUpFormulasToContainer = new HashMap<Formula, EObject>(
//				pulledUpFormulasToContainer);
//		result.pulledUpFormulasToContainingRef = new HashMap<Formula, EStructuralFeature>(
//				pulledUpFormulasToContainingRef);
		result.removeMappings = new HashSet<Mapping>(removeMappings);
		result.removeMappingContainingRef = new HashMap<Mapping, EStructuralFeature>(
				removeMappingContainingRef);
//		result.pulledUpFormulasToOldContainingRef = new HashMap<Formula, EStructuralFeature>();
//		result.pulledUpFormulasToOldContainer = new HashMap<Formula, EObject>();

		return result;

	}

}