/*******************************************************************************
 * Copyright (c) 2005, 2007 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.*;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.*;

import org.eclipse.core.runtime.FileLocator;
import org.eclipse.equinox.app.IApplication;
import org.eclipse.equinox.app.IApplicationContext;
import org.eclipse.test.internal.performance.results.AbstractResults;
import org.eclipse.test.internal.performance.results.ConfigResults;
import org.eclipse.test.internal.performance.results.DB_Results;
import org.eclipse.test.internal.performance.results.PerformanceResults;
import org.eclipse.test.internal.performance.results.ScenarioResults;
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 Main implements IApplication {

/**
 * 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
 */
private 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>
 */
private 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>
 */
private 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>
 */
private 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>
 */
private 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
 */
private 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>
 */
private 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
 */
private 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
 */
private 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
 */
private 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.
 */
private boolean print = false;

/**
 * Tells whether the generation is done for a PHP server or not.
 * This field is set to <code>false</code> if <b>-nophp</b> argument is specified.
 * <p>
 * Default is <code>true</code> which means that the generation is done for the build server.
 */
private boolean use_php = true; // PerformanceTestPlugin.getDBLocation().startsWith("net://");

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

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

	while (i < args.length) {
		String arg = args[i];
		if (!arg.startsWith("-")) {
			i++;
			continue;
		}
		if (args.length == i + 1 && i != args.length - 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++;
			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++;
			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++;
			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]);
			}
			buffer.append('\n');
			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++;
			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++;
			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!");
				System.exit(2);
			}
			buffer.append("	").append(arg).append(" = ").append(dir).append('\n');
			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);
			}
			buffer.append("	").append(arg).append(" = ").append(dir).append('\n');
			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++;
			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("	").append(arg).append(" = ");
			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++;
			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++;
			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.print = true;
			buffer.append("	").append(arg).append('\n');
			i++;
			continue;
		}
		if (arg.equals("-nophp")) {
			this.use_php = false;
			buffer.append("	").append(arg).append('\n');
			i++;
			continue;
		}
		i++;
	}
	if (this.print) System.out.println(buffer.toString());
	
	// Stop if some mandatory parameters are missing
	if (baseline == null || this.outputDir == null || this.configDescriptors == null || jvm == null || currentBuildId == null) {
		printUsage();
	}
	
	// Init baseline prefix if not set
	if (this.baselinePrefix == null) {
		// Assume that baseline name format is *always* x.y_yyyyMMddhhmm_yyyyMMddhhmm
		this.baselinePrefix = baseline.substring(0, baseline.lastIndexOf('_'));
	}

	// Init currnt build prefixes if not set
	if (this.currentBuildPrefixes == null) {
		this.currentBuildPrefixes = new ArrayList();
		if (currentBuildId.charAt(0) == 'M') {
			this.currentBuildPrefixes.add("M");
		} else {
			this.currentBuildPrefixes.add("N");
		}
		this.currentBuildPrefixes.add("I");
	}
	return new PerformanceResults(currentBuildId, baseline, this.print);
}

/*
 * Print component PHP file
 */
