/*******************************************************************************
 * Copyright (c) 2005, 2006 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.jdt.internal.ui.text.java;

import java.util.Collections;
import java.util.List;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.InvalidRegistryObjectException;
import org.eclipse.core.runtime.PerformanceStats;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;

import org.eclipse.jface.text.Assert;

import org.eclipse.jdt.internal.corext.util.Messages;

import org.eclipse.jdt.ui.text.java.AbstractProposalSorter;
import org.eclipse.jdt.ui.text.java.ContentAssistInvocationContext;

import org.eclipse.jdt.internal.ui.JavaPlugin;

import org.osgi.framework.Bundle;

/**
 * The description of an extension to the
 * <code>org.eclipse.jdt.ui.javaCompletionProposalSorters</code> extension point. Instances are
 * immutable.
 * 
 * @since 3.2
 */
public final class ProposalSorterHandle {
	/** The extension schema name of the id attribute. */
	private static final String ID= "id"; //$NON-NLS-1$
	/** The extension schema name of the name attribute. */
	private static final String NAME= "name"; //$NON-NLS-1$
	/** The extension schema name of the class attribute. */
	private static final String CLASS= "class"; //$NON-NLS-1$
	/** The extension schema name of the activate attribute. */
	private static final String ACTIVATE= "activate"; //$NON-NLS-1$
	/** The name of the performance event used to trace extensions. */
	private static final String PERFORMANCE_EVENT= JavaPlugin.getPluginId() + "/perf/content_assist_sorters/extensions"; //$NON-NLS-1$
	/**
	 * If <code>true</code>, execution time of extensions is measured and extensions may be
	 * disabled if execution takes too long.
	 */
	private static final boolean MEASURE_PERFORMANCE= PerformanceStats.isEnabled(PERFORMANCE_EVENT);
	/** The one and only operation name. */
	private static final String SORT= "sort"; //$NON-NLS-1$

	/** The identifier of the extension. */
	private final String fId;
	/** The name of the extension. */
	private final String fName;
	/** The class name of the provided <code>AbstractProposalSorter</code>. */
	private final String fClass;
	/** The activate attribute value. */
	private final boolean fActivate;
	/** The configuration element of this extension. */
	private final IConfigurationElement fElement;
	/** The computer, if instantiated, <code>null</code> otherwise. */
	private AbstractProposalSorter fSorter;

	/**
	 * Creates a new descriptor.
	 * 
	 * @param element the configuration element to read
	 * @throws InvalidRegistryObjectException if the configuration element is not valid any longer
	 *         or does not contain mandatory attributes
	 */
	ProposalSorterHandle(IConfigurationElement element) throws InvalidRegistryObjectException {
		Assert.isLegal(element != null);
		
		fElement= element;
		fId= element.getAttribute(ID);
		checkNotNull(fId, ID);

		String name= element.getAttribute(NAME);
		if (name == null)
			fName= fId;
		else
			fName= name;
		
		String activateAttribute= element.getAttribute(ACTIVATE);
		fActivate= Boolean.valueOf(activateAttribute).booleanValue();

		fClass= element.getAttribute(CLASS);
		checkNotNull(fClass, CLASS);
	}

	/**
	 * Checks an element that must be defined according to the extension
	 * point schema. Throws an
	 * <code>InvalidRegistryObjectException</code> if <code>obj</code>
	 * is <code>null</code>.
	 */
	private void checkNotNull(Object obj, String attribute) throws InvalidRegistryObjectException {
		if (obj == null) {
			Object[] args= { getId(), fElement.getContributor().getName(), attribute };
			String message= Messages.format(JavaTextMessages.CompletionProposalComputerDescriptor_illegal_attribute_message, args);
			IStatus status= new Status(IStatus.WARNING, JavaPlugin.getPluginId(), IStatus.OK, message, null);
			JavaPlugin.log(status);
			throw new InvalidRegistryObjectException();
		}
	}

	/**
	 * Returns the identifier of the described extension.
	 *
	 * @return Returns the id
	 */
	public String getId() {
		return fId;
	}

	/**
	 * Returns the name of the described extension.
	 * 
	 * @return Returns the name
	 */
	public String getName() {
		return fName;
	}
	
	/**
	 * Returns a cached instance of the sorter as described in the extension's xml. The sorter is
	 * {@link #createSorter() created} the first time that this method is called and then cached.
	 * 
	 * @return a new instance of the proposal sorter as described by this descriptor
	 * @throws CoreException if the creation fails
	 * @throws InvalidRegistryObjectException if the extension is not valid any longer (e.g. due to
	 *         plug-in unloading)
	 */
	private synchronized AbstractProposalSorter getSorter() throws CoreException, InvalidRegistryObjectException {
		if (fSorter == null && (fActivate || isPluginLoaded()))
			fSorter= createSorter();
		return fSorter;
	}

	private boolean isPluginLoaded() throws InvalidRegistryObjectException {
		Bundle bundle= getBundle();
		return bundle != null && bundle.getState() == Bundle.ACTIVE;
	}

