/*******************************************************************************
 * Copyright (c) 2012 EclipseSource Muenchen GmbH.
 * 
 * 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:
 ******************************************************************************/
package org.eclipse.emf.emfstore.fuzzy.emf.diff;

import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.emfstore.fuzzy.emf.FuzzyUtil;
import org.eclipse.emf.emfstore.fuzzy.emf.config.TestConfig;
import org.eclipse.emf.emfstore.fuzzy.emf.config.TestRun;

/**
 * An implementation of {@link TestRunProvider} to provide {@link TestRun}s created by the CI-Server Hudson.
 * 
 * @author Julian Sommerfeldt
 * 
 */
public class HudsonTestRunProvider extends TestRunProvider {

	private static final String JOB = "job/";

	private static SAXReader saxReader = new SAXReader();

	private String hudsonUrl;

	private static String jobUrl;

	private int firstBuildNumber;

	private int secondBuildNumber;

	/**
	 * The prefix for hudson peroperties.
	 */
	public static final String PROP_HUDSON = ".hudson";

	/**
	 * The hudson url property.
	 */
	public static final String PROP_URL = ".url";

	/**
	 * The hudson artifact folder property.
	 */
	public static final String PROP_ARTIFACT_FOLDER = ".artifact.folder";

	/**
	 * The hudson port property.
	 */
	public static final String PROP_PORT = ".port";

	/**
	 * The name of the hudson job property.
	 */
	public static final String PROP_JOB = ".job";

	/**
	 * The property of the hudson diff job.
	 */
	public static final String PROP_DIFF_JOB = ".diffjob";

	private static final String LAST_BUILD = "lastBuild";

	/**
	 * An array containing all valid states of a hudson build. Valid means it can be used for creating diffs.
	 */
	public static final String[] VALID_STATES = new String[] { "SUCCESS", "UNSTABLE" };

	private static final String ARTIFACT = FuzzyUtil.getProperty(PROP_HUDSON + PROP_ARTIFACT_FOLDER, "/artifact/");

	/**
	 * Standard constructor using the last build and the build before the last build for reading testruns.
	 * 
	 * @throws DocumentException If it cannot read the buildnumbers correctly from hudson.
	 * @throws IOException If it cannot read the buildnumbers correctly from hudson.
	 */
	public HudsonTestRunProvider() throws DocumentException, IOException {
		initProperties();

		firstBuildNumber = getLastValidBuildNumber(
			Integer.parseInt(getFirstElementValue(jobUrl + LAST_BUILD + "/api/xml?tree=number")), jobUrl);
		secondBuildNumber = getLastValidBuildNumber(firstBuildNumber - 1, jobUrl);
	}

	/**
	 * Constructor using tow special numbers for testruns.
	 * 
	 * @param firstBuildNumber The number of the first build (first from the last one backwards, so it is later than the
	 *            second one).
	 * @param secondBuildNumber The number of the second build.
	 */
	public HudsonTestRunProvider(int firstBuildNumber, int secondBuildNumber) {
		initProperties();

		this.firstBuildNumber = firstBuildNumber;
		this.secondBuildNumber = secondBuildNumber;
	}

	private void initProperties() {
		hudsonUrl = getHudsonUrl();
		jobUrl = hudsonUrl + JOB + FuzzyUtil.getProperty(PROP_HUDSON + PROP_JOB, "Explorer") + "/";
	}

	private static String getHudsonUrl() {
		String port = FuzzyUtil.getProperty(PROP_HUDSON + PROP_PORT, null);
		return FuzzyUtil.getProperty(PROP_HUDSON + PROP_URL, "http://localhost") + (port != null ? (":" + port) : "")
			+ "/";
	}

	private static int getLastValidBuildNumber(int maxBuildNumber, String jobUrl) throws MalformedURLException,
		DocumentException {
		if (maxBuildNumber < 0) {
			throw new RuntimeException("There are not enough valid builds till now!");
		}
		if (isValidBuild(maxBuildNumber, jobUrl)) {
			return maxBuildNumber;
		} else {
			return getLastValidBuildNumber(maxBuildNumber - 1, jobUrl);
		}
	}

	private static boolean isValidBuild(int buildNumber, String jobUrl) throws MalformedURLException, DocumentException {
		String result = getFirstElementValue(jobUrl + buildNumber + "/api/xml?tree=result");
		for (String valid : VALID_STATES) {
			if (valid.equals(result)) {
				return true;
			}
		}
		return false;
	}

	@SuppressWarnings("unchecked")
	private static String getFirstElementValue(String url) throws MalformedURLException, DocumentException {
		Document doc = saxReader.read(new URL(url));
		List<Element> elements = doc.getRootElement().elements();
		if (elements.size() == 0) {
			throw new RuntimeException("There are no elements in the result of the url: " + url);
		}
		return elements.get(0).getText();
	}

	@Override
	public TestRun[] getTestRuns() throws IOException {

		TestRun[] runs = new TestRun[2];

		Resource resource = getTestRunResource(firstBuildNumber);
		if (!FuzzyUtil.resourceExists(resource)) {
			throw new RuntimeException("No TestRun file for first run!");
		}
		resource.load(null);

		runs[0] = getTestRun(resource);

		resource = getTestRunResource(secondBuildNumber);
		if (!FuzzyUtil.resourceExists(resource)) {
			throw new RuntimeException("No TestRun file for second run!");
		}
		resource.load(null);

		runs[1] = getTestRun(resource);

		return runs;
	}

	private Resource getTestRunResource(int buildNumber) {
		return FuzzyUtil.createResource(jobUrl + buildNumber + ARTIFACT + FuzzyUtil.FUZZY_FOLDER + FuzzyUtil.RUN_FOLDER
			+ getTestConfig().getId() + FuzzyUtil.FILE_SUFFIX);
	}

	/**
	 * @return All {@link TestConfig} which are loadable via this {@link HudsonTestRunProvider}.
	 */
	public List<TestConfig> getAllConfigs() {
		Resource resource = FuzzyUtil.createResource(jobUrl + firstBuildNumber + ARTIFACT + FuzzyUtil.FUZZY_FOLDER
			+ FuzzyUtil.TEST_CONFIG_FILE);
		try {
			resource.load(null);
		} catch (IOException e) {
			throw new RuntimeException("Could not load configs file!", e);
		}
		List<TestConfig> configs = new ArrayList<TestConfig>();
		for (EObject obj : resource.getContents()) {
			if (obj instanceof TestConfig) {
				configs.add((TestConfig) obj);
			}
		}
		return configs;
	}

	/**
	 * @return The diff resource created by hudson.
	 * @throws DocumentException 
	 * 			in case an error occurs during obtainment of the resource.
	 * @throws MalformedURLException
	 * 			in case an error occurs during obtainment of the resource.
	 */
	public static Resource getDiffResource() throws MalformedURLException, DocumentException {
		String diffJobUrl = getHudsonUrl() + JOB + FuzzyUtil.getProperty(PROP_HUDSON + PROP_DIFF_JOB, "Diff") + "/";
		int lastValidNumber = getLastValidBuildNumber(
			Integer.parseInt(getFirstElementValue(diffJobUrl + LAST_BUILD + "/api/xml?tree=number")), diffJobUrl);
		return FuzzyUtil.createResource(diffJobUrl + lastValidNumber + ARTIFACT + FuzzyUtil.FUZZY_FOLDER + "diff"
			+ FuzzyUtil.FILE_SUFFIX);
	}
}