private void printComponent(PerformanceResults performanceResults, String component) throws FileNotFoundException {
	if (this.print) System.out.print(".");
	File outputFile = new File(this.outputDir, component + ".php");
	PrintStream stream = new PrintStream(new BufferedOutputStream(new FileOutputStream(outputFile)));
	stream.println(Utils.HTML_OPEN);
	stream.println("<link href=\"ToolTip.css\" rel=\"stylesheet\" type=\"text/css\"><script src=\"ToolTip.js\"></script>");
	stream.println(Utils.HTML_DEFAULT_CSS);
	stream.println("<body>");

	String baselineName = performanceResults.getBaselineName();
	String currentName = performanceResults.getName();
	boolean isGlobal = component.equals("global");
	StringBuffer title = new StringBuffer("<h3>Performance of ");
	if (!isGlobal) {
		title.append(component);
		title.append(": ");
	}
	title.append(currentName);
	title.append(" relative to ");
	int index = baselineName.indexOf('_');
	title.append(baselineName.substring(0, index));
	title.append(" (");
	index = baselineName.lastIndexOf('_');
	title.append(baselineName.substring(index+1, baselineName.length()));
	title.append(")</h3>");
	stream.println(title.toString());

	// print the html representation of fingerprint for each config
	if (genFingerPrints || genAll) {
		FingerPrint fingerprint = new FingerPrint(component, stream, this.outputDir);
		try {
			fingerprint.print(performanceResults);
		} catch (Exception ex) {
			ex.printStackTrace();
		}
	}

	// print scenario status table
	if (isGlobal) {
		if (!this.use_php) {
			stream.println("<table border=0 cellpadding=2 cellspacing=5 width=\"100%\">");
			stream.println("<tbody><tr> <td colspan=3 align=\"left\" bgcolor=\"#0080c0\" valign=\"top\"><b><font color=\"#ffffff\" face=\"Arial,Helvetica\">");
			stream.println("Detailed performance data grouped by scenario prefix</font></b></td></tr></tbody></table>");
			stream.println("<a href=\"org.eclipse.ant.php?\">org.eclipse.ant*</a><br>");
			stream.println("<a href=\"org.eclipse.compare.php?\">org.eclipse.compare*</a><br>");
			stream.println("<a href=\"org.eclipse.core.php?\">org.eclipse.core*</a><br>");
			stream.println("<a href=\"org.eclipse.jdt.core.php?\">org.eclipse.jdt.core*</a><br>");
			stream.println("<a href=\"org.eclipse.jdt.debug.php?\">org.eclipse.jdt.debug*</a><br>");
			stream.println("<a href=\"org.eclipse.jdt.text.php?\">org.eclipse.jdt.text*</a><br>");
			stream.println("<a href=\"org.eclipse.jdt.ui.php?\">org.eclipse.jdt.ui*</a><br>");
			stream.println("<a href=\"org.eclipse.jface.php?\">org.eclipse.jface*</a><br>");
			stream.println("<a href=\"org.eclipse.osgi.php?\">org.eclipse.osgi*</a><br>");
			stream.println("<a href=\"org.eclipse.pde.ui.php?\">org.eclipse.pde.ui*</a><br>");
			stream.println("<a href=\"org.eclipse.swt.php?\">org.eclipse.swt*</a><br>");
			stream.println("<a href=\"org.eclipse.team.php?\">org.eclipse.team*</a><br>");
			stream.println("<a href=\"org.eclipse.ua.php?\">org.eclipse.ua*</a><br>");
			stream.println("<a href=\"org.eclipse.ui.php?\">org.eclipse.ui*</a><br><p><br><br>");
		}
	} else if (component.length() > 0) {
		// print the component scenario status table beneath the fingerprint
		ScenarioStatusTable sst = new ScenarioStatusTable(component, stream);
		try {
			sst.print(performanceResults);
		} catch (Exception ex) {
			ex.printStackTrace();
		}
	}

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

/*
 * 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.print) System.out.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.getScenariosNames();
		int size = scenarioNames.size();
		printSummaryColumnsTitle(stream, performanceResults);
		String[] configs = performanceResults.getConfigNames(true/*sorted*/);
		int configsLength = configs.length;
		for (int i=0; i<size; i++) {
			String scenarioName = (String) scenarioNames.get(i);
			if (scenarioName == null) continue;
			ScenarioResults scenarioResults = performanceResults.getScenarioResults(scenarioName);
			if (scenarioResults != null) {
				stream.println("<tr>");
				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.println("</td></tr>");
			}
		}
	} catch (Exception e) {
		e.printStackTrace();
	} finally {
		stream.println("</table></body></html>");
		stream.flush();
		stream.close();
	}
	if (this.print) System.out.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.println(Utils.HTML_OPEN);
	stream.print(Utils.HTML_DEFAULT_CSS);
	stream.println("<title>Summary of Elapsed Process Variation Coefficients</title></head>");
	stream.println("<body><h3>Summary of Elapsed Process Variation Coefficients</h3>\n");
	stream.println("<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.println("The variability for each scenario is expressed as a <a href=\"http://en.wikipedia.org/wiki/Coefficient_of_variation\">coefficient\n");
	stream.println("of variation</a> (CV). The CV is calculated by dividing the <b>standard deviation\n");
	stream.println("of the elapse process time over builds</b> by the <b>average elapsed process\n");
	stream.println("time over builds</b> and multiplying by 100.\n");
	stream.println("</p><p>High CV values may be indicative of any of the following:<br></p>\n");
	stream.println("<ol><li> an unstable performance test. </li>\n");
	stream.println("<ul><li>may be evidenced by an erratic elapsed process line graph.<br><br></li></ul>\n");
	stream.println("<li>performance regressions or improvements at some time in the course of builds.</li>\n");
	stream.println("<ul><li>may be evidenced by plateaus in elapsed process line graphs.<br><br></li></ul>\n");
	stream.println("<li>unstable testing hardware.\n");
	stream.print("<ul><li>consistent higher CV values for one test configuration as compared to others across");
	stream.println(" scenarios may be related to hardward problems.</li></ul></li></ol>\n");
	stream.println("<p> Scenarios are listed in alphabetical order in the far right column. A scenario's\n");
	stream.println("variation coefficients (CVs) are in columns to the left for baseline and current\n");
	stream.println("build streams for each test configuration. Scenarios with CVs > 10% are highlighted\n");
	stream.println("in yellow (10%<CV>&lt;CV<20%) and orange(CV>20%). </p>\n");
	stream.println("<p> Each CV value links to the scenario's detailed results to allow viewers to\n");
	stream.println("investigate the variability.</p>\n");
}

