/*******************************************************************************
 * 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.core.runtime.IAdaptable;
import org.eclipse.core.runtime.preferences.IEclipsePreferences;
import org.eclipse.core.runtime.preferences.InstanceScope;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.swt.graphics.Image;
import org.eclipse.test.internal.performance.eval.StatisticsUtil;
import org.eclipse.test.internal.performance.results.db.AbstractResults;
import org.eclipse.test.internal.performance.results.db.BuildResults;
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.ISharedImages;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.model.IWorkbenchAdapter;
import org.eclipse.ui.views.properties.ComboBoxPropertyDescriptor;
import org.eclipse.ui.views.properties.IPropertyDescriptor;
import org.eclipse.ui.views.properties.IPropertySource;
import org.eclipse.ui.views.properties.PropertyDescriptor;
import org.eclipse.ui.views.properties.TextPropertyDescriptor;
import org.osgi.service.prefs.BackingStoreException;

/**
 * An Organization Element
 */
public abstract class ResultsElement implements IAdaptable, IPropertySource, IWorkbenchAdapter, Comparable<ResultsElement> {

	// Image descriptors
	private static final ISharedImages WORKBENCH_SHARED_IMAGES = PlatformUI.getWorkbench().getSharedImages();
	public static final Image ERROR_IMAGE = WORKBENCH_SHARED_IMAGES.getImage(ISharedImages.IMG_OBJS_ERROR_TSK);
	public static final ImageDescriptor ERROR_IMAGE_DESCRIPTOR = WORKBENCH_SHARED_IMAGES.getImageDescriptor(ISharedImages.IMG_OBJS_ERROR_TSK);
	public static final Image WARN_IMAGE = WORKBENCH_SHARED_IMAGES.getImage(ISharedImages.IMG_OBJS_WARN_TSK);
	public static final ImageDescriptor WARN_IMAGE_DESCRIPTOR = WORKBENCH_SHARED_IMAGES.getImageDescriptor(ISharedImages.IMG_OBJS_WARN_TSK);
	public static final Image INFO_IMAGE = WORKBENCH_SHARED_IMAGES.getImage(ISharedImages.IMG_OBJS_INFO_TSK);
	public static final ImageDescriptor INFO_IMAGE_DESCRIPTOR = WORKBENCH_SHARED_IMAGES.getImageDescriptor(ISharedImages.IMG_OBJS_INFO_TSK);
	public static final Image HELP_IMAGE = WORKBENCH_SHARED_IMAGES.getImage(ISharedImages.IMG_LCL_LINKTO_HELP);
	public static final ImageDescriptor HELP_IMAGE_DESCRIPTOR = WORKBENCH_SHARED_IMAGES.getImageDescriptor(ISharedImages.IMG_LCL_LINKTO_HELP);
	public static final ImageDescriptor FOLDER_IMAGE_DESCRIPTOR = WORKBENCH_SHARED_IMAGES.getImageDescriptor(ISharedImages.IMG_OBJ_FOLDER);
	public static final ImageDescriptor CONNECT_IMAGE_DESCRIPTOR = WORKBENCH_SHARED_IMAGES.getImageDescriptor(ISharedImages.IMG_ELCL_SYNCED);

	// Model
    ResultsElement parent;
	AbstractResults results;
	ResultsElement[] children;
	String name;
	int status = -1;

	// Stats
    double[] statistics;

	// Status constants
	// state
	static final int UNKNOWN = 0x01;
	static final int UNREAD = 0x02;
	static final int READ = 0x04;
	static final int MISSING = 0x08;
	public static final int STATE_MASK = 0x0F;
	// info
	static final int SMALL_VALUE = 0x0010;
	static final int STUDENT_TTEST = 0x0020;
	public static final int INFO_MASK = 0x0030;
	// warning
	static final int NO_BASELINE = 0x0040;
	static final int SINGLE_RUN = 0x0080;
	static final int BIG_ERROR = 0x0100;
	static final int NOT_STABLE = 0x0200;
	static final int NOT_RELIABLE = 0x0400;
	public static final int WARNING_MASK = 0x0FC0;
	// error
	static final int BIG_DELTA = 0x1000;
	public static final int ERROR_MASK = 0xF000;

	// Property descriptors
	static final String P_ID_STATUS_INFO = "ResultsElement.status_info"; //$NON-NLS-1$
	static final String P_ID_STATUS_WARNING = "ResultsElement.status_warning"; //$NON-NLS-1$
	static final String P_ID_STATUS_ERROR = "ResultsElement.status_error"; //$NON-NLS-1$
	static final String P_ID_STATUS_COMMENT = "ResultsElement.status_comment"; //$NON-NLS-1$

