/*******************************************************************************
 * Copyright (c) 2000, 2010 IBM Corporation and others.
 * 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:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.test.performance.ui;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.PrintStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.StringTokenizer;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.SubMonitor;
import org.eclipse.swt.widgets.Display;
import org.eclipse.test.internal.performance.results.db.ConfigResults;
import org.eclipse.test.internal.performance.results.db.DB_Results;
import org.eclipse.test.internal.performance.results.db.PerformanceResults;
import org.eclipse.test.internal.performance.results.db.ScenarioResults;
import org.eclipse.test.internal.performance.results.utils.Util;
import org.osgi.framework.Bundle;

/**
 * Main class to generate performance results of all scenarios matching a given pattern
 * in one HTML page per component.
 *
 * @see #printUsage() method to see a detailed parameters usage
 */
public class GenerateResults {

/**
 * Prefix of baseline builds displayed in data graphs.
 * This field is set using <b>-baseline.prefix</b> argument.
 * <p>
 * Example:
 *		<pre>-baseline.prefix 3.2_200606291905</pre>
 *
 * @see #currentBuildPrefixes
 */
String baselinePrefix = null;

/**
 * Root directory where all files are generated.
 * This field is set using <b>-output</b> argument.
 * <p>
 * Example:
 * 	<pre>-output /releng/results/I20070615-1200/performance</pre>
 */
File outputDir;

/**
 * Root directory where all data are locally stored to speed-up generation.
 * This field is set using <b>-dataDir</b> argument.
 * <p>
 * Example:
 * 	<pre>-dataDir /tmp</pre>
 */
File dataDir;

/**
 * Arrays of 2 strings which contains config information: name and description.
 * This field is set using <b>-config</b> and/or <b>-config.properties</b> arguments.
 * <p>
 * Example:
 * <pre>
 * 	-config eclipseperflnx3_R3.3,eclipseperfwin2_R3.3,eclipseperflnx2_R3.3,eclipseperfwin1_R3.3,eclipseperflnx1_R3.3
 * 	-config.properties
 * 		"eclipseperfwin1_R3.3,Win XP Sun 1.4.2_08 (2 GHz 512 MB);
 * 		eclipseperflnx1_R3.3,RHEL 3.0 Sun 1.4.2_08 (2 GHz 512 MB);
 * 		eclipseperfwin2_R3.3,Win XP Sun 1.4.2_08 (3 GHz 2 GB);
 * 		eclipseperflnx2_R3.3,RHEL 3.0 Sun 1.4.2_08 (3 GHz 2 GB);
 * 		eclipseperflnx3_R3.3,RHEL 4.0 Sun 1.4.2_08 (3 GHz 2.5 GB)"
 * </pre>
 * Note that:
 * <ul>
 * <li>if only <b>-config</b> is set, then configuration name is used for description </li>
 * <li>if only <b>-config.properties</b> is set, then all configurations defined with this argument are generated
 * <li>if both arguments are defined, then only configurations defined by <b>-config</b> argument are generated,
 * 		<b>-config.properties</b> argument is only used to set the configuration description.</li>
 * </ul>
 */
String[][] configDescriptors;

/**
 * Scenario pattern used to generate performance results.
 * This field is set using <b>-scenarioPattern</b> argument.
 * <p>
 * Note that this pattern uses SQL conventions, not RegEx ones,
 * which means that '%' is used to match several consecutive characters
 * and '_' to match a single character.
 * <p>
 * Example:
 * 	<pre>-scenario.pattern org.eclipse.%.test</pre>
 */
String scenarioPattern;

/**
 * A list of prefixes for builds displayed in data graphs.
 * This field is set using <b>-currentPrefix</b> argument.
 * <p>
 * Example:
 * 	<pre>-current.prefix N, I</pre>
 *
 * @see #baselinePrefix
 */
List currentBuildPrefixes;

/**
 * A list of prefixes of builds to highlight in displayed data graphs.
 * This field is set using <b>-highlight</b> and/or <b>-highlight.latest</b> arguments.
 * <p>
 * Example:
 * 	<pre>-higlight 3_2</pre>
 */
List pointsOfInterest;

/**
 * Tells whether only fingerprints has to be generated.
 * This field is set to <code>true</code> if <b>-fingerprints</b> argument is specified.
 * <p>
 * Default is <code>false</code> which means that scenario data
 * will also be generated.
 *
 * @see #genData
 * @see #genAll
 */
boolean genFingerPrints = false;

/**
 * Tells whether only fingerprints has to be generated.
 * This field is set to <code>true</code> if <b>-data</b> argument is specified.
 * <p>
 * Default is <code>false</code> which means that fingerprints
 * will also be generated.
 *
 * @see #genFingerPrints
 * @see #genAll
 */
boolean genData = false;

/**
 * Tells whether only fingerprints has to be generated.
 * This field is set to <code>false</code>
 * if <b>-fingerprints</b> or <b>-data</b> argument is specified.
 * <p>
 * Default is <code>true</code> which means that scenario data
 * will also be generated.
 *
 * @see #genData
 * @see #genFingerPrints
 */
boolean genAll = true;

/**
 * Tells whether information should be displayed in the console while generating.
 * This field is set to <code>true</code> if <b>-print</b> argument is specified.
 * <p>
 * Default is <code>false</code> which means that nothing is print during the generation.
 */
PrintStream printStream = null;

/**
 * Tells what should be the failure percentage threshold.
 * <p>
 * Default is 10%.
 */
int failure_threshold = 10; // PerformanceTestPlugin.getDBLocation().startsWith("net://");

PerformanceResults performanceResults;

public GenerateResults() {
}

public GenerateResults(boolean fingerprints, File data) {
	this.dataDir = data;
	this.genFingerPrints = fingerprints;
	this.genAll = !fingerprints;
	this.printStream = System.out;
}

/*
 * Parse the command arguments and create corresponding performance
 * results object.
 */
private void parse(String[] args) {
	StringBuffer buffer = new StringBuffer("Parameters used to generate performance results (");
	buffer.append(new SimpleDateFormat().format(new Date(System.currentTimeMillis())));
	buffer.append("):\n");
	int i = 0;
	int argsLength = args.length;
	if (argsLength == 0) {
		printUsage();
	}

	String currentBuildId = null;
	String baseline = null;
	String jvm = null;
	this.configDescriptors = null;

	while (i < argsLength) {
		String arg = args[i];
		if (!arg.startsWith("-")) {
		    System.err.println("ERROR: Unrecognized argument (arg) found, with value of >" + arg + "<");
			i++;
			continue;
		}
		if (argsLength == i + 1 && i != argsLength - 1) {
			System.out.println("Missing value for last parameter");
			printUsage();
		}
		if (arg.equals("-baseline")) {
			baseline = args[i + 1];
			if (baseline.startsWith("-")) {
				System.out.println("Missing value for "+arg+" parameter");
				printUsage();
			}
			buffer.append("	-baseline = "+baseline+'\n');
			i++;
			i++;
			continue;
		}
		if (arg.equals("-baseline.prefix")) {
			this.baselinePrefix = args[i + 1];
			if (this.baselinePrefix.startsWith("-")) {
				System.out.println("Missing value for "+arg+" parameter");
				printUsage();
			}
			buffer.append("	").append(arg).append(" = ").append(this.baselinePrefix).append('\n');
			i++;
			i++;
			continue;
		}
		if (arg.equals("-current.prefix")) {
			String idPrefixList = args[i + 1];
			if (idPrefixList.startsWith("-")) {
				System.out.println("Missing value for "+arg+" parameter");
				printUsage();
			}
			buffer.append("	").append(arg).append(" = ");
			String[] ids = idPrefixList.split(",");
			this.currentBuildPrefixes = new ArrayList();
			for (int j = 0; j < ids.length; j++) {
				this.currentBuildPrefixes.add(ids[j]);
				buffer.append(ids[j]);
			}
			buffer.append('\n');
			i++;
			i++;
			continue;
		}
		if (arg.equals("-highlight") || arg.equals("-highlight.latest")) {
			if (args[i + 1].startsWith("-")) {
				System.out.println("Missing value for "+arg+" parameter");
				printUsage();
			}
			buffer.append("	").append(arg).append(" = ");
			String[] ids = args[i + 1].split(",");
			this.pointsOfInterest = new ArrayList();
			for (int j = 0; j < ids.length; j++) {
				this.pointsOfInterest.add(ids[j]);
				buffer.append(ids[j]);
				if (j < ids.length - 1) {
				    buffer.append(",");
				}
			}
			buffer.append('\n');
			i++;
			i++;
			continue;
		}
		if (arg.equals("-current")) {
			currentBuildId  = args[i + 1];
			if (currentBuildId.startsWith("-")) {
				System.out.println("Missing value for "+arg+" parameter");
				printUsage();
			}
			buffer.append("	").append(arg).append(" = ").append(currentBuildId).append('\n');
			i++;
			i++;
			continue;
		}
		if (arg.equals("-jvm")) {
			jvm = args[i + 1];
			if (jvm.startsWith("-")) {
				System.out.println("Missing value for "+arg+" parameter");
				printUsage();
			}
			buffer.append("	").append(arg).append(" = ").append(jvm).append('\n');
			i++;
			i++;
			continue;
		}
		if (arg.equals("-output")) {
			String dir = args[++i];
			if (dir.startsWith("-")) {
				System.out.println("Missing value for "+arg+" parameter");
				printUsage();
			}
			this.outputDir = new File(dir);
			if (!this.outputDir.exists() && !this.outputDir.mkdirs()) {
				System.err.println("Cannot create directory "+dir+" to write results in!");
				throw new RuntimeException("Can not create directory " + dir);
				//System.exit(2);
			}
			buffer.append("	").append(arg).append(" = ").append(dir).append('\n');
			i++;
			continue;
		}
		if (arg.equals("-dataDir")) {
			String dir = args[++i];
			if (dir.startsWith("-")) {
				System.out.println("Missing value for "+arg+" parameter");
				printUsage();
			}
			this.dataDir = new File(dir);
			if (!this.dataDir.exists() && !this.dataDir.mkdirs()) {
				System.err.println("Cannot create directory "+dir+" to save data locally!");
				//System.exit(2);
				throw new RuntimeException("Can not create directory " + dir);
			}
			buffer.append("	").append(arg).append(" = ").append(dir).append('\n');
			i++;
			continue;
		}
		if (arg.equals("-config")) {
			String configs = args[i + 1];
			if (configs.startsWith("-")) {
				System.out.println("Missing value for "+arg+" parameter");
				printUsage();
			}
			String[] names = configs.split(",");
			int length = names.length;
			buffer.append("	").append(arg).append(" = ");
			for (int j=0; j<length; j++) {
				if (j>0) buffer.append(',');
				buffer.append(names[j]);
			}
			if (this.configDescriptors == null) {
				this.configDescriptors = new String[length][2];
				for (int j=0; j<length; j++) {
					this.configDescriptors[j][0] = names[j];
					this.configDescriptors[j][1] = names[j];
				}
			} else {
				int confLength = this.configDescriptors[0].length;
				int newLength = confLength;
				mainLoop: for (int j=0; j<confLength; j++) {
					for (int k=0; k<length; k++) {
						if (this.configDescriptors[j][0].equals(names[k])) {
							continue mainLoop;
						}
					}
					this.configDescriptors[j][0] = null;
					this.configDescriptors[j][1] = null;
					newLength--;
				}
				if (newLength < confLength) {
					String[][] newDescriptors = new String[newLength][2];
					for (int j=0, c=0; j<newLength; j++) {
						if (this.configDescriptors[c] != null) {
							newDescriptors[j][0] = this.configDescriptors[c][0];
							newDescriptors[j][1] = this.configDescriptors[c][1];
						} else {
							c++;
						}
					}
					this.configDescriptors = newDescriptors;
				}
			}
			buffer.append('\n');
			i++;
			i++;
			continue;
		}
		if (arg.equals("-config.properties")) {
			String configProperties = args[i + 1];
			if (configProperties.startsWith("-")) {
				System.out.println("Missing value for "+arg+" parameter");
				printUsage();
			}
			if (this.configDescriptors == null) {
				System.out.println("Missing -config parameter");
				printUsage();
			}
			int length = this.configDescriptors.length;
			StringTokenizer tokenizer = new StringTokenizer(configProperties, ";");
			buffer.append('\t').append(arg).append(" = '").append(configProperties).append("' splitted in ").append(length).append(" configs:");
			while (tokenizer.hasMoreTokens()) {
				String labelDescriptor = tokenizer.nextToken();
				String[] elements = labelDescriptor.trim().split(",");
				for (int j=0; j<length; j++) {
					if (elements[0].equals(this.configDescriptors[j][0])) {
						this.configDescriptors[j][1] = elements[1];
						buffer.append("\n\t\t+ ");
						buffer.append(elements[0]);
						buffer.append(" -> ");
						buffer.append(elements[1]);
					}
				}
			}
			buffer.append('\n');
			i++;
			i++;
			continue;
		}
		if (arg.equals("-scenario.filter") || arg.equals("-scenario.pattern")) {
			this.scenarioPattern= args[i + 1];
			if (this.scenarioPattern.startsWith("-")) {
				System.out.println("Missing value for "+arg+" parameter");
				printUsage();
			}
			buffer.append("	").append(arg).append(" = ").append(this.scenarioPattern).append('\n');
			i++;
			i++;
			continue;
		}
		if (arg.equals("-fingerprints")) {
			this.genFingerPrints = true;
			this.genAll = false;
			buffer.append("	").append(arg).append('\n');
			i++;
			continue;
		}
		if (arg.equals("-data")) {
			this.genData = true;
			this.genAll = false;
			buffer.append("	").append(arg).append('\n');
			i++;
			continue;
		}
		if (arg.equals("-print")) {
			this.printStream = System.out; // default is to print to console
			buffer.append("	").append(arg);
			i++;
			String printFile = i==argsLength ? null : args[i];
			if (printFile==null ||printFile.startsWith("-")) {
				buffer.append(" (to the console)").append('\n');
			} else {
			    i++;
				try {
					this.printStream = new PrintStream(new BufferedOutputStream(new FileOutputStream(printFile)));
				}
				catch (FileNotFoundException fnfe) {
					// use the console if the output file cannot be created
				}
				buffer.append(" (to file: ").append(printFile).append(")\n");
			}
			continue;
		}
		if (arg.equals("-failure.threshold")) {
			String value = args[i + 1];
			try {
				this.failure_threshold = Integer.parseInt(value);
				if (this.failure_threshold < 0) {
					System.out.println("Value for "+arg+" parameter must be positive.");
					printUsage();
				}
			}
			catch (NumberFormatException nfe) {
				System.out.println("Invalid value for "+arg+" parameter");
				printUsage();
			}
			buffer.append("	").append(arg).append(" = ").append(value).append('\n');
			i++;
			i++;
			continue;
		}
		// To get to hear mean "matched none". 
        System.err.println("ERROR: Unrecognized argument (arg) found, with value of >" + arg + "<");
        i++;
        continue;
	}
	if (this.printStream != null) {
		this.printStream.print(buffer.toString());
	}

	// Stop if some mandatory parameters are missing
	if (this.outputDir == null || this.configDescriptors == null || jvm == null) {
		printUsage();
	}

	// Set performance results
	setPerformanceResults(currentBuildId, baseline);
}

/*
 * Print component PHP file
 */
private void printComponent(/*PerformanceResults performanceResults, */String component) throws FileNotFoundException {
	if (this.printStream != null) this.printStream.print(".");
	File outputFile = new File(this.outputDir, component + ".php");
	PrintStream stream = new PrintStream(new BufferedOutputStream(new FileOutputStream(outputFile)));

	// Print header
	boolean isGlobal = component.startsWith("global");
	if (isGlobal) {
		File globalFile = new File(this.outputDir, "global.php");
		PrintStream gStream = new PrintStream(new BufferedOutputStream(new FileOutputStream(globalFile)));
		gStream.print(Utils.HTML_OPEN);
		gStream.print("</head>\n");
		gStream.print("<body>\n");
		gStream.print("<?php\n");
		gStream.print("	include(\"global_fp.php\");\n");
		gStream.print("?>\n");
		gStream.print("<table border=0 cellpadding=2 cellspacing=5 width=\"100%\">\n");
		gStream.print("<tbody><tr> <td colspan=3 align=\"left\" bgcolor=\"#0080c0\" valign=\"top\"><b><font color=\"#ffffff\" face=\"Arial,Helvetica\">\n");
		gStream.print("Detailed performance data grouped by scenario prefix</font></b></td></tr></tbody></table>\n");
		gStream.print("<a href=\"org.eclipse.ant.php?\">org.eclipse.ant*</a><br>\n");
		gStream.print("<a href=\"org.eclipse.compare.php?\">org.eclipse.compare*</a><br>\n");
		gStream.print("<a href=\"org.eclipse.core.php?\">org.eclipse.core*</a><br>\n");
		gStream.print("<a href=\"org.eclipse.jdt.core.php?\">org.eclipse.jdt.core*</a><br>\n");
		gStream.print("<a href=\"org.eclipse.jdt.debug.php?\">org.eclipse.jdt.debug*</a><br>\n");
		gStream.print("<a href=\"org.eclipse.jdt.text.php?\">org.eclipse.jdt.text*</a><br>\n");
		gStream.print("<a href=\"org.eclipse.jdt.ui.php?\">org.eclipse.jdt.ui*</a><br>\n");
		gStream.print("<a href=\"org.eclipse.jface.php?\">org.eclipse.jface*</a><br>\n");
		gStream.print("<a href=\"org.eclipse.osgi.php?\">org.eclipse.osgi*</a><br>\n");
		gStream.print("<a href=\"org.eclipse.pde.api.tools.php?\">org.eclipse.pde.api.tools*</a><br>\n");
		gStream.print("<a href=\"org.eclipse.pde.ui.php?\">org.eclipse.pde.ui*</a><br>\n");
		gStream.print("<a href=\"org.eclipse.swt.php?\">org.eclipse.swt*</a><br>\n");
		gStream.print("<a href=\"org.eclipse.team.php?\">org.eclipse.team*</a><br>\n");
		gStream.print("<a href=\"org.eclipse.ua.php?\">org.eclipse.ua*</a><br>\n");
		gStream.print("<a href=\"org.eclipse.ui.php?\">org.eclipse.ui*</a><br><p><br><br>\n");
		gStream.print("</body>\n");
		gStream.print(Utils.HTML_CLOSE);
		gStream.close();
	} else {
		stream.print(Utils.HTML_OPEN);
	}
	stream.print("<link href=\""+Utils.TOOLTIP_STYLE+"\" rel=\"stylesheet\" type=\"text/css\">\n");
	stream.print("<script src=\""+Utils.TOOLTIP_SCRIPT+"\"></script>\n");
	stream.print("<script src=\""+Utils.FINGERPRINT_SCRIPT+"\"></script>\n");
	stream.print(Utils.HTML_DEFAULT_CSS);

	// Print title
	stream.print("<body>");
	printComponentTitle(/*performanceResults, */component, isGlobal, stream);

	// print the html representation of fingerprint for each config
	Display display = Display.getDefault();
	if (this.genFingerPrints || this.genAll) {
		final FingerPrint fingerprint = new FingerPrint(component, stream, this.outputDir);
		display.syncExec(
			new Runnable() {
				public void run(){
					try {
						fingerprint.print(GenerateResults.this.performanceResults);
					} catch (Exception ex) {
						ex.printStackTrace();
					}
				}
			}
		);
	}
//	FingerPrint fingerprint = new FingerPrint(component, stream, this.outputDir);
//	fingerprint.print(performanceResults);

	// print scenario status table
	if (!isGlobal) {
		// print the component scenario status table beneath the fingerprint
		final ScenarioStatusTable sst = new ScenarioStatusTable(component, stream);
		display.syncExec(
			new Runnable() {
				public void run(){
					try {
						sst.print(GenerateResults.this.performanceResults);
					} catch (Exception ex) {
						ex.printStackTrace();
					}
				}
			}
		);
//		ScenarioStatusTable sst = new ScenarioStatusTable(component, stream);
//		sst.print(performanceResults);
	}

	stream.print(Utils.HTML_CLOSE);
	stream.close();
}

private void printComponentTitle(/*PerformanceResults performanceResults, */String component, boolean isGlobal, PrintStream stream) {
	String baselineName = this.performanceResults.getBaselineName();
	String currentName = this.performanceResults.getName();

	// Print title line
	stream.print("<h3>Performance of ");
	if (!isGlobal) {
		stream.print(component);
		stream.print(": ");
	}
	stream.print(currentName);
	stream.print(" relative to ");
	int index = baselineName.indexOf('-');
	if (index > 0) {
		stream.print(baselineName.substring(0, index));
		stream.print(" (");
		index = baselineName.lastIndexOf('-');
		stream.print(baselineName.substring(index+1, baselineName.length()));
		stream.print(')');
	} else {
		stream.print(baselineName);
	}
		stream.print("</h3>\n");

	// Print reference to global results
	if (!isGlobal) {
		stream.print("<?php\n");
		stream.print("	$type=$_SERVER['QUERY_STRING'];\n");
		stream.print("	if ($type==\"\") {\n");
		stream.print("		$type=\"fp_type=0\";\n");
		stream.print("	}\n");
		stream.print("	$href=\"<a href=\\\"performance.php?\";\n");
		stream.print("	$href=$href . $type . \"\\\">Back to global results</a><br><br>\";\n");
		stream.print("	echo $href;\n");
		stream.print("?>\n");
	}
}

/*
 * Print summary of coefficient of variation for each scenario of the given pattern
 * both for baseline and current builds.
 */
private void printSummary(/*PerformanceResults performanceResults*/) {
	long start = System.currentTimeMillis();
	if (this.printStream != null) this.printStream.print("Print scenarios variations summary...");
	File outputFile = new File(this.outputDir, "cvsummary.html");
	PrintStream stream = null;
	try {
		stream = new PrintStream(new BufferedOutputStream(new FileOutputStream(outputFile)));
		printSummaryPresentation(stream);
//		List scenarioNames = DB_Results.getScenarios();
//		int size = scenarioNames.size();
		String[] components = this.performanceResults.getComponents();
		int componentsLength = components.length;
		printSummaryColumnsTitle(stream/*, performanceResults*/);
		String[] configs = this.performanceResults.getConfigNames(true/*sorted*/);
		int configsLength = configs.length;
		for (int i=0; i<componentsLength; i++) {
			String componentName = components[i];
			List scenarioNames = this.performanceResults.getComponentScenarios(componentName);
			int size = scenarioNames.size();
			for (int s=0; s<size; s++) {
				String scenarioName = ((ScenarioResults) scenarioNames.get(s)).getName();
				if (scenarioName == null) continue;
				ScenarioResults scenarioResults = this.performanceResults.getScenarioResults(scenarioName);
				if (scenarioResults != null) {
					stream.print("<tr>\n");
					for (int j=0; j<2; j++) {
						for (int c=0; c<configsLength; c++) {
							printSummaryScenarioLine(j, configs[c], scenarioResults, stream);
						}
					}
					stream.print("<td>");
					stream.print(scenarioName);
					stream.print("</td></tr>\n");
				}
			}
		}
	} catch (Exception e) {
		e.printStackTrace();
	} finally {
	    if (stream != null) {
		stream.print("</table></body></html>\n");
		stream.flush();
		stream.close();
	    }
	}
	if (this.printStream != null) this.printStream.println("done in "+(System.currentTimeMillis()-start)+"ms");
}

/*
 * Print summary presentation (eg. file start and text presenting the purpose of this file contents)..
 */
private void printSummaryPresentation(PrintStream stream) {
	stream.print(Utils.HTML_OPEN);
	stream.print(Utils.HTML_DEFAULT_CSS);
	stream.print("<title>Summary of Elapsed Process Variation Coefficients</title></head>\n");
	stream.print("<body><h3>Summary of Elapsed Process Variation Coefficients</h3>\n");
	stream.print("<p> This table provides a bird's eye view of variability in elapsed process times\n");
	stream.print("for baseline and current build stream performance scenarios.");
	stream.print(" This summary is provided to facilitate the identification of scenarios that should be examined due to high variability.");
	stream.print("The variability for each scenario is expressed as a <a href=\"http://en.wikipedia.org/wiki/Coefficient_of_variation\">coefficient\n");
	stream.print("of variation</a> (CV). The CV is calculated by dividing the <b>standard deviation\n");
	stream.print("of the elapse process time over builds</b> by the <b>average elapsed process\n");
	stream.print("time over builds</b> and multiplying by 100.\n");
	stream.print("</p><p>High CV values may be indicative of any of the following:<br></p>\n");
	stream.print("<ol><li> an unstable performance test. </li>\n");
	stream.print("<ul><li>may be evidenced by an erratic elapsed process line graph.<br><br></li></ul>\n");
	stream.print("<li>performance regressions or improvements at some time in the course of builds.</li>\n");
	stream.print("<ul><li>may be evidenced by plateaus in elapsed process line graphs.<br><br></li></ul>\n");
	stream.print("<li>unstable testing hardware.\n");
	stream.print("<ul><li>consistent higher CV values for one test configuration as compared to others across");
	stream.print(" scenarios may be related to hardward problems.</li></ul></li></ol>\n");
	stream.print("<p> Scenarios are listed in alphabetical order in the far right column. A scenario's\n");
	stream.print("variation coefficients (CVs) are in columns to the left for baseline and current\n");
	stream.print("build streams for each test configuration. Scenarios with CVs > 10% are highlighted\n");
	stream.print("in yellow (10%<CV>&lt;CV<20%) and orange(CV>20%). </p>\n");
	stream.print("<p> Each CV value links to the scenario's detailed results to allow viewers to\n");
	stream.print("investigate the variability.</p>\n");
}

/*
 * Print columns titles of the summary table.
 */
private void printSummaryColumnsTitle(PrintStream stream/*, PerformanceResults performanceResults*/) {
	String[] configBoxes = this.performanceResults.getConfigBoxes(true/*sorted*/);
	int length = configBoxes.length;
	stream.print("<table border=\"1\"><tr><td colspan=\"");
	stream.print(length);
	stream.print("\"><b>Baseline CVs</b></td><td colspan=\"");
	stream.print(length);
	stream.print("\"><b>Current Build Stream CVs</b></td><td rowspan=\"2\"><b>Scenario Name</b></td></tr>\n");
	stream.print("<tr>");
	for (int n=0; n<2; n++) {
		for (int c=0; c<length; c++) {
			stream.print("<td>");
			stream.print(configBoxes[c]);
			stream.print("</td>");
		}
	}
	stream.print("</tr>\n");
}

/*
 * Print a scenario line in the summary table.
 */
private void printSummaryScenarioLine(int i, String config, ScenarioResults scenarioResults, PrintStream stream) {
	ConfigResults configResults = scenarioResults.getConfigResults(config);
	if (configResults == null || !configResults.isValid()) {
		stream.print("<td>n/a</td>");
		return;
	}
	String url = config + "/" + scenarioResults.getFileName()+".html";
	double[] stats = null;
	if (i==0) { // baseline results
		List baselinePrefixes;
		if (this.baselinePrefix == null) {
			baselinePrefixes = Util.BASELINE_BUILD_PREFIXES;
		} else {
			baselinePrefixes = new ArrayList();
			baselinePrefixes.add(this.baselinePrefix);
		}
		stats = configResults.getStatistics(baselinePrefixes);
	} else {
		stats = configResults.getStatistics(this.currentBuildPrefixes);
	}
	double variation = stats[3];
	if (variation > 0.1 && variation < 0.2) {
		stream.print("<td bgcolor=\"yellow\">");
	} else if (variation >= 0.2) {
		stream.print("<td bgcolor=\"FF9900\">");
	} else {
		stream.print("<td>");
	}
	stream.print("<a href=\"");
	stream.print(url);
	stream.print("\"/>");
	stream.print(Util.PERCENTAGE_FORMAT.format(variation));
	stream.print("</a></td>");
}

/*
 * Print usage in case one of the argument of the line was incorrect.
 * Note that calling this method ends the program run due to final System.exit()
 */
private void printUsage() {
	System.out.println(
		"Usage:\n\n" +
		"-baseline\n" +
		"	Build id against which to compare results.\n" +
		"	Same as value specified for the \"build\" key in the eclipse.perf.config system property.\n\n" +

		"[-baseline.prefix]\n" +
		"	Optional.  Build id prefix used in baseline test builds and reruns.  Used to plot baseline historical data.\n" +
		"	A common prefix used for the value of the \"build\" key in the eclipse.perf.config system property when rerunning baseline tests.\n\n" +

		"-current\n" +
		"	build id for which to generate results.  Compared to build id specified in -baseline parameter above.\n" +
		"	Same as value specified for the \"build\" key in the eclipse.perf.config system property. \n\n" +

		"[-current.prefix]\n" +
		"	Optional.  Comma separated list of build id prefixes used in current build stream.\n" +
		"	Used to plot current build stream historical data.  Defaults to \"N,I\".\n" +
		"	Prefixes for values specified for the \"build\" key in the eclipse.perf.config system property. \n\n" +

		"-jvm\n" +
		"	Value specified in \"jvm\" key in eclipse.perf.config system property for current build.\n\n" +

		"-config\n" +
		"	Comma separated list of config names for which to generate results.\n" +
		"	Same as values specified in \"config\" key in eclipse.perf.config system property.\n\n" +

		"-output\n" +
		"	Path to default output directory.\n\n" +

		"[-config.properties]\n" +
		"	Optional.  Used by scenario status table to provide the following:\n" +
		"		alternate descriptions of config values to use in columns.\n" +
		"	The value should be specified in the following format:\n" +
		"	name1,description1;name2,description2;etc..\n\n" +

		"[-highlight]\n" +
		"	Optional.  Comma-separated list of build Id prefixes used to find most recent matching for each entry.\n" +
		"	Result used to highlight points in line graphs.\n\n" +

		"[-scenario.pattern]\n" +
		"	Optional.  Scenario prefix pattern to query database.  If not specified,\n" +
		"	default of % used in query.\n\n" +

		"[-fingerprints]\n" +
		"	Optional.  Use to generate fingerprints only.\n\n" +

		"[-data]\n" +
		"	Optional.  Generates table of scenario reference and current data with line graphs.\n\n" +

		"[-print]\n" +
		"	Optional.  Display output in the console while generating.\n" +

		"[-nophp]\n" +
		"	Optional.  Generate files for non-php server.\n" +

		"[-failure.threshold]\n" +
		"	Optional.  Set the failure percentage threshold (default is 10%).\n"
	);

	System.exit(1);
}

/**
 * Run the generation from a list of arguments.
 * Typically used to generate results from an application.
 */
public IStatus run(String[] args) {
	parse(args);
	return generate(null);
}

/**
 * Run the generation.
 */
public IStatus run(PerformanceResults results, String buildName, String baseline, File output, final IProgressMonitor monitor) {
	this.performanceResults = results;
	this.outputDir = output;
	setDefaults(buildName, baseline);
	return generate(monitor);
}

/*
 * Note that all necessary information to generate properly must be set before
 * calling this method
 */
private IStatus generate(final IProgressMonitor monitor) {
	long begin = System.currentTimeMillis();
	int work = 1100;
    int dataWork = 1000 * this.performanceResults.getConfigBoxes(false).length;
	if (this.genAll || this.genData) {
	    work += dataWork;
    }
	SubMonitor subMonitor = SubMonitor.convert(monitor, work);
	subMonitor.setTaskName("Generate perf results for build "+this.performanceResults.getName());
	try {

		// Print whole scenarios summary
		if (this.printStream != null) this.printStream.println();
		printSummary(/*performanceResults*/);

		// Copy images and scripts to output dir
		Bundle bundle = UiPlugin.getDefault().getBundle();
//		URL images = bundle.getEntry("images");
//		if (images != null) {
//			images = FileLocator.resolve(images);
//			Utils.copyImages(new File(images.getPath()), this.outputDir);
//		}
		/* New way to get images
		File content = FileLocator.getBundleFile(bundle);
		BundleFile bundleFile;
		if (content.isDirectory()) {
			bundleFile = new DirBundleFile(content);
			Utils.copyImages(bundleFile.getFile("images", true), this.outputDir);
		} else {
			bundleFile = new ZipBundleFile(content, null);
			Enumeration imageFiles = bundle.findEntries("images", "*.gif", false);
			while (imageFiles.hasMoreElements()) {
				URL url = (URL) imageFiles.nextElement();
				Utils.copyFile(bundleFile.getFile("images"+File.separator+, true), this.outputDir);
			}
		}
		*/
		// Copy bundle files
		Utils.copyBundleFiles(bundle, "images", "*.gif", this.outputDir); // images
		Utils.copyBundleFiles(bundle, "scripts", "*.js", this.outputDir); // java scripts
		Utils.copyBundleFiles(bundle, "scripts", "*.css", this.outputDir); // styles
		Utils.copyBundleFiles(bundle, "doc", "*.html", this.outputDir); // doc
		Utils.copyBundleFiles(bundle, "doc/images", "*.png", this.outputDir); // images for doc
		/*
		URL doc = bundle.getEntry("doc");
		if (doc != null) {
			doc = FileLocator.resolve(doc);
			File docDir = new File(doc.getPath());
			FileFilter filter = new FileFilter() {
				public boolean accept(File pathname) {
		            return !pathname.getName().equals("CVS");
	            }
			};
			File[] docFiles = docDir.listFiles(filter);
			for (int i=0; i<docFiles.length; i++) {
				File file = docFiles[i];
				if (file.isDirectory()) {
					File subdir = new File(this.outputDir, file.getName());
					subdir.mkdir();
					File[] subdirFiles = file.listFiles(filter);
					for (int j=0; j<subdirFiles.length; j++) {
						if (subdirFiles[i].isDirectory()) {
							// expect only one sub-directory
						} else {
							Util.copyFile(subdirFiles[j], new File(subdir, subdirFiles[j].getName()));
						}
					}
				} else {
					Util.copyFile(file, new File(this.outputDir, file.getName()));
				}
			}
		}
		*/

		// Print HTML pages and all linked files
		if (this.printStream != null) {
			this.printStream.println("Print performance results HTML pages:");
			this.printStream.print("	- components main page");
		}
		long start = System.currentTimeMillis();
//		subMonitor.setTaskName("Write fingerprints: 0%");
//		subMonitor.subTask("Global...");
		subMonitor.subTask("Write fingerprints: global (0%)...");
		printComponent(/*performanceResults, */"global_fp");
		subMonitor.worked(100);
		if (subMonitor.isCanceled()) throw new OperationCanceledException();
		String[] components = this.performanceResults.getComponents();
		int length = components.length;
		int step = 1000 / length;
		int progress = 0;
		for (int i=0; i<length; i++) {
			int percentage = (int) ((progress / ((double) length)) * 100);
//			subMonitor.setTaskName("Write fingerprints: "+percentage+"%");
//			subMonitor.subTask(components[i]+"...");
			subMonitor.subTask("Write fingerprints: "+components[i]+" ("+percentage+"%)...");
			printComponent(/*performanceResults, */components[i]);
			subMonitor.worked(step);
			if (subMonitor.isCanceled()) throw new OperationCanceledException();
			progress++;
		}
		if (this.printStream != null) {
			String duration = Util.timeString(System.currentTimeMillis()-start);
			this.printStream.println(" done in "+duration);
		}

		// Print the scenarios data
		if (this.genData || this.genAll) {
			start = System.currentTimeMillis();
			if (this.printStream != null) this.printStream.println("	- all scenarios data:");
			ScenarioData data = new ScenarioData(this.baselinePrefix, this.pointsOfInterest, this.currentBuildPrefixes, this.outputDir);
			try {
				data.print(this.performanceResults, this.printStream, subMonitor.newChild(dataWork));
			} catch (Exception ex) {
				ex.printStackTrace();
			}
			if (this.printStream != null) {
				String duration = Util.timeString(System.currentTimeMillis()-start);
				this.printStream.println("	=> done in "+duration);
			}
		}
		if (this.printStream != null) {
			long time = System.currentTimeMillis();
			this.printStream.println("End of generation: "+new SimpleDateFormat("H:mm:ss").format(new Date(time)));
			String duration = Util.timeString(System.currentTimeMillis()-begin);
			this.printStream.println("=> done in "+duration);
		}
		return new Status(IStatus.OK, UiPlugin.getDefault().toString(), "Everything is OK");
	}
	catch (OperationCanceledException oce) {
		return new Status(IStatus.OK, UiPlugin.getDefault().toString(), "Generation was cancelled!");
	}
	catch (Exception ex) {
		return new Status(IStatus.ERROR, UiPlugin.getDefault().toString(), "An unexpected exception occurred!", ex);
	}
	finally {
		if (this.printStream != null) {
			this.printStream.flush();
			if (this.printStream != System.out) {
				this.printStream.close();
			}
		}
	}
}

private void setDefaults(String buildName, String baseline) {
	if (buildName == null) {
		buildName = this.performanceResults.getName();
	}

	// Set default output dir if not set
	if (this.outputDir.getPath().indexOf(buildName) == -1) {
		File dir = new File(this.outputDir, buildName);
		if (dir.exists() || dir.mkdir()) {
			this.outputDir = dir;
			if (this.printStream != null) {
				this.printStream.println("	+ changed output dir to: "+dir.getPath());
			}
		}
	}

	// must set our known "last build" (that we are interested in) before
	// 'getAllBuildNames' is called, else it may set "name" to some later 
	// build we are not interested in analyzing yet.
    this.performanceResults.setLastBuildName(buildName);

	// Verify that build is known
	String[] builds = this.performanceResults.getAllBuildNames();
	if (builds == null || builds.length == 0) {
		System.err.println("Cannot connect to database to generate results build '"+buildName+"'");
		// TODO: changed a system.exit to this exception ... but, there might be better choices?
		throw new IllegalStateException("Cannot connect to database to generate results build '"+buildName+"'");
	}
	if (Arrays.binarySearch(builds, buildName, Util.BUILD_DATE_COMPARATOR) < 0) {
		throw new RuntimeException("No results in database for build '"+buildName+"'");
	}
	if (this.printStream != null) {
		this.printStream.println();
		this.printStream.flush();
	}

	// Init baseline prefix if not set
	if (this.baselinePrefix == null) {
		int index = baseline.lastIndexOf('-');
		if (index > 0) {
			this.baselinePrefix = baseline.substring(0, index);
		} else {
			this.baselinePrefix = DB_Results.getDbBaselinePrefix();
		}
	}

	// Init current build prefixes if not set
	if (this.currentBuildPrefixes == null) {
		this.currentBuildPrefixes = new ArrayList();
		char buildType = buildName.charAt(0);
		if (buildType == 'M') {
			this.currentBuildPrefixes.add("M");
		} else if (buildType == 'N') {
			this.currentBuildPrefixes.add("N");
		} else if (buildType == 'I') {
		this.currentBuildPrefixes.add("I");
		} else {
		    // TODO: may want to throw error here? 
		    this.currentBuildPrefixes.add("?");
		}
	}
}

private void setPerformanceResults(String buildName, String baselineName) {

	// Set performance results
	this.performanceResults = new PerformanceResults(buildName, baselineName, this.baselinePrefix, this.printStream);

	// Set defaults
	setDefaults(buildName, this.performanceResults.getBaselineName());

	// Read performance results data
	this.performanceResults.readAll(buildName, this.configDescriptors, this.scenarioPattern, this.dataDir, this.failure_threshold, null);
}

/* (non-Javadoc)
 * @see org.eclipse.equinox.app.IApplication#stop()
 */
public void stop() {
	// Do nothing
}

}