package NFP.Algorithms;

import java.util.List;

import seg.jUCMNav.nfp.generated.*;

public class AggregateResponseTime {
	
	private ResponseTime aggregatedResponseTime;
	private DurationUnitKind aggregateUnit;
	private List<ResponseTime> ResponseTimes;
	private CompositionType composition;
	private ConvertTime convertTime;
	
	public ResponseTime getAggregateResponseTime(
			DurationUnitKind aggregateUnit, List<ResponseTime> ResponseTimes,
			CompositionType composition) {
		this.aggregateUnit=aggregateUnit;
		this.ResponseTimes=ResponseTimes;
		this.composition=composition;
		convertTime=new ConvertTime();
		initialize();
		if(this.composition == CompositionType.Sequence || this.composition == CompositionType.Loop){
			for (ResponseTime RT : this.ResponseTimes) {
				aggregatedResponseTime.setWorst(aggregatedResponseTime.getWorst()
						+convertTime.getConvertedValue(RT.getWorst(), RT.getUnit(), aggregateUnit));
				aggregatedResponseTime.setAverage(aggregatedResponseTime.getAverage()
						+convertTime.getConvertedValue(RT.getAverage(), RT.getUnit(), aggregateUnit));
				aggregatedResponseTime.setBest(aggregatedResponseTime.getBest()
						+convertTime.getConvertedValue(RT.getBest(), RT.getUnit(), aggregateUnit));
				aggregatedResponseTime.setConfidence(Math.min(aggregatedResponseTime.getConfidence(),RT.getConfidence()));
			}
		}
		if(this.composition == CompositionType.Concurrency || this.composition == CompositionType.Discriminator){
			for (ResponseTime RT : this.ResponseTimes) {
				aggregatedResponseTime.setWorst(Math.max(aggregatedResponseTime.getWorst()
						,convertTime.getConvertedValue(RT.getWorst(), RT.getUnit(), aggregateUnit)));
				aggregatedResponseTime.setAverage(Math.max(aggregatedResponseTime.getAverage()
						,convertTime.getConvertedValue(RT.getAverage(), RT.getUnit(), aggregateUnit)));
				aggregatedResponseTime.setBest(Math.max(aggregatedResponseTime.getBest()
						,convertTime.getConvertedValue(RT.getBest(), RT.getUnit(), aggregateUnit)));
				aggregatedResponseTime.setConfidence(Math.min(aggregatedResponseTime.getConfidence(),RT.getConfidence()));
			}
		}
		if(this.composition == CompositionType.ConditionalBranching){
			double partialAverageSum = 0;
			for (ResponseTime RT : this.ResponseTimes) {
				aggregatedResponseTime.setWorst(Math.max(aggregatedResponseTime.getWorst()
						,convertTime.getConvertedValue(RT.getWorst(), RT.getUnit(), aggregateUnit)));
				partialAverageSum = partialAverageSum + convertTime.getConvertedValue(RT.getAverage(), RT.getUnit(), aggregateUnit);
				aggregatedResponseTime.setBest(Math.min(aggregatedResponseTime.getBest()
						,convertTime.getConvertedValue(RT.getBest(), RT.getUnit(), aggregateUnit)));
				aggregatedResponseTime.setConfidence(Math.min(aggregatedResponseTime.getConfidence(),RT.getConfidence()));
			}
			aggregatedResponseTime.setAverage(partialAverageSum/this.ResponseTimes.size());
		}
		return aggregatedResponseTime;
	}
	
	private void initialize(){
		aggregatedResponseTime = new ResponseTime();
		aggregatedResponseTime.setUnit(aggregateUnit);
		aggregatedResponseTime.setWorst(0);
		aggregatedResponseTime.setAverage(0);
		aggregatedResponseTime.setBest(0);
		aggregatedResponseTime.setConfidence(100);
	}
}