	static final String P_STR_STATUS_INFO = " info"; //$NON-NLS-1$
	static final String P_STR_STATUS_WARNING = "warning"; //$NON-NLS-1$
	static final String P_STR_STATUS_ERROR = "error"; //$NON-NLS-1$
	static final String P_STR_STATUS_COMMENT = "comment"; //$NON-NLS-1$
	static final String[] NO_VALUES = new String[0];

	private static Vector<IPropertyDescriptor> DESCRIPTORS;
	static final TextPropertyDescriptor COMMENT_DESCRIPTOR = new TextPropertyDescriptor(P_ID_STATUS_COMMENT, P_STR_STATUS_COMMENT);
	static final TextPropertyDescriptor ERROR_DESCRIPTOR = new TextPropertyDescriptor(P_ID_STATUS_ERROR, P_STR_STATUS_ERROR);
    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");
		// Survey category
		DESCRIPTORS.add(COMMENT_DESCRIPTOR);
		COMMENT_DESCRIPTOR.setCategory("Survey");
		return DESCRIPTORS;
	}
    static Vector<IPropertyDescriptor> getDescriptors() {
    	return DESCRIPTORS;
	}
    static ComboBoxPropertyDescriptor getInfosDescriptor(int status) {
		List<String> list = new ArrayList<>();
		if ((status & SMALL_VALUE) != 0) {
			list.add("Some builds have tests with small values");
		}
		if ((status & STUDENT_TTEST) != 0) {
			list.add("Some builds have student-t test error 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("Some builds have tests with error over 3%");
		}
		if ((status & NOT_RELIABLE) != 0) {
			list.add("Some builds have no reliable tests");
		}
		if ((status & NOT_STABLE) != 0) {
			list.add("Some builds have no stable tests");
		}
		if ((status & NO_BASELINE) != 0) {
			list.add("Some builds have no baseline to compare with");
		}
		if ((status & SINGLE_RUN) != 0) {
			list.add("Some builds have single run tests");
		}
		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;
	}

ResultsElement() {
}

ResultsElement(AbstractResults results, ResultsElement parent) {
    this.parent = parent;
    this.results = results;
}

ResultsElement(String name, ResultsElement parent) {
	this.parent = parent;
	this.name = name;
}

@Override
public int compareTo(ResultsElement o) {
	if (this.results == null) {
		if (o != null && this.name != null) {
			ResultsElement element = o;
			return this.name.compareTo(element.getName());
		}
		return -1;
	}
	if (o != null) {
		return this.results.compareTo(o.results);
	}
	return -1;
}

abstract ResultsElement createChild(AbstractResults testResults);

@Override
public <T> T getAdapter(Class<T> adapter) {
    if (adapter == IPropertySource.class) {
        return adapter.cast(this);
    }
    if (adapter == IWorkbenchAdapter.class) {
        return adapter.cast(this);
    }
    return null;
}

/**
 * Iterate the element children.
 */
public ResultsElement[] getChildren() {
	if (this.results == null) {
		return new ResultsElement[0];
	}
	if (this.children == null) {
		initChildren();
	}
    return this.children;
}

@Override
public Object[] getChildren(Object o) {
	if (this.results == null) {
		return new Object[0];
	}
	if (this.children == null) {
		initChildren();
	}
    return this.children;
}

@Override
public Object getEditableValue() {
    return this;
}

final String getId() {
	return getId(new StringBuilder()).toString();
}

private StringBuilder getId(StringBuilder buffer) {
	if (this.parent != null) {
		return this.parent.getId(buffer).append('/').append(getName());
	}
	return buffer;
}

@Override
public ImageDescriptor getImageDescriptor(Object object) {
	if (object instanceof ResultsElement) {
		ResultsElement resultsElement = (ResultsElement) object;
// DEBUG
//		if (resultsElement.getName().equals("I20090806-0100")) {
//			if (resultsElement.results != null) {
//				String toString = resultsElement.results.getParent().toString();
//				String toString = resultsElement.results.toString();
//				if (toString.indexOf("testStoreExists")>0 && toString.indexOf("eplnx2")>0) {
//					System.out.println("stop");
//				}
//			}
//		}
		int elementStatus = resultsElement.getStatus();
		if (elementStatus == MISSING) {
			return HELP_IMAGE_DESCRIPTOR;
		}
		if ((elementStatus & ResultsElement.ERROR_MASK) != 0) {
			return ERROR_IMAGE_DESCRIPTOR;
		}
		if ((elementStatus & ResultsElement.WARNING_MASK) != 0) {
			return WARN_IMAGE_DESCRIPTOR;
		}
		if ((elementStatus & ResultsElement.INFO_MASK) != 0) {
			return INFO_IMAGE_DESCRIPTOR;
		}
	}
	return null;
}

@Override
public String getLabel(Object o) {
    return getName();
}

/**
 * Returns the name
 */
public String getName() {
	if (this.name == null && this.results != null) {
		this.name = this.results.getName();
	}
	return this.name;
}

/**
 * Returns the parent
 */
@Override
public Object getParent(Object o) {
    return this.parent;
}

@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) {
	if (propKey.equals(P_ID_STATUS_INFO)) {
		if ((getStatus() & INFO_MASK) != 0) {
			return Integer.valueOf(0);
		}
	}
	if (propKey.equals(P_ID_STATUS_WARNING)) {
		if ((getStatus() & WARNING_MASK) != 0) {
			return Integer.valueOf(0);
		}
	}
	if (propKey.equals(P_ID_STATUS_ERROR)) {
		if ((getStatus() & BIG_DELTA) != 0) {
			return "Some builds have tests with regression";
		}
	}
	if (propKey.equals(P_ID_STATUS_COMMENT)) {
		IEclipsePreferences preferences = InstanceScope.INSTANCE.getNode(IPerformancesConstants.PLUGIN_ID);
		return preferences.get(getId(), "");
	}
	return null;
}

