/***************************************************************************************************
 * Copyright (c) 2003, 2004 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.wst.common.frameworks.internal.operations;

import java.lang.reflect.InvocationTargetException;
import java.util.List;

import org.eclipse.core.internal.runtime.Assert;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResourceStatus;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.IWorkspaceRunnable;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
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.SubProgressMonitor;
import org.eclipse.core.runtime.jobs.ISchedulingRule;
import org.eclipse.wst.common.frameworks.internal.AdaptabilityUtility;
import org.eclipse.wst.common.frameworks.internal.WTPResourceHandler;
import org.eclipse.wst.common.frameworks.internal.enablement.IEnablementManager;
import org.eclipse.wst.common.frameworks.internal.enablement.nonui.WFTWrappedException;
import org.eclipse.wst.common.frameworks.internal.plugin.WTPCommonPlugin;

//TODO perhaps this class should be subclassed from a new super class which more closely resembles org.eclipse.ui.actions.WorkspaceModifyOperation
/**
 * An operation which potentially makes changes to the workspace. All resource modification should
 * be performed using this operation. The primary consequence of using this operation is that events
 * which typically occur as a result of workspace changes (such as the firing of resource deltas,
 * performance of autobuilds, etc.) are deferred until the outermost operation has successfully
 * completed.
 * <p>
 * Subclasses must implement <code>execute</code> to do the work of the operation.
 * </p>
 * This class is EXPERIMENTAL and is subject to substantial changes.
 */
public abstract class WTPOperation implements IHeadlessRunnableWithProgress {

	/**
	 * The dataModel used to execute this operation
	 */
	protected WTPOperationDataModel operationDataModel;

	private OperationStatus opStatus;

	private String id;

	/**
	 * Constructor for the operation. Clients should use this constructor instead of the no argument
	 * constructor.
	 * 
	 * @param operationDataModel
	 */
	public WTPOperation(WTPOperationDataModel operationDataModel) {
		setOperationDataModel(operationDataModel);
	}

	/**
	 * This no argument constructor should not be used by clients. This is for extended operations.
	 * 
	 * ExtendedOperations
	 */
	public WTPOperation() {
	}

	//TODO see if this can be made package visible only.
	/**
	 * Note: This method is for internal use only. Clients should not call this method.
	 * 
	 * ExtendedOperations
	 * 
	 * @param value
	 *            the operation's id
	 */
	public final void setID(String value) {
		Assert.isTrue(this.id == null, WTPResourceHandler.getString("22")); //$NON-NLS-1$
		Assert.isNotNull(value, WTPResourceHandler.getString("23")); //$NON-NLS-1$
		this.id = value;
	}

	//TODO see if this can be removed
	/**
	 * Note: This method is for internal use only. Clients should not call this method.
	 * 
	 * ExtendedOperations
	 * 
	 * @return the operation's id
	 */
	public final String getID() {
		return this.id;
	}

	//TODO see if this can be make package visible only.
	/**
	 * Note: This method is for internal use only. Clients should not call this method.
	 * 
	 * @param operationDataModel
	 */
	public final void setOperationDataModel(WTPOperationDataModel operationDataModel) {
		this.operationDataModel = operationDataModel;
	}

	/**
	 * Returns the dataModels used by this operation.
	 * 
	 * @return the dataModels used by this operation.
	 */
	public final WTPOperationDataModel getOperationDataModel() {
		return operationDataModel;
	}

	/**
	 * Returns the result status of this operation. If this operation net been executed, then it
	 * will return null.
	 * 
	 * @return he result status of this operation.
	 */
	public IStatus getStatus() {
		if (null == opStatus)
			return WTPCommonPlugin.OK_STATUS;
		return opStatus;
	}

	/**
	 * Performs the steps that are to be treated as a single logical workspace change.
	 * <p>
	 * Subclasses must implement this method.
	 * </p>
	 * 
	 * @param monitor
	 *            the progress monitor to use to display progress and field user requests to cancel
	 * @exception CoreException
	 *                if the operation fails due to a CoreException
	 * @exception InvocationTargetException
	 *                if the operation fails due to an exception other than CoreException
	 * @exception InterruptedException
	 *                if the operation detects a request to cancel, using
	 *                <code>IProgressMonitor.isCanceled()</code>, it should exit by throwing
	 *                <code>InterruptedException</code>
	 */
	protected abstract void execute(IProgressMonitor monitor) throws CoreException, InvocationTargetException, InterruptedException;

	/**
	 * Subclasses should override as necessary to perform any additional initialization before
	 * executing.
	 * 
	 * @param monitor
	 *            the progress monitor
	 */
	protected void initilize(IProgressMonitor monitor) {
		//Making sure the status objects are initialized
		//		status = null;
		opStatus = null;
	}

	private ComposedExtendedOperationHolder initializeExtensionOperations() {
		return OperationExtensionRegistry.getExtensions(this);
	}

