/*******************************************************************************
 * Copyright (c) 2009, 2011 SAP AG and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 * 
 * Contributors:
 *     SAP AG - initial API and implementation
 ******************************************************************************/
package org.eclipse.ocl.examples.impactanalyzer.benchmark.preparation.model;

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

import modelmanagement.Package;

import org.eclipse.emf.common.util.TreeIterator;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.util.EcoreUtil;

/**
 * The {@link IncrementalResourceShrinker} class is responsible for cutting down
 * the size of emf models in one emf resource by removing packages and its model
 * elements bit by bit according to a dependency graph
 *
 * This class may be used for varying the size of models for benchmarking.
 *
 * @author Manuel Holzleitner (D049667)
 */

public class IncrementalResourceShrinker {

    public Collection<Resource> shrinkIncrementally(Resource fullSizeResource){
		ArrayList<Resource> result = new ArrayList<Resource>();
		
		int cloneId = 0;
		Resource nextResourceToShrink = ModelCloner.cloneResource(fullSizeResource, String.valueOf(cloneId));
		while(deletePackageWithFewestDependencies(nextResourceToShrink) >= 1){
			cloneId++;
			
		    result.add(nextResourceToShrink);
		    nextResourceToShrink = ModelCloner.cloneResource(nextResourceToShrink, String.valueOf(cloneId));
		}
		
		return result;    	
	}
    
    //FIXME: Needs refactoring. Extract combinational shrinking
    public void shrinkCombinational(Resource parent, ArrayList<Resource> result, ArrayList<Integer> visitedSizes){
      	PackageDependencyGraph dependencyGraph = new PackageDependencyGraph(parent);
		
    	List<Package> packageToDeleteList = calculatePossiblePackagesToDelete(dependencyGraph);
    	List<Resource> cloneList = new ArrayList<Resource>();
    	List<PackageDependencyGraph> dependencyGraphList = new ArrayList<PackageDependencyGraph>();
    	
    	
    	for(int i=0; i < packageToDeleteList.size(); i++){
    		Resource clone = ModelCloner.cloneResource(parent, String.valueOf(i));
    		cloneList.add(clone);
    		//List of packages which should be deleted of parent is not applicable for cloned resources
    		//Therefore recalculate packages to delete on clones and pick one alternative 
    		PackageDependencyGraph cloneDependencyGraph = new PackageDependencyGraph(clone);
    		dependencyGraphList.add(cloneDependencyGraph);
    		
    		List<Package> clonePackageToDeleteList = calculatePossiblePackagesToDelete(cloneDependencyGraph);
    		
    		if(cloneDependencyGraph.getNumberOfPackages() > 1){
	    		deletePackage(clonePackageToDeleteList.get(i), cloneDependencyGraph);
	    		
	    			int numberOfElementsInChild = getNumberOfElements(clone);
	    			if(!visitedSizes.contains(new Integer(numberOfElementsInChild))){
	    				result.add(clone);
	    				visitedSizes.add(numberOfElementsInChild);
	    			}
	    			System.out.println(visitedSizes.size());
    		}
    	}
    	
    	for(int i=0; i < packageToDeleteList.size(); i++){
    		if(dependencyGraphList.get(i).getNumberOfPackages() > 1 && visitedSizes.size() < 108){
    			shrinkCombinational(cloneList.get(i), result, visitedSizes);
    		}
    	}
    
    }
    
    private int getNumberOfElements(Resource resource){
	int resourceSize = 0;
	TreeIterator<EObject> iterator = resource.getAllContents();
	while (iterator.hasNext()) {
		iterator.next();
		resourceSize++;
	}
	return resourceSize;
    }
    
        
	private int deletePackageWithFewestDependencies(Resource resourceToShrink){
		//TODO: Actually, rebuilding the dependency graph should not be required for deleting the next package. Therefore, ensure
		// that after deleting a package the dependency graph is updated accordingly.
		PackageDependencyGraph dependencyGraph = new PackageDependencyGraph(resourceToShrink);
		
		ArrayList<Package> packagesToDeleteList = calculatePossiblePackagesToDelete(dependencyGraph);  	
		deletePackage(getPackageWithFewestDependencies(packagesToDeleteList, dependencyGraph), dependencyGraph);
	
		return dependencyGraph.getNumberOfPackages();
	}

