/*******************************************************************************
 * Copyright (c) 2000, 2018 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.internal.performance.results.model;

import java.util.ArrayList;
import java.util.List;
import java.util.Vector;

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.utils.IPerformancesConstants;
import org.eclipse.test.internal.performance.results.utils.Util;
import org.eclipse.ui.views.properties.ComboBoxPropertyDescriptor;
import org.eclipse.ui.views.properties.IPropertyDescriptor;
import org.eclipse.ui.views.properties.PropertyDescriptor;
import org.eclipse.ui.views.properties.TextPropertyDescriptor;

public class ConfigResultsElement extends ResultsElement {

	// Elements
	BuildResultsElement currentBuild, baselineBuild;

	// Property descriptors
	static final String P_ID_CONFIG_NAME = "ConfigResultsElement.name"; //$NON-NLS-1$
	static final String P_ID_CONFIG_DESCRIPTION = "ConfigResultsElement.description"; //$NON-NLS-1$
	static final String P_ID_CONFIG_CURRENT_BUILD = "ConfigResultsElement.currentbuild"; //$NON-NLS-1$
	static final String P_ID_CONFIG_BASELINE_BUILD = "ConfigResultsElement.baselinebuild"; //$NON-NLS-1$
	static final String P_ID_CONFIG_BASELINED = "ConfigResultsElement.baselined"; //$NON-NLS-1$
	static final String P_ID_CONFIG_VALID = "ConfigResultsElement.valid"; //$NON-NLS-1$
	static final String P_ID_CONFIG_DELTA = "ConfigResultsElement.delta"; //$NON-NLS-1$
	static final String P_ID_CONFIG_ERROR = "ConfigResultsElement.error"; //$NON-NLS-1$

	static final String P_STR_CONFIG_NAME = "internal name"; //$NON-NLS-1$
	static final String P_STR_CONFIG_DESCRIPTION = "description"; //$NON-NLS-1$
	static final String P_STR_CONFIG_CURRENT_BUILD = "current build"; //$NON-NLS-1$
	static final String P_STR_CONFIG_BASELINE_BUILD = "baseline build"; //$NON-NLS-1$
	static final String P_STR_CONFIG_BASELINED = "has baseline"; //$NON-NLS-1$
	static final String P_STR_CONFIG_VALID = "is valid"; //$NON-NLS-1$
	static final String P_STR_CONFIG_DELTA = "delta with baseline"; //$NON-NLS-1$
	static final String P_STR_CONFIG_ERROR = "delta error"; //$NON-NLS-1$

	private static final TextPropertyDescriptor CONFIG_NAME_DESCRIPTOR = new TextPropertyDescriptor(P_ID_CONFIG_NAME, P_STR_CONFIG_NAME);
	private static final TextPropertyDescriptor CONFIG_DESCRIPTION_DESCRIPTOR = new TextPropertyDescriptor(P_ID_CONFIG_DESCRIPTION, P_STR_CONFIG_DESCRIPTION);
	private static final PropertyDescriptor CONFIG_CURRENT_BUILD_DESCRIPTOR = new PropertyDescriptor(P_ID_CONFIG_CURRENT_BUILD, P_STR_CONFIG_CURRENT_BUILD);
	private static final PropertyDescriptor CONFIG_BASELINE_BUILD_DESCRIPTOR = new PropertyDescriptor(P_ID_CONFIG_BASELINE_BUILD, P_STR_CONFIG_BASELINE_BUILD);
	private static final PropertyDescriptor CONFIG_BASELINED_DESCRIPTOR = new PropertyDescriptor(P_ID_CONFIG_BASELINED, P_STR_CONFIG_BASELINED);
	private static final PropertyDescriptor CONFIG_VALID_DESCRIPTOR = new PropertyDescriptor(P_ID_CONFIG_VALID, P_STR_CONFIG_VALID);
	private static final PropertyDescriptor CONFIG_DELTA_DESCRIPTOR = new PropertyDescriptor(P_ID_CONFIG_DELTA, P_STR_CONFIG_DELTA);
	private static final PropertyDescriptor CONFIG_ERROR_DESCRIPTOR = new PropertyDescriptor(P_ID_CONFIG_ERROR, P_STR_CONFIG_ERROR);

    private static Vector<IPropertyDescriptor> DESCRIPTORS;
    static Vector<IPropertyDescriptor> initDescriptors(int status) {
		DESCRIPTORS = new Vector<>();
		// Status category
		DESCRIPTORS.add(getInfosDescriptor(status));
		DESCRIPTORS.add(getWarningsDescriptor(status));
		DESCRIPTORS.add(ERROR_DESCRIPTOR);
		ERROR_DESCRIPTOR.setCategory("Status");
		// Results category
		DESCRIPTORS.addElement(CONFIG_NAME_DESCRIPTOR);
		CONFIG_NAME_DESCRIPTOR.setCategory("Results");
		DESCRIPTORS.addElement(CONFIG_DESCRIPTION_DESCRIPTOR);
		CONFIG_DESCRIPTION_DESCRIPTOR.setCategory("Results");
		DESCRIPTORS.addElement(CONFIG_CURRENT_BUILD_DESCRIPTOR);
		CONFIG_CURRENT_BUILD_DESCRIPTOR.setCategory("Results");
		DESCRIPTORS.addElement(CONFIG_BASELINE_BUILD_DESCRIPTOR);
		CONFIG_BASELINE_BUILD_DESCRIPTOR.setCategory("Results");
		DESCRIPTORS.addElement(CONFIG_BASELINED_DESCRIPTOR);
		CONFIG_BASELINED_DESCRIPTOR.setCategory("Results");
		DESCRIPTORS.addElement(CONFIG_VALID_DESCRIPTOR);
		CONFIG_VALID_DESCRIPTOR.setCategory("Results");
		DESCRIPTORS.addElement(CONFIG_DELTA_DESCRIPTOR);
		CONFIG_DELTA_DESCRIPTOR.setCategory("Results");
		DESCRIPTORS.addElement(CONFIG_ERROR_DESCRIPTOR);
		CONFIG_ERROR_DESCRIPTOR.setCategory("Results");
		// Survey category
		DESCRIPTORS.add(COMMENT_DESCRIPTOR);
		COMMENT_DESCRIPTOR.setCategory("Survey");
		return DESCRIPTORS;
	}
    static ComboBoxPropertyDescriptor getInfosDescriptor(int status) {
		List<String> list = new ArrayList<>();
		if ((status & SMALL_VALUE) != 0) {
			list.add("This test and/or its variation has a small value on this machine, hence it may not be necessary to spend time on fixing it if a regression occurs");
		}
		if ((status & STUDENT_TTEST) != 0) {
			list.add("The student-t test error on this machine is over the threshold");
		}
		String[] infos = new String[list.size()];
		if (list.size() > 0) {
			list.toArray(infos);
		}
		ComboBoxPropertyDescriptor infoDescriptor = new ComboBoxPropertyDescriptor(P_ID_STATUS_INFO, P_STR_STATUS_INFO, infos);
		infoDescriptor.setCategory("Status");
		return infoDescriptor;
	}
    static PropertyDescriptor getWarningsDescriptor(int status) {
		List<String> list = new ArrayList<>();
		if ((status & BIG_ERROR) != 0) {
			list.add("The error on this machine is over the 3% threshold, hence its result may not be really reliable");
		}
		if ((status & NOT_RELIABLE) != 0) {
			list.add("The results history for this machine shows that the variation of its delta is over 20%, hence its result is surely not reliable");
		}
		if ((status & NOT_STABLE) != 0) {
			list.add("The results history for this machine shows that the variation of its delta is between 10% and 20%, hence its result may not be really reliable");
		}
		if ((status & NO_BASELINE) != 0) {
			list.add("There's no baseline for this machine to compare with");
		}
		if ((status & SINGLE_RUN) != 0) {
			list.add("This test has only one run on this machine, hence no error can be computed to verify if it's stable enough to be reliable");
		}
		if ((status & STUDENT_TTEST) != 0) {
			list.add("The student-t test error on this machine is over the threshold");
		}
		String[] warnings = new String[list.size()];
		if (list.size() > 0) {
			list.toArray(warnings);
		}
		ComboBoxPropertyDescriptor warningDescriptor = new ComboBoxPropertyDescriptor(P_ID_STATUS_WARNING, P_STR_STATUS_WARNING, warnings);
		warningDescriptor.setCategory("Status");
		return warningDescriptor;
	}
    static Vector<IPropertyDescriptor> getDescriptors() {
    	return DESCRIPTORS;
	}

public ConfigResultsElement(AbstractResults results, ResultsElement parent) {
	super(results, parent);
}

@Override
ResultsElement createChild(AbstractResults testResults) {
	return new BuildResultsElement(testResults, this);
}

BuildResultsElement getBaselineBuild() {
	if (this.baselineBuild == null) {
		this.baselineBuild = new BuildResultsElement(getConfigResults().getBaselineBuildResults(), this);
	}
	return this.baselineBuild;
}

/**
 * Get the baseline build used for this configuration.
 *
 * @param buildName The name of the build to have the baseline
 * @return The baseline build as {@link BuildResultsElement}.
 */
