/**
 * Copyright (c) 2019 CEA LIST.
 * 
 * All rights reserved. This program and the accompanying materials
 * are the property of the CEA. 
 * Any use is subject to specific agreement with the CEA.
 * Contributors:
 * 
 * 		Gabriel Pedroza (CEA LIST) - API extensions and modifications
 * 
 * 
 */
package org.eclipse.papyrus.pdp4eng.designer.datastrategies.command;

import java.util.ArrayList;
import java.util.Iterator;

import org.eclipse.emf.common.util.BasicEList;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.transaction.RecordingCommand;
import org.eclipse.emf.transaction.TransactionalEditingDomain;
import org.eclipse.papyrus.pdp4eng.designer.datastrategies.ui.KAnonymityDialog;
import org.eclipse.papyrus.pdp4eng.designer.datastrategies.ui.KAnonymityOutcomesDialog;
import org.eclipse.uml2.uml.Classifier;
import org.eclipse.uml2.uml.Element;
import org.eclipse.uml2.uml.PackageableElement;
import org.eclipse.uml2.uml.Property;
import org.eclipse.uml2.uml.Stereotype;


public class KAnonymityCommand extends RecordingCommand {

	public Element elmt;

	public KAnonymityCommand(TransactionalEditingDomain domain, Element element) {
		super(domain);
		this.elmt = element;
		// TODO Auto-generated constructor stub
	}

	public KAnonymityCommand(TransactionalEditingDomain domain, String label) {
		super(domain, label);
		// TODO Auto-generated constructor stub
	}

	public KAnonymityCommand(TransactionalEditingDomain domain, String label, String description) {
		super(domain, label, description);
		// TODO Auto-generated constructor stub
	}

	@Override
	protected void doExecute() {
		// TODO Auto-generated method stub
		EList<Stereotype> selectedStereotypeList = elmt.getAppliedStereotypes();
		EList<Element> tableElementsList = new BasicEList<Element>();
		if (selectedStereotypeList.size()>0) {
			// Get the stereotype from the element selected
			Stereotype selectedStereotype = selectedStereotypeList.get(0);
			if (selectedStereotype!=null) {

				// Gather all elements having the selected stereotype
				tableElementsList = getTableElementsList(selectedStereotype);

				// Create and open the k-anonymity dialog
				KAnonymityDialog kAnonymityDialog=new KAnonymityDialog(selectedStereotype);
				kAnonymityDialog.open();

				ArrayList<Property> propertiesList = kAnonymityDialog.getSelectedProperty();
				
				EList<Element> KanonymizedTable = computeEqualitySetsWrtQI(selectedStereotype, tableElementsList, propertiesList);
				
				ArrayList<Integer> cardinalityEqualitySetsQI = computeEqualitySetsCardinalityWrtQI(selectedStereotype, tableElementsList, propertiesList);
				
				for (Iterator<Integer> cardinalityEqualitySetsQIIt = cardinalityEqualitySetsQI.iterator(); cardinalityEqualitySetsQIIt.hasNext();) {
					System.out.println("Cardinality: "+cardinalityEqualitySetsQIIt.next().toString());
				}
				int kAnonymityTarget = kAnonymityDialog.getKvalue();
				int kAnonymityValue = KAnonymityAlgorithm(selectedStereotype, tableElementsList, propertiesList);
				
				System.out.println("K-anonymity value: "+ kAnonymityValue);
				
				int[] lowerUpperBounds = computeLowerUpperBounds(selectedStereotype, tableElementsList, propertiesList);

				
				KAnonymityOutcomesDialog kAnonymityOutcomes = new KAnonymityOutcomesDialog(KanonymizedTable, 
						propertiesList, 
						kAnonymityTarget, 
						kAnonymityValue, lowerUpperBounds);
				
			}	
		}
	}
	
