package de.ugoe.cs.cpdp.dataprocessing;

import java.util.ArrayList;

import java.util.HashMap;

import weka.core.Attribute;
import weka.core.Instance;
import weka.core.Instances;

/**
 * Filter for the Repast Simulation of Software Projects.
 * 
 * Filters the training dataset in the following way: If 0 is no bug
 * and 1 means there is a bug in this artifact, then this filter
 * filters the dataset in this way:
 * 
 * 10010111000101110101111011101
 * x--x-x-----x-x---x-x----x---x
 * 
 * The instances, which are marked with x in this graphic are included
 * in the newly created dataset and form the trainingsdataset.
 * 
 * @author Fabian Trautsch
 *
 */

public class SimulationFilter implements IProcessesingStrategy{

	/**
	 * Does not have parameters. String is ignored.
	 * @param parameters ignored
	 */
	@Override
	public void setParameter(String parameters) {
		// dummy
		
	}

	
	/*
	 * (non-Javadoc)
	 * @see de.ugoe.cs.cpdp.dataprocessing.IProcessesingStrategy#apply(weka.core.Instances, weka.core.Instances)
	 */
	@Override
	public void apply(Instances testdata, Instances traindata) {
		Instances newDataSet = new Instances(traindata);
		traindata.delete();
		
		HashMap<Double, Instance> artifactNames = new HashMap<Double, Instance>();
		
		// This is to add all data, where the first occurence of the file has a bug
		ArrayList<Double> firstOccurenceArtifactNames = new ArrayList<Double>();
		
		// Sort dataset (StateID is connected to the date of commit: Lower StateID
		// means earlier commit than a higher stateID)
		Attribute wekaAttribute = newDataSet.attribute("Artifact.Target.StateID");
		newDataSet.sort(wekaAttribute);
		
		
		/*
		 * Logical summary:
		 * If there is an instance that dont have a bug, put it into the hashmap (only unique values in there)
		 * 
		 * If there is an instance, that hava a bug look up if it is in the hashmap already (this means:
		 * it does not had a bug before!): If this is true add it to a new dataset and remove it from
		 * the hashmap, so that new changes from "nonBug" -> "bug" for this file can be found.
		 * 
		 * If the instance has a bug and is not in the hashmap (this means: The file has a bug with its
		 * first occurence or this file only has bugs and not an instance with no bug), then (if it is
		 * not in the arrayList above) add it to the new dataset. This way it is possible to get
		 * the first occurence of a file, which has a bug
		 * 
		 */
		for(int i=0; i<newDataSet.numInstances(); i++) {
			Instance wekaInstance = newDataSet.instance(i);

			double newBugLabel = wekaInstance.classValue();
			Attribute wekaArtifactName = newDataSet.attribute("Artifact.Name");
			Double artifactName = wekaInstance.value(wekaArtifactName);
			
			if(newBugLabel == 0.0 && artifactNames.keySet().contains(artifactName)) {
				artifactNames.put(artifactName, wekaInstance);
			} else if(newBugLabel == 0.0 && !artifactNames.keySet().contains(artifactName)) {
				artifactNames.put(artifactName, wekaInstance);
			} else if(newBugLabel == 1.0 && artifactNames.keySet().contains(artifactName)) {
				traindata.add(wekaInstance);
				artifactNames.remove(artifactName);
			} else if(newBugLabel == 1.0 && !artifactNames.keySet().contains(artifactName)) {
				if(!firstOccurenceArtifactNames.contains(artifactName)) {
					traindata.add(wekaInstance);
					firstOccurenceArtifactNames.add(artifactName);
				}
			}
		}
		
		
		// If we have a file, that never had a bug (this is, when it is NOT in the
		// new created dataset, but it is in the HashMap from above) add it to
		// the new dataset
		
		double[] artifactNamesinNewDataSet = traindata.attributeToDoubleArray(0);
		HashMap<Double, Instance> artifactNamesCopy = new HashMap<Double, Instance>(artifactNames);
		
		
		for(Double artifactName : artifactNames.keySet()) {
	
			for(int i=0; i<artifactNamesinNewDataSet.length; i++) {
				if(artifactNamesinNewDataSet[i] == artifactName) {
					artifactNamesCopy.remove(artifactName);
				}
			}
		}
		
		for(Double artifact: artifactNamesCopy.keySet()) {
			traindata.add(artifactNamesCopy.get(artifact));
		}
		
	}

}