public String getBaselineBuildName(String buildName) {
	return getConfigResults().getBaselineBuildResults(buildName).getName();
}

private ConfigResults getConfigResults() {
	return (ConfigResults) this.results;
}

BuildResultsElement getCurrentBuild() {
	if (this.currentBuild == null) {
		this.currentBuild = new BuildResultsElement(getConfigResults().getCurrentBuildResults(), this);
	}
	return this.currentBuild;
}

@Override
public String getLabel(Object o) {
	String description = getConfigResults().getDescription();
	int index = description.indexOf(" (");
	if (index <= 0) {
		return description;
	}
	return description.substring(0, index);
}

@Override
public IPropertyDescriptor[] getPropertyDescriptors() {
	Vector<IPropertyDescriptor> descriptors = getDescriptors();
	if (descriptors == null) {
		descriptors = initDescriptors(getStatus());
	}
	int size = descriptors.size();
	IPropertyDescriptor[] descriptorsArray = new IPropertyDescriptor[size];
	descriptorsArray[0] = getInfosDescriptor(getStatus());
	descriptorsArray[1] = getWarningsDescriptor(getStatus());
	for (int i=2; i<size; i++) {
		descriptorsArray[i] = descriptors.get(i);
	}
	return descriptorsArray;
}

@Override
public Object getPropertyValue(Object propKey) {
	ConfigResults configResults = getConfigResults();
	if (propKey.equals(P_ID_CONFIG_NAME)) {
		return configResults.getName();
	}
	if (propKey.equals(P_ID_CONFIG_DESCRIPTION)) {
		return configResults.getDescription();
	}
	if (propKey.equals(P_ID_CONFIG_CURRENT_BUILD)) {
		return getCurrentBuild();
	}
	if (propKey.equals(P_ID_CONFIG_BASELINE_BUILD)) {
		return getBaselineBuild();
	}
	if (propKey.equals(P_ID_CONFIG_BASELINED)) {
		return Boolean.valueOf(configResults.isBaselined());
	}
	if (propKey.equals(P_ID_CONFIG_VALID)) {
		return Boolean.valueOf(configResults.isValid());
	}
	if (propKey.equals(P_ID_CONFIG_DELTA)) {
		return Double.valueOf(configResults.getDelta());
	}
	if (propKey.equals(P_ID_CONFIG_ERROR)) {
		return Double.valueOf(configResults.getError());
	}
	if (propKey.equals(P_ID_STATUS_ERROR)) {
		if (getStatus() == MISSING) {
			PerformanceResultsElement performanceResultsElement = (PerformanceResultsElement) ((ResultsElement)((ResultsElement)getParent(null)).getParent(null)).getParent(null);
			return "No result for build "+performanceResultsElement.getName()+" on this machine!";
		}
		if ((getStatus() & BIG_DELTA) != 0) {
			return "The delta on this machine is over the 10% threshold, hence may indicate a possible regression";
		}
	}
	return super.getPropertyValue(propKey);
}

