/*******************************************************************************
 * Copyright (c) 2000, 2017 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.AbstractResults;
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<String> 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<String> 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) {
	StringBuilder buffer = new StringBuilder("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");
  try (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");
      try (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);
      }
    } 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(() -> {
        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(() -> {
        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);
  }
}

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) {
    index = baselineName.lastIndexOf('-');
    stream.print(baselineName.substring(0, index-1));
  } 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");
	try (PrintStream stream = new PrintStream(new BufferedOutputStream(new FileOutputStream(outputFile)))) {
	  try {
  		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<AbstractResults> scenarioNames = this.performanceResults.getComponentScenarios(componentName);
  			int size = scenarioNames.size();
  			for (int s=0; s<size; s++) {
  				String scenarioName = 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");
  				}
  			}
  		}
	  } finally {
	    stream.print("</table></body></html>\n");
    }
	} catch (Exception e) {
		e.printStackTrace();
	}
	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<String> 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
}

}