/***************************************************************************************************
 * 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.jst.j2ee.internal.actions;


import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.jdt.internal.core.JavaProject;
import org.eclipse.jdt.ui.actions.SelectionDispatchAction;
import org.eclipse.jface.dialogs.ErrorDialog;
import org.eclipse.jface.dialogs.ProgressMonitorDialog;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.window.Window;
import org.eclipse.jst.j2ee.application.Application;
import org.eclipse.jst.j2ee.applicationclient.creation.ApplicationClientNatureRuntime;
import org.eclipse.jst.j2ee.internal.common.util.CommonUtil;
import org.eclipse.jst.j2ee.internal.dialogs.J2EERenameDialog;
import org.eclipse.jst.j2ee.internal.dialogs.J2EERenameUIConstants;
import org.eclipse.jst.j2ee.internal.dialogs.RenameModuleDialog;
import org.eclipse.jst.j2ee.internal.earcreation.EAREditModel;
import org.eclipse.jst.j2ee.internal.earcreation.EARNatureRuntime;
import org.eclipse.jst.j2ee.internal.ejb.project.EJBNatureRuntime;
import org.eclipse.jst.j2ee.internal.jca.operations.ConnectorNatureRuntime;
import org.eclipse.jst.j2ee.internal.listeners.IValidateEditListener;
import org.eclipse.jst.j2ee.internal.listeners.ValidateEditListener;
import org.eclipse.jst.j2ee.internal.plugin.CommonEditorUtility;
import org.eclipse.jst.j2ee.internal.plugin.J2EEPlugin;
import org.eclipse.jst.j2ee.internal.plugin.J2EEUIMessages;
import org.eclipse.jst.j2ee.internal.project.IWebNatureConstants;
import org.eclipse.jst.j2ee.internal.rename.RenameModuleOperation;
import org.eclipse.jst.j2ee.internal.rename.RenameOptions;
import org.eclipse.jst.j2ee.internal.web.operations.J2EEWebNatureRuntime;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IWorkbenchSite;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.actions.RenameResourceAction;
import org.eclipse.wst.common.frameworks.internal.ui.WTPUIPlugin;

import com.ibm.wtp.common.logger.proxy.Logger;
import com.ibm.wtp.emf.workbench.ProjectUtilities;

public class J2EERenameAction extends SelectionDispatchAction implements J2EERenameUIConstants {

	protected Shell shell;
	//Used for EAR rename
	protected Set referencedProjects;
	protected List projects;
	protected RenameOptions options;
	// added for IRefactoringAction behavior
	protected ISelectionProvider provider = null;
	protected RenameModuleOperation renameModuleOperation = null;

	/**
	 * Constructor for RenameModuleAction.
	 * 
	 * @param text
	 */
	public J2EERenameAction(IWorkbenchSite site, Shell parent) {
		super(site);
		setText(RENAME);
		shell = parent;
	}

	public J2EERenameAction(IWorkbenchSite site, ISelectionProvider newProvider) {
		super(site);
		setText(RENAME);
		shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell();
		provider = newProvider;
	}

	protected void reset() {
		if (renameModuleOperation != null) {
			renameModuleOperation.release();
			renameModuleOperation = null;
		}
		referencedProjects = null;
		projects = null;
		options = null;
	}

	/**
	 * @see SelectionListenerAction#updateSelection(IStructuredSelection)
	 */
	protected void updateSelection(IStructuredSelection selection) {
		super.update(selection);
	}

	/**
	 * @see SelectionDispatchAction#selectionChanged(ISelection)
	 */
	public void selectionChanged(ISelection selection) {
		if (selection instanceof IStructuredSelection)
			setEnabledFromSelection((IStructuredSelection) selection);
		else
			super.selectionChanged(selection);
	}

	protected void setEnabledFromSelection(IStructuredSelection selection) {
		if (selection == null) {
			setEnabled(false);
		} else {
			if (selection.toList().size() != 1) {
				setEnabled(false);
			} else {
				setEnabled(getEnableStateBasedOnSelection(selection));
			}
		}
	}

	protected boolean getEnableStateBasedOnSelection(IStructuredSelection selection) {
		if (selection.isEmpty())
			return false;
		return isSelectionAllDDRoots() || isSelectionAllApplications();
	}

	protected boolean isSelectionAllDDRoots() {
		IStructuredSelection sel = (StructuredSelection) getSelection();
		Iterator it = sel.iterator();
		while (it.hasNext()) {
			Object o = it.next();
			if (!CommonUtil.isDeploymentDescriptorRoot(o, false) && !isJ2EEProject(o))
				return false;
		}
		return true;
	}

	protected boolean isSelectionAllApplications() {
		IStructuredSelection sel = (StructuredSelection) getSelection();
		Iterator it = sel.iterator();
		while (it.hasNext()) {
			Object o = it.next();
			if (!(o instanceof Application) && !isJ2EEApplicationProject(o))
				return false;
		}
		return true;
	}


	protected List getProjects() {
		if (projects == null) {
			projects = new ArrayList();
			IStructuredSelection sel = (StructuredSelection) getSelection();
			Iterator iterator = sel.iterator();
			IProject project = null;
			Object o = null;
			while (iterator.hasNext()) {
				o = iterator.next();
				if (o instanceof JavaProject) {
					o = ((JavaProject) o).getProject();
				}
				if (o instanceof IProject) {
					projects.add(o);
				} else if (o instanceof EObject) {
					EObject obj = (EObject) o;
					project = ProjectUtilities.getProject(obj);
					if (project == null)
						throw new RuntimeException(J2EEUIMessages.getResourceString("Project_should_not_be_null_1_ERROR_")); //$NON-NLS-1$
					projects.add(project);
				} else {
					throw new RuntimeException(J2EEUIMessages.getResourceString("Non-project_in_selection_2_ERROR_")); //$NON-NLS-1$
				}
			}
		}
		return projects;
	}

	/**
	 * @see IAction#run()
	 */
	public void run() {
		try {
			List localProjects = getProjects();
			if (localProjects.size() != 1)
				return;
			IProject project = (IProject) localProjects.get(0);
			J2EERenameDialog dlg = null;

			// if all we are doing is renaming an EAR, let the base platform do it
			if (isSelectionAllApplications()) {
				RenameResourceAction action = new RenameResourceAction(shell);
				action.selectionChanged(new StructuredSelection(project));
				action.run();
			} else {
				String contextRoot = null;
				try {
					if (project.hasNature(IWebNatureConstants.J2EE_NATURE_ID)) {
						contextRoot = J2EEWebNatureRuntime.getRuntime(project).getContextRoot();
					}
				} catch (Throwable t) {
					contextRoot = null;
				}
				dlg = new RenameModuleDialog(shell, project.getName(), contextRoot);
				dlg.open();
				if (dlg.getReturnCode() == Window.CANCEL)
					return;

				options = dlg.getRenameOptions();
				if (options != null)
					options.setSelectedProjects(localProjects);

				if (!(ensureEditorsSaved() && validateState()))
					return;
				renameProjectsIfNecessary();
				renameMetadataIfNecessary();
				presentStatusIfNeccessary();
			}
		} finally {
			reset();
		}
	}


	private boolean ensureEditorsSaved() {
		return CommonEditorUtility.promptToSaveAllDirtyEditors();
	}

	protected Set getReferencedProjects() {
		if (referencedProjects == null)
			computeReferencedProjects();
		return referencedProjects;
	}

	protected void computeReferencedProjects() {
		getProjects();
		referencedProjects = new HashSet();
		for (int i = 0; i < projects.size(); i++) {
			IProject project = (IProject) projects.get(i);
			EARNatureRuntime runtime = EARNatureRuntime.getRuntime(project);
			if (runtime == null)
				continue;
			EAREditModel editModel = runtime.getEarEditModelForRead(this);
			try {
				referencedProjects.addAll(editModel.getModuleMappedProjects());
			} finally {
				editModel.releaseAccess(this);
			}
		}
	}

	protected void renameMetadataIfNecessary() {
		if (!shouldRenameMetaData())
			return;
		RenameModuleOperation op = getRenameModuleOperation();
		IRunnableWithProgress runnable = WTPUIPlugin.getRunnableWithProgress(op);
		ProgressMonitorDialog monitorDialog = new ProgressMonitorDialog(shell);

		try {
			monitorDialog.run(false, false, runnable);
		} catch (InvocationTargetException e) {
			handleException(e);
		} catch (InterruptedException e) {
			//Ignore
		}
	}

	protected boolean shouldRenameMetaData() {
		if (renameProjectsFailedOrCancelled())
			return false;

		return primShouldRenameMetaData();
	}

	protected boolean renameProjectsFailedOrCancelled() {
		if (options == null || !options.shouldRenameProjects())
			return false;
		return renamedProjectsExist();
	}

	protected boolean renamedProjectsExist() {
		List renamedProjects = options.getAllProjectsToRename();
		for (int i = 0; i < renamedProjects.size(); i++) {
			IProject project = (IProject) renamedProjects.get(i);
			if (project.exists())
				return true;
		}
		return false;
	}

	protected void renameProjectsIfNecessary() {
		if (options == null || !options.shouldRenameProjects())
			return;
		J2EERenameResourceAction action = new J2EERenameResourceAction(shell);
		action.setNewName(options.getNewName());
		IStructuredSelection sel = new StructuredSelection(options.getAllProjectsToRename());
		action.selectionChanged(sel);
		action.run();

		// only web projects should have a context root
		String newContextRoot = options.getNewContextRoot();
		if (newContextRoot != null && options.shouldRenameProjects()) {
			IProject project = (IProject) getProjects().get(0);
			try {
				IProject newProject = project.getWorkspace().getRoot().getProject(options.getNewName());
				J2EEWebNatureRuntime runtime = J2EEWebNatureRuntime.getRuntime(newProject);
				if (runtime != null)
					runtime.setContextRoot(newContextRoot);
			} catch (Throwable t) {
				//Ignore
			}
		}
	}

	public void handleException(InvocationTargetException e) {
		Logger.getLogger().logError(e);
		IStatus status = J2EEPlugin.newErrorStatus(IStatus.ERROR, RENAME_ERROR, e);
		ErrorDialog.openError(shell, RENAME_ERROR, RENAME_NOT_COMPLETED, status);
	}

	/**
	 * Update the action's enable state according to the current selection of the used selection
	 * provider.
	 */
	public void update() {
		IStructuredSelection selection = null;

		if (provider != null) {
			selection = (IStructuredSelection) provider.getSelection();
			super.update(selection);
		} else {
			selection = (IStructuredSelection) getSelection();

			if (selection == null) {
				setEnabled(false);
			} else {
				updateSelection(selection);
			}
		}
	}

	protected boolean isJ2EEProject(Object o) {
		boolean retVal = false;
		if (o instanceof JavaProject) {
			o = ((JavaProject) o).getProject();
		}
		if (o instanceof IProject) {
			IProject project = (IProject) o;
			try {
				if (EJBNatureRuntime.hasRuntime(project)) {
					retVal = true;
				} else if (project.hasNature(IWebNatureConstants.J2EE_NATURE_ID)) {
					retVal = true;
				} else if (ApplicationClientNatureRuntime.hasRuntime(project)) {
					retVal = true;
				} else if (ConnectorNatureRuntime.hasRuntime(project)) {
					retVal = true;
				}
			} catch (Throwable t) {
				retVal = false;
			}
		}
		return retVal;
	}

	protected boolean isJ2EEApplicationProject(Object o) {
		boolean retVal = false;
		if (o instanceof IProject) {
			IProject project = (IProject) o;
			try {
				if (EARNatureRuntime.hasRuntime(project)) {
					retVal = true;
				}
			} catch (Throwable t) {
				retVal = false;
			}
		}
		return retVal;
	}

	protected boolean validateState() {
		if (!primShouldRenameMetaData())
			return true;

		IValidateEditListener listener = new ValidateEditListener(null, getRenameModuleOperation().getRenameEditModel());
		listener.setShell(shell);
		return listener.validateState().isOK();
	}

	protected boolean primShouldRenameMetaData() {
		return options != null && (options.shouldRenameModules() || options.shouldRenameModuleDependencies());
	}

	protected RenameModuleOperation getRenameModuleOperation() {
		if (renameModuleOperation == null) {
			renameModuleOperation = new RenameModuleOperation(options);
		}
		return renameModuleOperation;
	}

	protected void presentStatusIfNeccessary() {
		IStatus status = null;

		if (renameModuleOperation != null) {
			status = renameModuleOperation.getStatus();
		}

		if (status == null || status.isOK())
			return;

		ErrorDialog.openError(shell, null, null, status, IStatus.ERROR);
	}
}