	/**
	 * 
	 * @param stereotype
	 * @return
	 */
	public EList<Element> getTableElementsList(Stereotype stereotype){
		EList<Element> tableElementsList = new BasicEList<Element>();

		// Gather all elements within the parent package
		PackageableElement parentPackage = elmt.getModel().getNearestPackage();
		if (parentPackage!=null) {
			EList<Element> parentPackageElements = parentPackage.getOwnedElements();
			// Filter elements according to the chosen stereotype
			for (Iterator<Element> elementsListIt = parentPackageElements.iterator(); elementsListIt.hasNext() ;){
				Element tgtElement = elementsListIt.next();
				if ((tgtElement!=null) && (tgtElement instanceof org.eclipse.uml2.uml.Classifier) ){
					Classifier tgtClassElement = (Classifier) tgtElement;
					// Obtain list of applied stereotypes
					EList<Stereotype>  tgtClassStLst = tgtClassElement.getAppliedStereotypes();
					// Find if the list includes the chosen stereotype
					if (tgtClassStLst!=null){
						boolean notfound = true;
						for (Iterator<Stereotype> tgtClassStLstIt = tgtClassStLst.iterator(); tgtClassStLstIt.hasNext() && notfound;){
							Stereotype tgtClassSt = tgtClassStLstIt.next();
							if (tgtClassSt!=null && tgtClassSt.getName().equals(stereotype.getName())){
								notfound = false;
								if (!tableElementsList.contains(tgtElement)){
									tableElementsList.add((Element) tgtElement);	
								}
							} 
						}
					}
				}
			}
		}
		return tableElementsList;
	}
	
	/**
	 * 
	 * @param stereotype
	 * @param rowElement1
	 * @param rowElement2
	 * @param QuasiIdentifiers
	 * @return
	 */
	public boolean compareTwoRowElements(Stereotype stereotype, Element rowElement1, Element rowElement2, ArrayList<Property> QuasiIdentifiers) {
		boolean result = true;
		for (Iterator<Property> QuasiIdentifierIt = QuasiIdentifiers.iterator(); QuasiIdentifierIt.hasNext() && result;) {
			Property property = QuasiIdentifierIt.next();
			if (rowElement1!=null && 
					rowElement2!= null && 
					rowElement1.getValue(stereotype, property.getName())!=null && 
					rowElement2.getValue(stereotype, property.getName())!=null) {
				if (!(rowElement1.getValue(stereotype, property.getName()).equals(rowElement2.getValue(stereotype, property.getName()))) ) {
					result = false;
				}
			} else {
				result = false;
			}
		}
		return result;
	}
	
	/**
	 * 
	 * @param stereotype
	 * @param refRowElement
	 * @param tableElementsList
	 * @param QuasiIdentifiers
	 * @return
	 */
	public int countEqualRowsWrtQuasiIdentifiers(Stereotype stereotype, Element refRowElement, EList<Element> tableElementsList, ArrayList<Property> QuasiIdentifiers) {
		int result = 0;
		Element element;
		for (Iterator<Element> tableElementsListIt = tableElementsList.iterator(); tableElementsListIt.hasNext();) {
			element = tableElementsListIt.next();
			if (element!=null && element instanceof org.eclipse.uml2.uml.Classifier) {
				if (compareTwoRowElements(stereotype, refRowElement, element, QuasiIdentifiers)) {
					result++;
				}	
			}
		}
		return result;
	}
	
	/**
	 * 
	 * @param stereotype
	 * @param refRowElement
	 * @param tableElementsList
	 * @param QuasiIdentifiers
	 * @return
	 */
	public EList<Element> getEqualRowsWrtQuasiIdentifiers(Stereotype stereotype, Element refRowElement, EList<Element> tableElementsList, ArrayList<Property> QuasiIdentifiers) {
		EList<Element> equalityElementsWrtQI = new BasicEList<Element>();
		Element element;
		for (Iterator<Element> tableElementsListIt = tableElementsList.iterator(); tableElementsListIt.hasNext();) {
			element = tableElementsListIt.next();
			if (element!=null && element instanceof org.eclipse.uml2.uml.Classifier) {
				if (compareTwoRowElements(stereotype, refRowElement, element, QuasiIdentifiers)) {
					equalityElementsWrtQI.add(element);
				}	
			}
		}
		return equalityElementsWrtQI;
	}
	
