/*******************************************************************************
 * Copyright (c) 2000, 2009 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.db.DB_Results;
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 {

	// 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;
//    private ImageDescriptor imageDescriptor;
	AbstractResults results;
	ResultsElement[] children;
	String name;
	int status = -1;

	// 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 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 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 getDescriptors() {
    	return DESCRIPTORS;
	}
    static ComboBoxPropertyDescriptor getInfosDescriptor(int status) {
		List 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 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;
	}
    double deviation = -1;

ResultsElement() {
}

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

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

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

abstract ResultsElement createChild(AbstractResults testResults);

/* (non-Javadoc)
 * Method declared on IAdaptable
 */
public Object getAdapter(Class adapter) {
    if (adapter == IPropertySource.class) {
        return this;
    }
    if (adapter == IWorkbenchAdapter.class) {
        return 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;
}

/* (non-Javadoc)
 * Method declared on IWorkbenchAdapter
 */
public Object[] getChildren(Object o) {
	if (this.results == null) {
		return new Object[0];
	}
	if (this.children == null) {
		initChildren();
	}
    return this.children;
}

/* (non-Javadoc)
 * Method declared on IPropertySource
 */
public Object getEditableValue() {
    return this;
}

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

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

/* (non-Javadoc)
 * Method declared on IWorkbenchAdapter
 */
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;
}

/* (non-Javadoc)
 * Method declared on IWorkbenchAdapter
 */
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
 */
public Object getParent(Object o) {
    return this.parent;
}

/* (non-Javadoc)
 * @see org.eclipse.ui.views.properties.IPropertySource#getPropertyDescriptors()
 */
public IPropertyDescriptor[] getPropertyDescriptors() {
	Vector 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] = (IPropertyDescriptor) descriptors.get(i);
	}
	return descriptorsArray;
}

/* (non-Javadoc)
 * @see org.eclipse.ui.views.properties.IPropertySource#getPropertyValue(java.lang.Object)
 */
public Object getPropertyValue(Object propKey) {
	if (propKey.equals(P_ID_STATUS_INFO)) {
		if ((getStatus() & INFO_MASK) != 0) {
			return new Integer(0);
		}
	}
	if (propKey.equals(P_ID_STATUS_WARNING)) {
		if ((getStatus() & WARNING_MASK) != 0) {
			return new Integer(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 = new InstanceScope().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;
}

/**
 * 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;
	double buildValue = buildResults.getValue();
	ConfigResults configResults = (ConfigResults) buildResults.getParent();
	BuildResults baselineResults = configResults.getBaselineBuildResults(buildResults.getName());
	double baselineValue = baselineResults.getValue();
	double delta = (baselineValue - buildValue) / baselineValue;
	if (Double.isNaN(delta)) {
		this.status |= NO_BASELINE;
	}
	long baselineCount = baselineResults.getCount();
	long currentCount = buildResults.getCount();
	double error = Double.NaN;
	if (baselineCount == 1 || currentCount == 1) {
		this.status |= SINGLE_RUN;
	} else {
		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;
		}
		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;
		}
		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 {
				if (this.deviation < 0) {
					double[] stats = ((ConfigResults)buildResults.getParent()).getStatistics();
					this.deviation = stats[3];
				}
				if (this.deviation > 20) { // invalidate the status when the test
					// historical deviation is over 20%
					this.status |= NOT_RELIABLE;
				} else if (this.deviation > 10) { // 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;
}

/* (non-Javadoc)
 * Method declared on IPropertySource
 */
public boolean isPropertySet(Object property) {
    return false;
}

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

/* (non-Javadoc)
 * Method declared on IPropertySource
 */
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();
		}
	}
}

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

/**
 * Sets the image descriptor
 */
void setImageDescriptor(ImageDescriptor desc) {
//    this.imageDescriptor = desc;
}
public String toString() {
	if (this.results == null) {
		return getName();
	}
	return this.results.toString();
}

}