public ResultsElement getResultsElement(String resultName) {
	int length = getChildren(null).length;
	for (int i=0; i<length; i++) {
		ResultsElement searchedResults = this.children[i];
		if (searchedResults.getName().equals(resultName)) {
			return searchedResults;
		}
	}
	return null;
}

/**
 * Return the status of the element.
 *
 * The status is a bit mask pattern where digits are
 * allowed as follow:
 *	<ul>
 * 		<li>0-3: bits for state showing whether the element is
 * 			<ul>
 * 				<li>{@link #UNKNOWN} : not connected to a db</li>
 * 				<li>{@link #UNREAD} : is not valid (e.g. NaN results)</li>
 * 				<li>{@link #MISSING} : no results (e.g. the perf machine crashed and didn't store any results)</li>
 * 				<li>{@link #READ} : has valid results</li>
 * 			</ul>
 * 		</li>
 * 		<li>4-5: bits for information. Current possible information are
 * 			<ul>
 * 				<li>{@link #SMALL_VALUE} : build results or delta with baseline value is under 100ms</li>
 * 				<li>{@link #STUDENT_TTEST} : the Student T-test is over the threshold (old yellow color for test results)</li>
 * 			</ul>
 * 		</li>
 * 		<li>6-11: bits for warnings. Current possible warnings are
 * 			<ul>
 * 				<li>{@link #NO_BASELINE} : no baseline for the current build</li>
 * 				<li>{@link #SINGLE_RUN} : the test has only one run (i.e. no error could be computed), hence its reliability cannot be evaluated</li>
 * 				<li>{@link #BIG_ERROR} : the test result is over the 3% threshold</li>
 * 				<li>{@link #NOT_STABLE} : the test history shows a deviation between 10% and 20% (may mean that this test is not so reliable)</li>
 * 				<li>{@link #NOT_RELIABLE} : the test history shows a deviation over 20% (surely means that this test is too erratic to be reliable)</li>
 * 			</ul>
 * 		</li>
 * 		<li>12-15: bits for errors. Current possible errors are
 * 			<ul>
 * 				<li>{@link #BIG_DELTA} : the delta for the test is over the 10% threshold</li>
 * 			</ul>
 * 		</li>
 *	</ul>
 *
 * Note that these explanation applied to {@link BuildResultsElement}, and {@link DimResultsElement}.
 * For {@link ComponentResultsElement}, and {@link ScenarioResultsElement}, it's the merge of all the children status
 * and means "Some tests have..." instead of "The test has...". For {@link ConfigResultsElement}, it means the status
 * of the most recent build compared to its most recent baseline.
 *
 * @return An int with each bit set when the corresponding symptom applies.
 */
public final int getStatus() {
	if (this.status < 0) {
		initStatus();
	}
	return this.status;
}

/**
 * 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>
 */
double[] getStatistics() {
	return this.statistics;
}

/**
 * Returns whether the element (or one in its hierarchy) has an error.
 *
 * @return <code> true</code> if the element or one in its hierarchy has an error,
 * 	<code> false</code>  otherwise
 */
public final boolean hasError() {
	return (getStatus() & ERROR_MASK) != 0;
}