	/**
	 * <p>
	 * Subclasses should override as necessary to perform any post executiong cleanup. Subclasses,
	 * should not initialize any resources anywhere other than within either the
	 * initialize(IProjgressMonitor) or the execute(IProgressMonitor) methods. This method will
	 * always be called when an operation is run irregardless of whether the execution is
	 * successful.
	 * </p>
	 * <p>
	 * Clients should never need to call this method
	 * </p>
	 * 
	 * @param monitor
	 *            the progress monitor
	 */
	protected void dispose(IProgressMonitor monitor) {
	}

	//TODO see if this can be removed
	/**
	 * Note: This method is for internal use only. Clients should not call this method.
	 * 
	 * @return the workspace
	 */
	protected IWorkspace getWorkspace() {
		return ResourcesPlugin.getWorkspace();
	}

	//TODO see if this can be removed
	/**
	 * Note: This method is for internal use only. Clients should not call this method.
	 * 
	 * @param op
	 *            the to append
	 * @return A new operation
	 */
	public WTPOperation append(WTPOperation op) {
		ComposedOperation composedOp = new ComposedOperation();
		composedOp.addRunnable(this);
		composedOp.addRunnable(op);
		return composedOp;
	}

	/**
	 * Initiates a batch of changes, by invoking the execute() method as a workspace runnable.
	 * Client should always call this method and never call the execute() method.
	 * 
	 * @param monitor
	 *            the progress monitor to use to display progress
	 * @exception InvocationTargetException
	 *                wraps any CoreException, runtime exception or error thrown by the execute()
	 *                method
	 * @see WorkspaceModifyOperation - this class was directly copied from it
	 */
	public synchronized final void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
		final InvocationTargetException[] iteHolder = new InvocationTargetException[1];
		try {

			IWorkspaceRunnable workspaceRunnable = new IWorkspaceRunnable() {

				public void run(IProgressMonitor pm) throws CoreException {
					try {
						doRun(pm);
						if (opStatus != null && !opStatus.isOK()) {
							//TODO do something with the status
							System.out.println(opStatus.getMessage());
						}
					} catch (InvocationTargetException e) {
						// Pass it outside the workspace runnable
						iteHolder[0] = e;
					} catch (InterruptedException e) {
						// Re-throw as OperationCanceledException, which will
						// be
						// caught and re-thrown as InterruptedException below.
						throw new OperationCanceledException(e.getMessage());
					}
				}
			};
			ISchedulingRule rule = getSchedulingRule();
			if (rule == null)
				ResourcesPlugin.getWorkspace().run(workspaceRunnable, monitor);
			else
				ResourcesPlugin.getWorkspace().run(workspaceRunnable, rule, 0, monitor);
		} catch (CoreException e) {
			if (e.getStatus().getCode() == IResourceStatus.OPERATION_FAILED)
				throw new WFTWrappedException(e.getStatus().getException(), e.getMessage());
			throw new WFTWrappedException(e);
		} catch (OperationCanceledException e) {
			throw new InterruptedException(e.getMessage());
		}
		// Re-throw the InvocationTargetException, if any occurred
		if (iteHolder[0] != null) {
			throw new WFTWrappedException(iteHolder[0].getTargetException(), iteHolder[0].getMessage());
		}
	}

	/**
	 * @return
	 */
	protected ISchedulingRule getSchedulingRule() {
		return null;
	}

	/**
	 * Typically clients should call the run(IProgressMonitor) method instead of this method. This
	 * may be used by subclassed operations during execution to invoke other operations. This method
	 * runs within the same the same WorkspaceRunnable as the calling operation.
	 * 
	 * @param monitor
	 *            the progress monitor to use to display progress
	 * @throws CoreException
	 * @throws InvocationTargetException
	 * @throws InterruptedException
	 */
	public final void doRun(IProgressMonitor monitor) throws CoreException, InvocationTargetException, InterruptedException {
		boolean alreadyLocked = operationDataModel == null ? true : operationDataModel.isLocked();
		boolean operationValidationEnabled = operationDataModel == null ? false : operationDataModel.isOperationValidationEnabled();
		try {
			if (!alreadyLocked) {
				operationDataModel.setLocked(true);
			}
			if (operationValidationEnabled) {
				operationDataModel.setOperationValidationEnabled(false);
				IStatus status = operationDataModel.validateDataModel();
				if (!status.isOK()) {
					//TODO display something to user and remove System.out
					System.out.println(WTPResourceHandler.getString("24", new Object[]{status.getMessage()})); //$NON-NLS-1$
					Thread.dumpStack();
					return;
				}
			}
			initilize(monitor);

			if (!validateEdit())
				return;
			//if (getStatus().isOK()) {
			ComposedExtendedOperationHolder extOpHolder = initializeExtensionOperations();
			IStatus preOpStatus = runPreOps(monitor, extOpHolder);
			execute(monitor);
			IStatus postOpStatus = runPostOps(monitor, extOpHolder);
			if (null != preOpStatus)
				addExtendedStatus(preOpStatus);
			if (null != postOpStatus)
				addExtendedStatus(postOpStatus);
			//}
		} finally {
			dispose(monitor);

			if (!alreadyLocked) {
				operationDataModel.setLocked(false);
			}
			if (operationValidationEnabled) {
				operationDataModel.setOperationValidationEnabled(true);
			}

		}
		// CoreException and OperationCanceledException are propagated
	}

	/**
	 * This method is called when an operation is run after initialize() is called, but before
	 * execute(). If this method returns <code>true</code> then operation's execution continues,
	 * otherwise, execution is aborted. Subclasses should override this method to provide any final
	 * initialization and validation required before execution.
	 * 
	 * @return
	 */
	protected boolean validateEdit() {
		return true;
	}

	//TODO lock down addStatus so it throws runtime exceptions if not called during execute.
	//TODO make this protected and create a package level accessor for WTPOperationJobAdapter
	/**
	 * <p>
	 * Adds a status to this opererations status. If this operation currently has no status, then
	 * the specified status becomes the operation's status. If the operation already has a status,
	 * then that status is converted to a multistatus and the specified status is appendend to it.
	 * </p>
	 * <p>
	 * This method should only be called from the execute() method of subclasses.
	 * </p>
	 * 
	 * @param aStatus
	 *            the status to add.
	 */
	public final void addStatus(IStatus aStatus) {
		if (opStatus == null) {
			opStatus = new OperationStatus(aStatus.getMessage(), aStatus.getException());
			opStatus.setSeverity(aStatus.getSeverity());
			opStatus.add(aStatus);
		} else {
			opStatus.add(aStatus);
		}
	}

	/**
	 * This is to keep track of extended operation stati. If the main status is WARNING, an extended
	 * status of ERROR will not make the main status ERROR. If the main status is OK, an extended
	 * status of ERROR or WARNING will make the main status WARNING.
	 * 
	 * @param aStatus
	 */
	private void addExtendedStatus(IStatus aStatus) {
		if (opStatus == null) {
			opStatus = new OperationStatus(new IStatus[]{WTPCommonPlugin.OK_STATUS});
		}
		opStatus.addExtendedStatus(aStatus);
	}

	private IStatus runPostOps(IProgressMonitor pm, ComposedExtendedOperationHolder extOpHolder) {
		IStatus postOpStatus = null;
		if ((extOpHolder != null) && extOpHolder.hasPostOps()) {
			postOpStatus = runExtendedOps(extOpHolder.getPostOps(), pm);
		}

		return postOpStatus;
	}

	private IStatus runPreOps(IProgressMonitor pm, ComposedExtendedOperationHolder extOpHolder) {
		IStatus preOpStatus = null;
		if ((extOpHolder != null) && extOpHolder.hasPreOps()) {
			preOpStatus = runExtendedOps(extOpHolder.getPreOps(), pm);
		}
		return preOpStatus;
	}

	private IStatus runExtendedOps(List opList, IProgressMonitor pm) {
		WTPOperation op = null;
		OperationStatus returnStatus = null;
		IStatus localStatus;
		String opId = null;
		for (int i = 0; i < opList.size(); i++) {
			op = (WTPOperation) opList.get(i);
			try {
				opId = op.getID();
				boolean shouldExtendedRun = true;
				List extendedContext = (List) operationDataModel.getProperty(WTPOperationDataModel.EXTENDED_CONTEXT);
				for (int contextCount = 0; shouldExtendedRun && contextCount < extendedContext.size(); contextCount++) {
					IProject project = (IProject) AdaptabilityUtility.getAdapter(extendedContext.get(contextCount), IProject.class);
					if (null != project && !IEnablementManager.INSTANCE.getIdentifier(opId, project).isEnabled()) {
						shouldExtendedRun = false;
					}
				}
				if (shouldExtendedRun) {
					op.setOperationDataModel(operationDataModel);
					op.doRun(new SubProgressMonitor(pm, IProgressMonitor.UNKNOWN));
					localStatus = op.getStatus();
				} else
					localStatus = null;
			} catch (Exception e) {
				localStatus = new Status(IStatus.ERROR, WTPCommonPlugin.PLUGIN_ID, 0, WTPResourceHandler.getString("25", new Object[]{op.getClass().getName()}), e); //$NON-NLS-1$
			}
			if (localStatus != null) {
				if (returnStatus == null) {
					returnStatus = new OperationStatus(new IStatus[]{localStatus});
				} else {
					returnStatus.add(localStatus);
				}
			}
		}
		return returnStatus;
	}

	//	protected WTPOperation getRootExtendedOperation() {
	//		if (this.getRootExtendedOperation() == null)
	//			return this;
	//		return this.getRootExtendedOperation();
	//	}

	//TODO this should be deleted.
	/**
	 * Note: This method is for internal use only. Clients should not call this method.
	 */
	protected static final void runNestedDefaultOperation(WTPOperationDataModel model, IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
		WTPOperation op = model.getDefaultOperation();
		if (op != null)
			op.run(monitor);
	}
}