package de.ugoe.cs.autoquest.usability;

import java.util.EnumSet;
import java.util.List;

import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;

import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
import com.google.common.collect.Lists;

import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskTree;
import de.ugoe.cs.autoquest.usability.evaluation.result.UsabilityDefect;
import de.ugoe.cs.autoquest.usability.evaluation.rule.set.UsabilityRule;
import de.ugoe.cs.autoquest.usability.evaluation.rule.set.UsabilityRuleset;

@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class UsabilityEvaluationFacade {

    public static ExecuteUsabilityEvaluationStep applyUsabilityRuleset(UsabilityRuleset usabilityRuleset) {
	Preconditions.checkNotNull(usabilityRuleset);
        return new ExecuteUsabilityEvaluationStep(usabilityRuleset);
    }

    @AllArgsConstructor
    protected static class ExecuteUsabilityEvaluationStep {
	
	private final UsabilityRuleset usabilityRuleset;

	public UsabilityEvaluationReport evaluateUsabilityOf(ITaskTree taskTree) {
	    Preconditions.checkNotNull(taskTree);
	    EnumSet<? extends UsabilityRule> evaluationRules = usabilityRuleset.evaluationRules();
	    List<UsabilityDefect> evaluationResults = 
		    Lists.newArrayListWithCapacity(evaluationRules.size());
	    for(UsabilityRule usabilityRule : evaluationRules) {
		Optional<UsabilityDefect> ruleEvaluationResult = usabilityRule.evaluate(taskTree);
		if(ruleEvaluationResult.isPresent()) {
		    evaluationResults.add(ruleEvaluationResult.get());
		}
	    }
	    return UsabilityEvaluationReport.from(evaluationResults);
	}
	
    }

}
