package org.jenkinsci.plugins.ghprb.manager.impl;


import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import jenkins.model.Jenkins;

import hudson.model.AbstractBuild;
import hudson.model.AbstractProject;
import hudson.tasks.junit.TestResult;
import hudson.tasks.junit.CaseResult;
import hudson.tasks.test.AggregatedTestResultAction;
import hudson.tasks.test.AggregatedTestResultAction.ChildReport;

import org.jenkinsci.plugins.ghprb.GhprbTrigger;
import org.jenkinsci.plugins.ghprb.manager.configuration.JobConfiguration;
import org.jenkinsci.plugins.ghprb.manager.GhprbBuildManager;

/**
 * @author mdelapenya (Manuel de la Peña)
 */
public abstract class GhprbBaseBuildManager implements GhprbBuildManager {

	public GhprbBaseBuildManager(AbstractBuild build) {
		this.build = build;
		this.jobConfiguration = buildDefaultConfiguration();
	}

	public GhprbBaseBuildManager(AbstractBuild build, JobConfiguration jobConfiguration) {
		this.build = build;
		this.jobConfiguration = jobConfiguration;
	}

	private JobConfiguration buildDefaultConfiguration() {
		return JobConfiguration.builder()
				.printStackTrace(false)
				.build();
	}

	/**
	 * Calculate the build URL of a build of default type. This will be overriden
	 * by specific build types.
	 * 
	 * @return the build URL of a build of default type
	 */
	public String calculateBuildUrl() {
		String publishedURL = GhprbTrigger.getDscp().getPublishedURL();

		return publishedURL + "/" + build.getUrl();
	}

	/**
	 * Return a downstream iterator of a build of default type. This will be overriden
	 * by specific build types.
	 *
	 * If the receiver of the call has no child projects, it will return an
	 * iterator over itself
	 *
	 * @return the downstream builds as an iterator
	 */
	public Iterator downstreamProjects() {
		List downstreamList = new ArrayList();

		downstreamList.add(build);

		return downstreamList.iterator();
	}

	public JobConfiguration getJobConfiguration() {
		return this.jobConfiguration;
	}

	/**
	 * Return the tests results of a build of default type. This will be overriden
	 * by specific build types.
	 *
	 * @return the tests result of a build of default type
	 */
	public String getTestResults() {
		return getAggregatedTestResults(build);
	}

	protected String getAggregatedTestResults(AbstractBuild build) {
		AggregatedTestResultAction testResultAction =
			build.getAction(AggregatedTestResultAction.class);

		StringBuilder sb = new StringBuilder();

		sb.append("<h2>Failed Tests: ");
		sb.append("<span class='status-failure'>");
		sb.append(testResultAction.getFailedTests().size());
		sb.append("</span></h2>");

		List<ChildReport> childReports = testResultAction.getChildReports();

		for (ChildReport report : childReports) {
			AbstractProject project =
				(AbstractProject)report.child.getProject();

			String baseUrl = Jenkins.getInstance().getRootUrl() + build.getUrl() +
				project.getShortUrl() + "testReport";

			TestResult result = (TestResult)report.result;

			sb.append("<h3>");
			sb.append("<a name='");
			sb.append(project.getName());
			sb.append("' />");
			sb.append("<a href='");
			sb.append(baseUrl);
			sb.append("'>");
			sb.append(project.getName());
			sb.append("</a>");
			sb.append(": ");
			sb.append("<span class='status-failure'>");
			sb.append(result.getFailCount());
			sb.append("</span></h3>");

			sb.append("<ul>");

			List<CaseResult> failedTests = result.getFailedTests();

			for (CaseResult failedTest : failedTests) {
				sb.append("<li>");
				sb.append("<a href='");
				sb.append(baseUrl);
				sb.append("/");
				sb.append(failedTest.getRelativePathFrom(result));
				sb.append("'>");
				sb.append("<strong>");
				sb.append(failedTest.getFullDisplayName());
				sb.append("</strong>");
				sb.append("</a>");

				if (getJobConfiguration().printStackTrace()) {
					sb.append("\n```\n");
					sb.append(failedTest.getErrorStackTrace());
					sb.append("\n```\n");
				}

				sb.append("</li>");
			}

			sb.append("</ul>");
		}

		return sb.toString();
	}

	protected AbstractBuild build;
	private JobConfiguration jobConfiguration;

}
@@ -2438,16 +2438,80 @@
 lass);%0A%0A
+%09%09if (testResultAction.getFailCount() %3C 1) %7B%0A%09%09%09return %22%22;%0A%09%09%7D%0A%0A
 %09%09String
@@ -2544,16 +2544,16 @@
 lder();%0A
-
 %0A%09%09sb.ap
@@ -2666,22 +2666,13 @@
 Fail
-edTests().size
+Count
 ());
@@ -2818,16 +2818,123 @@
 orts) %7B%0A
+%09%09%09TestResult result = (TestResult)report.result;%0A%0A%09%09%09if (result.getFailCount() %3C 1) %7B%0A%09%09%09%09continue;%0A%09%09%09%7D%0A%0A
 %09%09%09Abstr
@@ -3077,16 +3077,16 @@
 Url() +%0A
+
 %09%09%09%09proj
@@ -3124,59 +3124,8 @@
 %22;%0A%0A
-%09%09%09TestResult result = (TestResult)report.result;%0A%0A
 %09%09%09s

Add fail fast conditions