	/**
	 * 
	 * @param stereotype
	 * @param tableElementsList
	 * @param QuasiIdentifiers
	 * @return
	 */
	public ArrayList<Integer> computeEqualitySetsCardinalityWrtQI(Stereotype stereotype, EList<Element> tableElementsList, ArrayList<Property> QuasiIdentifiers){
		ArrayList<Integer> cardinalityEqualitySetsQI = new ArrayList<Integer>();
		EList<Element> equalityElementsWrtQI = new BasicEList<Element>();
		if (stereotype!=null && tableElementsList!=null && QuasiIdentifiers!=null && 
				tableElementsList.size()>0 && QuasiIdentifiers.size()>0) {
			int cardinality = 0;
			for (Iterator<Element> tableElementsListIt = tableElementsList.iterator(); tableElementsListIt.hasNext();) {
				Element element = tableElementsListIt.next();
				if (countEqualRowsWrtQuasiIdentifiers(stereotype, element, equalityElementsWrtQI, QuasiIdentifiers)==0) {
					cardinality = countEqualRowsWrtQuasiIdentifiers(stereotype, element, tableElementsList, QuasiIdentifiers);
					cardinalityEqualitySetsQI.add(cardinality);
					equalityElementsWrtQI.add(element);
				}
			}
		}
		return cardinalityEqualitySetsQI;
	}
	
	/**
	 * 
	 * @param stereotype
	 * @param tableElementsList
	 * @param QuasiIdentifiers
	 * @return
	 */
	public EList<Element> computeEqualitySetsWrtQI(Stereotype stereotype, EList<Element> tableElementsList, ArrayList<Property> QuasiIdentifiers){
		EList<Element> equalityElementsWrtQI = new BasicEList<Element>();
		if (stereotype!=null && tableElementsList!=null && QuasiIdentifiers!=null && 
				tableElementsList.size()>0 && QuasiIdentifiers.size()>0) {
			for (Iterator<Element> tableElementsListIt = tableElementsList.iterator(); tableElementsListIt.hasNext();) {
				Element element = tableElementsListIt.next();
				if (countEqualRowsWrtQuasiIdentifiers(stereotype, element, equalityElementsWrtQI, QuasiIdentifiers)==0) {
					equalityElementsWrtQI.addAll(getEqualRowsWrtQuasiIdentifiers(stereotype, element, tableElementsList, QuasiIdentifiers));
				}
			}
		}
		return equalityElementsWrtQI;
	}
	
	/**
	 * 
	 * @param stereotype
	 * @param tableElementsList
	 * @param QuasiIdentifiers
	 * @return
	 */
	public int KAnonymityAlgorithm(Stereotype stereotype, EList<Element> tableElementsList, ArrayList<Property> QuasiIdentifiers) {
		int kvalue = 0;
		ArrayList<Integer> cardinalityEqualitySetsQI = new ArrayList<Integer>();
		if (stereotype!=null && tableElementsList!=null && QuasiIdentifiers != null && 
				tableElementsList.size()>0 && QuasiIdentifiers.size()>0) {
			cardinalityEqualitySetsQI = computeEqualitySetsCardinalityWrtQI(stereotype, tableElementsList, QuasiIdentifiers);
			if (cardinalityEqualitySetsQI!=null && cardinalityEqualitySetsQI.size()>0) {
				kvalue = cardinalityEqualitySetsQI.get(0);
				for (Iterator<Integer> cardinalityEqualitySetsQIIt = cardinalityEqualitySetsQI.iterator(); 
						cardinalityEqualitySetsQIIt.hasNext();) {
					Integer value = cardinalityEqualitySetsQIIt.next();
					if (value < kvalue) {
						kvalue = value;
					}
				}
			}
		}
		
		return kvalue;
	}
	
	/**
	 * 
	 * @param stereotype
	 * @param tableElementsList
	 * @param QuasiIdentifiers
	 * @return
	 */
	public int[] computeLowerUpperBounds(Stereotype stereotype, EList<Element> tableElementsList, ArrayList<Property> QuasiIdentifiers){
		int[] lowerUpperBounds = new int[2];
		ArrayList<Integer> equalitySetsCardinality = computeEqualitySetsCardinalityWrtQI(stereotype, tableElementsList, QuasiIdentifiers);
		int kvalue = KAnonymityAlgorithm(stereotype, tableElementsList, QuasiIdentifiers);
		int lower = 0;
		int upper = 0;
		boolean notfound = true;
		for (Iterator<Integer> equalitySetsCardinalityIt = equalitySetsCardinality.iterator(); equalitySetsCardinalityIt.hasNext() && notfound; ) {
			Integer aux = equalitySetsCardinalityIt.next();
			if (aux == kvalue) {
				notfound=false;
			} else {
				lower += aux;
			}
		}
		upper = lower + kvalue;
		lowerUpperBounds[0] = lower;
		lowerUpperBounds[1] = upper;
		
		return lowerUpperBounds;
	}
	
}
