package tasks.bench;

import java.io.File;
import java.util.HashSet;
import java.util.Set;

import org.apache.tools.ant.Project;
import org.apache.tools.ant.ProjectHelper;
import org.apache.tools.ant.Target;

import data.BuildInfo;
import data.BuildType;
import tasks.util.Exec;

public class Compile {

	private BuildInfo buildInfo;

	public void compile(BuildInfo buildInfo) {
		this.buildInfo = buildInfo;
		for (BuildType bt : buildInfo.potentialBuildTypes.keySet()) {
			Set<File> usedBuildFiles = buildProject(bt);
			if (usedBuildFiles != null && !usedBuildFiles.isEmpty()) {
				buildInfo.usedBuildType = bt;
				buildInfo.usedBuildFiles = usedBuildFiles;
				buildInfo.compiles = true;
				return;
			}
		}
	}

	private Set<File> buildProject(BuildType bt) {
		Set<File> sucessfulBuildFiles = new HashSet<File>();
		for (File buildFile : buildInfo.potentialBuildTypes.get(bt)) {
			if (build(buildFile, bt))
				sucessfulBuildFiles.add(buildFile);
		}
		return sucessfulBuildFiles;
	}

	private boolean build(File buildFile, BuildType bt) {
		switch (bt) {
		case ANT:
			String command = getAntCommand(buildFile);
			if (command != null && Exec.exec("ant " + command, buildFile.getParentFile()) != null)
				return true;
			break;
		case MAVEN:
			if (Exec.exec("mvn compile", buildFile.getParentFile()) != null)
				return true;
			break;
		case GRADLE:
			if (Exec.exec("gradle build", buildFile.getParentFile()) != null)
				return true;
			break;
		default:
			throw new RuntimeException("Build type unknown: " + bt);
		}
		return false;
	}

	private String getAntCommand(File buildFile) {
		Project project = new Project();
		project.init();

		try {
			ProjectHelper.configureProject(project, buildFile);
		} catch (Exception e) {
			System.out.println("Error in parsing build file " + buildFile);
			return null;
		}

		for (Object o : project.getTargets().values()) {
			Target target = (Target) o;
			if (target.getName().equals("compile") || target.getName().equals("build"))
				return target.getName();
		}
		return null;
	}

}