void initChildren() {
	AbstractResults[] resultsChildren = this.results.getChildren();
	int length = resultsChildren.length;
	this.children = new ResultsElement[length];
	int count = 0;
	for (int i=0; i<length; i++) {
		ResultsElement childElement = createChild(resultsChildren[i]);
		if (childElement != null) {
			this.children[count++] = childElement;
		}
	}
	if (count < length) {
		System.arraycopy(this.children, 0, this.children = new ResultsElement[count], 0, count);
	}
}
void initStatus() {
	this.status = READ;
	if (this.results != null) {
		if (this.children == null) initChildren();
		int length = this.children.length;
		for (int i=0; i<length; i++) {
			this.status |= this.children[i].getStatus();
		}
	}
}

int initStatus(BuildResults buildResults) {
	this.status = READ;

	// Get values
	double buildValue = buildResults.getValue();
	ConfigResults configResults = (ConfigResults) buildResults.getParent();
	BuildResults baselineResults = configResults.getBaselineBuildResults(buildResults.getName());
	double baselineValue = baselineResults.getValue();
	double delta = (baselineValue - buildValue) / baselineValue;

	// Store if there's no baseline
	if (Double.isNaN(delta)) {
		this.status |= NO_BASELINE;
	}

	// Store if there's only one run
	long baselineCount = baselineResults.getCount();
	long currentCount = buildResults.getCount();
	double error = Double.NaN;
	if (baselineCount == 1 || currentCount == 1) {
		this.status |= SINGLE_RUN;
	}

	// Store if the T-test is not good
	double ttestValue = Util.computeTTest(baselineResults, buildResults);
	int degreeOfFreedom = (int) (baselineResults.getCount()+buildResults.getCount()-2);
	if (ttestValue >= 0 && StatisticsUtil.getStudentsT(degreeOfFreedom, StatisticsUtil.T90) >= ttestValue) {
		this.status |= STUDENT_TTEST;
	}

	// Store if there's a big error (over 3%)
	double baselineError = baselineResults.getError();
	double currentError = buildResults.getError();
	error = Double.isNaN(baselineError)
			? currentError / baselineValue
			: Math.sqrt(baselineError*baselineError + currentError*currentError) / baselineValue;
	if (error > 0.03) {
		this.status |= BIG_ERROR;
	}

	// Store if there's a big delta (over 10%)
	if (delta <= -0.1) {
		this.status |= BIG_DELTA;
		double currentBuildValue = buildResults.getValue();
		double diff = Math.abs(baselineValue - currentBuildValue);
		if (currentBuildValue < 100 || diff < 100) { // moderate the status when
			// diff is less than 100ms
			this.status |= SMALL_VALUE;
		} else {
			double[] stats = getStatistics();
			if (stats != null) {
				if (stats[3] > 0.2) { // invalidate the status when the test
					// historical deviation is over 20%
					this.status |= NOT_RELIABLE;
				} else if (stats[3] > 0.1) { // moderate the status when the test
					// historical deviation is between 10%
					// and 20%
					this.status |= NOT_STABLE;
				}
			}
		}
	}

	return this.status;
}

public boolean isInitialized() {
	return this.results != null;
}

@Override
public boolean isPropertySet(Object property) {
    return false;
}

boolean onlyFingerprints() {
	if (this.parent != null) {
		return this.parent.onlyFingerprints();
	}
	return ((PerformanceResultsElement)this).fingerprints;
}

@Override
public void resetPropertyValue(Object property) {
}

void resetStatus() {
	this.status = -1;
	if (this.results != null) {
		if (this.children == null) initChildren();
		int length = this.children.length;
		for (int i=0; i<length; i++) {
			this.children[i].resetStatus();
		}
	}
}

@Override
public void setPropertyValue(Object name, Object value) {
	if (name.equals(P_ID_STATUS_COMMENT)) {
		IEclipsePreferences preferences = InstanceScope.INSTANCE.getNode(IPerformancesConstants.PLUGIN_ID);
		preferences.put(getId(), (String) value);
		try {
			preferences.flush();
		} catch (BackingStoreException e) {
			// skip
		}
	}
}

@Override
public String toString() {
	if (this.results == null) {
		return getName();
	}
	return this.results.toString();
}

/*
 * Write the failures of the element in the given buffer
 */
StringBuilder getFailures(StringBuilder buffer, int kind, StringBuilder excluded) {
	int length = getChildren().length;
	for (int i=0; i<length; i++) {
		this.children[i].getFailures(buffer, kind, excluded);
	}
	return buffer;
}


}