	private ArrayList<Package> calculatePossiblePackagesToDelete(PackageDependencyGraph dependencyGraph) {
	int smallestAmountOfReferences = Integer.MAX_VALUE;
	for (Package pack : dependencyGraph.getAllPackages()) {
	    if (getListWithoutDuplicates(dependencyGraph.getDependencies().get(pack)).size() < smallestAmountOfReferences) {
		smallestAmountOfReferences = getListWithoutDuplicates(dependencyGraph.getDependencies().get(pack)).size();
	    }
	}
	ArrayList<Package> packagesToDeleteList = new ArrayList<Package>();
	for (Package pack : dependencyGraph.getAllPackages()) {
	    if (getListWithoutDuplicates(dependencyGraph.getDependencies().get(pack)).size() == smallestAmountOfReferences) {
		packagesToDeleteList.add(pack);
	    }
	}
	return packagesToDeleteList;
	}

	private Package getPackageWithFewestDependencies(ArrayList<Package> packagesToDeleteList, PackageDependencyGraph dependencyGraph){
		Package packageToDelete = null;
		if(packagesToDeleteList.size() == 1){
		    //System.out.println("match");
		    packageToDelete = packagesToDeleteList.get(0);
		}else if(packagesToDeleteList.size() > 1){
		    //System.out.println("choose");
		    packageToDelete = chooseBestPackageToDelete(packagesToDeleteList, dependencyGraph);
		}
		return packageToDelete;
	}

	private Package chooseBestPackageToDelete(ArrayList<Package> packagesToDeleteList, PackageDependencyGraph dependencyGraph) {
	
	Package packageToDelete = packagesToDeleteList.get(0);
	for(Package deletionCandidate : packagesToDeleteList){
	    if(dependencyGraph.getDependencies().get(deletionCandidate).size() < dependencyGraph.getDependencies().get(packageToDelete).size()){
		packageToDelete = deletionCandidate;
	    }
	}
	
	//System.out.println(dependencyGraph.getDependencies().get(packageToDelete).size());
	
	return packageToDelete;
	}

	private Package deletePackage(Package packageToDelete, PackageDependencyGraph dependencyGraph) {
	Package deletedPackage = null;

	System.out.println("\t\t\tDelete package: " + packageToDelete);
	
	//EcoreUtil.delete(packageToDelete, true);
	//packageWasDeleted = true;
	//deletedPackage = packageToDelete;
	
	for (Package key : dependencyGraph.getAllPackages()) {
	    if (key != null && key.equals(packageToDelete)) {
		
	    /*System.out.println("Elements: " + aggregatedElements.get(key).size());
		for (EObject elementToDelete : aggregatedElements.get(key)) {
		    if(!(elementToDelete instanceof Package)) {
			EcoreUtil.delete(elementToDelete);
		    }
		   // System.out.println("\t\t\t\t\tdeleted:" + elementToDelete);
		}*/
	    EcoreUtil.delete(key, true);
		deletedPackage = key;
	    }
	}
	
	dependencyGraph.removePackage(packageToDelete);
	
	return deletedPackage;
	}
	
	/* TODO: Delete this commented debug code in final implementation
	
	for (Package key : dependencies.keySet()) {
	    System.out.println("P: " + key + " Number:" + dependencies.get(key).size() + " Elements:"
		    + aggregatedElements.get(key).size());
	    for (Package subPackage : dependencies.get(key)) {
		System.out.println("\t\t" + subPackage);
	    }
	}
	
	System.out.println(aggregatedElements.size() + "/" + modelElementList.size() + "/" + dependencies.size());
	*/


    private <T> ArrayList<T> getListWithoutDuplicates(List<T> arlList) {
		ArrayList<T> result = new ArrayList<T>(arlList.size());
		java.util.HashSet<T> h = new java.util.HashSet<T>(arlList);
		result.addAll(h);
		return result;
	}
}