/**
 * Return the statistics of the build along its history.
 *
 * @return An array of double built as follows:
 * <ul>
 * <li>0:	numbers of values</li>
 * <li>1:	mean of values</li>
 * <li>2:	standard deviation of these values</li>
 * <li>3:	coefficient of variation of these values</li>
 * </ul>
 */
@Override
public double[] getStatistics() {
	if (this.statistics  == null) {
		this.statistics = getConfigResults().getStatistics(Util.BASELINE_BUILD_PREFIXES);
	}
	return this.statistics;
}

@Override
void initStatus() {
	ConfigResults configResults = getConfigResults();
	if (configResults.isValid()) {
		initStatus(configResults.getCurrentBuildResults());
	} else {
		this.status = MISSING;
	}
}

/*
 * Write the element status in the given stream
 */
@Override
StringBuilder getFailures(StringBuilder buffer, int kind, StringBuilder excluded) {
	if ((this.status & BIG_DELTA) != 0) { // there's a failure on this config

		// Get numbers
		int buildsNumber = kind & IPerformancesConstants.STATUS_BUILDS_NUMBER_MASK;
		ConfigResults configResults = getConfigResults();
		double[][] numbers = configResults.getLastNumbers(buildsNumber);
		int numbersLength = numbers.length;

		// if there are several builds to confirm the regression, then verify all deltas
		if (numbersLength > 1) {
			if (numbersLength < buildsNumber) {
				// there's not enough builds to wee whether there's a real regression, hence skip result
				if (excluded != null) {
					excluded.append(configResults+" excluded from status because there's only "+numbersLength+" builds available although "+buildsNumber+" is required to decide a regression is confirmed or not!");
					excluded.append(Util.LINE_SEPARATOR);
				}
				return buffer;
			}
			int confirmed = 1;
			for (int i=1; i<numbersLength; i++) {
				if (numbers[i] != null && numbers[i][AbstractResults.DELTA_VALUE_INDEX] < -0.1) {
					confirmed++;
				}
			}
			float ratio = ((float) confirmed) / numbersLength;
			if (ratio < 0.8) {
				// more than 20% of previous build didn't fail, hence skip result
				if (excluded != null) {
					excluded.append(configResults+" excluded from status because only "+confirmed+" builds failed on last "+buildsNumber+" ones!");
					excluded.append(Util.LINE_SEPARATOR);
				}
				return buffer;
			}
		}

		// Add values
		double[] values = numbers[0];
		double buildValue = values[AbstractResults.BUILD_VALUE_INDEX];
		double baselineValue = values[AbstractResults.BASELINE_VALUE_INDEX];
		double delta = values[AbstractResults.DELTA_VALUE_INDEX];
		double error = values[AbstractResults.DELTA_ERROR_INDEX];
		StringBuilder localBuffer = new StringBuilder("		");
		localBuffer.append(configResults.getName());
		double[] stats = null;
		boolean printValues = (kind & IPerformancesConstants.STATUS_VALUES) != 0;
		if (printValues) {
			localBuffer.append("	");
			localBuffer.append(buildValue);
			localBuffer.append("	");
			localBuffer.append(baselineValue);
			localBuffer.append("	");
			localBuffer.append(buildValue-baselineValue);
			localBuffer.append("	");
			localBuffer.append(Util.PERCENTAGE_FORMAT.format(delta));
			localBuffer.append("	");
			localBuffer.append(Util.PERCENTAGE_FORMAT.format(error));
			stats = getStatistics();
			if (stats != null) {
				localBuffer.append("	");
				localBuffer.append((int) stats[0]);
				localBuffer.append("	");
				localBuffer.append(Util.DOUBLE_FORMAT.format(stats[1]));
				localBuffer.append("	");
				localBuffer.append(Util.DOUBLE_FORMAT.format(stats[2]));
				localBuffer.append("	");
				localBuffer.append(Util.PERCENTAGE_FORMAT.format(stats[3]));
			}
		}

		/* Add comment
		IEclipsePreferences preferences = new InstanceScope().getNode(IPerformancesConstants.PLUGIN_ID);
		String comment = preferences.get(getId(), null);
		if (comment != null) {
			if (stats == null && printValues) {
				buffer.append("				");
			}
			buffer.append("	");
			buffer.append(comment);
		}
		*/

		// Add status info
		if (this.status != BIG_DELTA) { // there's some other info in the status
//			if (comment == null) {
				if (stats == null && printValues) {
					localBuffer.append("				");
				}
//			}
			localBuffer.append("	");
			String separator = "";

			// Error
			if ((this.status & BIG_ERROR) != 0) {
				int statusErrorLevel = kind & IPerformancesConstants.STATUS_ERROR_LEVEL_MASK;
				if (statusErrorLevel == IPerformancesConstants.STATUS_ERROR_NOTICEABLE) {
					// Skip result
					if (excluded != null) {
						excluded.append(configResults+" excluded from status due to a noticeable error!");
						excluded.append(Util.LINE_SEPARATOR);
					}
					return buffer;
				}
				localBuffer.append(separator);
				localBuffer.append("error (");
				localBuffer.append(Util.PERCENTAGE_FORMAT.format(error));
				localBuffer.append(")");
				separator = "+";
				double ratio = -(error/delta);
				if (ratio > 1) {
					switch (statusErrorLevel) {
						case IPerformancesConstants.STATUS_ERROR_INVALID:
						case IPerformancesConstants.STATUS_ERROR_WEIRD:
						case IPerformancesConstants.STATUS_ERROR_SUSPICIOUS:
							// Skip result
							if (excluded != null) {
								excluded.append(configResults+" excluded from status due to an invalid error!");
								excluded.append(Util.LINE_SEPARATOR);
							}
							return buffer;
					}
					localBuffer.append(": invalid measure!");
				} else if (ratio > 0.5) {
					switch (statusErrorLevel) {
						case IPerformancesConstants.STATUS_ERROR_WEIRD:
						case IPerformancesConstants.STATUS_ERROR_SUSPICIOUS:
							// Skip result
							if (excluded != null) {
								excluded.append(configResults+" excluded from status due to a weird error!");
								excluded.append(Util.LINE_SEPARATOR);
							}
							return buffer;
					}
					localBuffer.append(": weird measure!");
				} else if (ratio > 0.25) {
					if (statusErrorLevel == IPerformancesConstants.STATUS_ERROR_SUSPICIOUS) {
						// Skip result
						if (excluded != null) {
							excluded.append(configResults+" excluded from status due to a suspicious error!");
							excluded.append(Util.LINE_SEPARATOR);
						}
						return buffer;
					}
					localBuffer.append(": suspicious measure!");
				}
			}

			// Small value
			if ((this.status & SMALL_VALUE) != 0) {
				int statusSmallValue = kind & IPerformancesConstants.STATUS_SMALL_VALUE_MASK;
				localBuffer.append(separator);
				if (buildValue < 100) {
					if (statusSmallValue == IPerformancesConstants.STATUS_SMALL_VALUE_BUILD) {
						// Skip result
						if (excluded != null) {
							excluded.append(configResults+" excluded from status due to a small build value!");
							excluded.append(Util.LINE_SEPARATOR);
						}
						return buffer;
					}
					localBuffer.append("small build value (");
					localBuffer.append((int)buildValue);
					localBuffer.append("ms)");
				}
				int diff = (int) Math.abs(baselineValue - buildValue);
				if (diff < 100) {
					if (statusSmallValue == IPerformancesConstants.STATUS_SMALL_VALUE_DELTA) {
						// Skip result
						if (excluded != null) {
							excluded.append(configResults+" excluded from status due to a small delta value!");
							excluded.append(Util.LINE_SEPARATOR);
						}
						return buffer;
					}
					localBuffer.append("small delta value (");
					localBuffer.append(diff);
					localBuffer.append("ms)");
				}
				separator = "+";
			}

			// Statistics
			if ((this.status & NOT_RELIABLE) != 0) {
				switch (kind & IPerformancesConstants.STATUS_STATISTICS_MASK) {
					case IPerformancesConstants.STATUS_STATISTICS_UNSTABLE:
					case IPerformancesConstants.STATUS_STATISTICS_ERRATIC:
						// Skip result
						if (excluded != null) {
							excluded.append(configResults+" excluded from status due to erratic statistics!");
							excluded.append(Util.LINE_SEPARATOR);
						}
						return buffer;
				}
				localBuffer.append(separator);
				localBuffer.append("erratic");
				separator = "+";
			} else if ((this.status & NOT_STABLE) != 0) {
				if ((kind & IPerformancesConstants.STATUS_STATISTICS_UNSTABLE) != 0) {
					// Skip result
					if (excluded != null) {
						excluded.append(configResults+" excluded from status due to unstable statistics!");
						excluded.append(Util.LINE_SEPARATOR);
					}
					return buffer;
				}
				localBuffer.append(separator);
				localBuffer.append("unstable");
				separator = "+";
			}
		}

		// Write status
		buffer.append(localBuffer);
		buffer.append(Util.LINE_SEPARATOR);
	}
	return buffer;
}

}