/*
 * Print columns titles of the summary table.
 */
private void printSummaryColumnsTitle(PrintStream stream, PerformanceResults performanceResults) {
	String[] configBoxes = 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.println("\"><b>Current Build Stream CVs</b></td><td rowspan=\"2\"><b>Scenario Name</b></td></tr>");
	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.println("</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;
	int dim_id = AbstractResults.SUPPORTED_DIMS[0].getId();
	if (i==0) { // baseline results
		List baselinePrefixes = new ArrayList();
		baselinePrefixes.add(this.baselinePrefix);
		stats = configResults.getStatistics(baselinePrefixes, dim_id);
	} else {
		stats = configResults.getStatistics(this.currentBuildPrefixes, dim_id);
	}
	double variation = stats[3];
	if (variation > 10 && variation < 20) {
		stream.print("<td bgcolor=\"yellow\">");
	} else if (variation >= 20) {
		stream.print("<td bgcolor=\"FF9900\">");
	} else {
		stream.print("<td>");
	}
	stream.print("<a href=\"");
	stream.print(url);
	stream.print("\"/>");
	stream.print(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"
	);

	System.exit(1);
}

/**
 * Generate the performance results for a specified build regarding to a specific reference.
 * This action generates following HTML files:
 * <ul>
 * <li>A summary table to see the variations for all the concerned scenarios</li>
 * <li>A global php file including global scenario fingerprints and links for all concerned components results php files</li>
 * <li>A php file for each component including scenario fingerprints and status table with links to a scenario data file</li>
 * <li>A data HTML file for each config of each scenario included in status table</li>
 * </ul>
 * @see org.eclipse.equinox.app.IApplication#start(org.eclipse.equinox.app.IApplicationContext)
 */
public Object start(IApplicationContext context) throws Exception {

	long begin = System.currentTimeMillis();

	// Parse arguments and read DB info
	PerformanceResults performanceResults = parse(context.getArguments().get("application.args"));
	performanceResults.read(this.configDescriptors, this.scenarioPattern, this.dataDir);

	// Print whole scenarios summary
	printSummary(performanceResults);

	// Copy images and scripts to output dir
	Bundle bundle = UiPlugin.getDefault().getBundle();
	URL images = bundle.getEntry("images");
	URL scripts = bundle.getEntry("scripts");
	if (images != null) {
		images = FileLocator.resolve(images);
		Utils.copyImages(new File(images.getPath()), this.outputDir);
	}
	if (scripts != null) {
		scripts = FileLocator.resolve(scripts);
		Utils.copyScripts(new File(scripts.getPath()), this.outputDir);
	}

	// Print HTML pages and all linked files
	if (this.print) {
		System.out.println("Print performance results HTML pages:");
		System.out.print("	- all components");
	}
	long start = System.currentTimeMillis();
	printComponent(performanceResults, "global");
	Iterator components = performanceResults.getComponents().iterator();
	while (components.hasNext()) {
		printComponent(performanceResults, (String) components.next());
	}
	if (this.print) System.out.println("done in "+(System.currentTimeMillis()-start)+"ms");

	// Print the scenarios data
	if (genData || genAll) {
		start = System.currentTimeMillis();
		if (this.print) System.out.print("	- all scenarios data...");
		ScenarioData data = new ScenarioData(this.baselinePrefix, this.pointsOfInterest, this.currentBuildPrefixes, this.outputDir);
		try {
			data.print(performanceResults);
		} catch (Exception ex) {
			ex.printStackTrace();
		}
		if (this.print) System.out.println("done in "+(System.currentTimeMillis()-start)+"ms");
	}
	if (this.print) {
		long time = System.currentTimeMillis();
		System.out.println("End of generation: "+new SimpleDateFormat("H:mm:ss").format(new Date(time)));
		long ms = System.currentTimeMillis() - begin;
		int sec = (int) (ms / 1000L);
		if ((ms - (sec*1000)) >= 500) sec++;
		if (sec < 60) {
			System.out.println("=> done in "+sec+" second"+(sec==1?"":"s"));
		} else if (sec < 3600) {
			int m = sec / 60;
			int s = sec % 60;
			System.out.println("=> done in "+m+" minute"+(m==1?"":"s")+" and "+s+" second"+(s==1?"":"s"));
		} else {
			int h = sec / 3600;
			int m = (sec-h*3600) / 60;
			int s = (sec-h*3600)  % 60;
			System.out.println("=> done in "+h+" hour"+(h==1?"":"s")+", "+m+" minute"+(m==1?"":"s")+" and "+s+" second"+(s==1?"":"s"));
		}
	}
	return null;
}

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