	private Bundle getBundle() throws InvalidRegistryObjectException {
		String symbolicName= fElement.getContributor().getName();
		Bundle bundle= Platform.getBundle(symbolicName);
		return bundle;
	}

	/**
	 * Returns a new instance of the sorter as described in the
	 * extension's xml.
	 * 
	 * @return a new instance of the completion proposal computer as
	 *         described by this descriptor
	 * @throws CoreException if the creation fails
	 * @throws InvalidRegistryObjectException if the extension is not
	 *         valid any longer (e.g. due to plug-in unloading)
	 */
	private AbstractProposalSorter createSorter() throws CoreException, InvalidRegistryObjectException {
		return (AbstractProposalSorter) fElement.createExecutableExtension(CLASS);
	}
	
	/**
	 * Safely computes completion proposals through the described extension. If the extension throws
	 * an exception or otherwise does not adhere to the contract described in
	 * {@link AbstractProposalSorter}, the list is returned as is.
	 * 
	 * @param context the invocation context passed on to the extension
	 * @param proposals the list of computed completion proposals to be sorted (element type:
	 *        {@link org.eclipse.jface.text.contentassist.ICompletionProposal}), must be writable
	 */
	public void sortProposals(ContentAssistInvocationContext context, List proposals) {
		IStatus status;
		try {
			AbstractProposalSorter sorter= getSorter();
			
			PerformanceStats stats= startMeter(SORT, sorter);
			
			sorter.beginSorting(context);
			Collections.sort(proposals, sorter);
			sorter.endSorting();
			
			status= stopMeter(stats, SORT);
			
			// valid result
			if (status == null)
				return;
			
			status= createAPIViolationStatus(SORT);
			
		} catch (InvalidRegistryObjectException x) {
			status= createExceptionStatus(x);
		} catch (CoreException x) {
			status= createExceptionStatus(x);
		} catch (RuntimeException x) {
			status= createExceptionStatus(x);
		}

		JavaPlugin.log(status);
		return;
	}

	private IStatus stopMeter(final PerformanceStats stats, String operation) {
		if (MEASURE_PERFORMANCE) {
			stats.endRun();
			if (stats.isFailure())
				return createPerformanceStatus(operation);
		}
		return null;
	}

	private PerformanceStats startMeter(String context, AbstractProposalSorter sorter) {
		final PerformanceStats stats;
		if (MEASURE_PERFORMANCE) {
			stats= PerformanceStats.getStats(PERFORMANCE_EVENT, sorter);
			stats.startRun(context);
		} else {
			stats= null;
		}
		return stats;
	}

	private Status createExceptionStatus(InvalidRegistryObjectException x) {
		// extension has become invalid - log & disable
		String disable= createBlameMessage();
		String reason= JavaTextMessages.CompletionProposalComputerDescriptor_reason_invalid;
		return new Status(IStatus.INFO, JavaPlugin.getPluginId(), IStatus.OK, disable + " " + reason, x); //$NON-NLS-1$
	}

	private Status createExceptionStatus(CoreException x) {
		// unable to instantiate the extension - log & disable
		String disable= createBlameMessage();
		String reason= JavaTextMessages.CompletionProposalComputerDescriptor_reason_instantiation;
		return new Status(IStatus.ERROR, JavaPlugin.getPluginId(), IStatus.OK, disable + " " + reason, x); //$NON-NLS-1$
	}
	
	private Status createExceptionStatus(RuntimeException x) {
		// misbehaving extension - log & disable
		String disable= createBlameMessage();
		String reason= JavaTextMessages.CompletionProposalComputerDescriptor_reason_runtime_ex;
		return new Status(IStatus.WARNING, JavaPlugin.getPluginId(), IStatus.OK, disable + " " + reason, x); //$NON-NLS-1$
	}

	private Status createAPIViolationStatus(String operation) {
		String disable= createBlameMessage();
		Object[] args= {operation};
		String reason= Messages.format(JavaTextMessages.CompletionProposalComputerDescriptor_reason_API, args);
		return new Status(IStatus.WARNING, JavaPlugin.getPluginId(), IStatus.OK, disable + " " + reason, null); //$NON-NLS-1$
	}

	private Status createPerformanceStatus(String operation) {
		String disable= createBlameMessage();
		Object[] args= {operation};
		String reason= Messages.format(JavaTextMessages.CompletionProposalComputerDescriptor_reason_performance, args);
		return new Status(IStatus.WARNING, JavaPlugin.getPluginId(), IStatus.OK, disable + " " + reason, null); //$NON-NLS-1$
	}

	private String createBlameMessage() {
		Object[] args= { getName(), getId() };
		String disable= Messages.format(JavaTextMessages.ProposalSorterHandle_blame, args);
		return disable;
	}
	
	/**
	 * Returns the error message from the described extension, <code>null</code> for no error.
	 * 
	 * @return the error message from the described extension, <code>null</code> for no error
	 */
	public String getErrorMessage() {
		return null;
	}
	
}
