/*******************************************************************************
 * Copyright (c) 2005, 2007 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.ejb.archiveoperations;

import java.lang.reflect.InvocationTargetException;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.List;

import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.internal.resources.ResourceException;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceVisitor;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.SubProgressMonitor;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jem.util.emf.workbench.ProjectUtilities;
import org.eclipse.jem.workbench.utility.JemProjectUtilities;
import org.eclipse.jst.j2ee.application.internal.operations.UpdateManifestOperation;
import org.eclipse.jst.j2ee.commonarchivecore.internal.helpers.ArchiveManifest;
import org.eclipse.jst.j2ee.ejb.internal.plugin.EjbPlugin;
import org.eclipse.jst.j2ee.internal.J2EEConstants;
import org.eclipse.jst.j2ee.internal.ejb.project.operations.ClientJARCreationConstants;
import org.eclipse.jst.j2ee.internal.plugin.IJ2EEModuleConstants;
import org.eclipse.jst.j2ee.internal.plugin.LibCopyBuilder;
import org.eclipse.jst.j2ee.internal.project.J2EEProjectUtilities;
import org.eclipse.jst.j2ee.model.IModelProvider;
import org.eclipse.jst.j2ee.model.ModelProviderManager;
import org.eclipse.jst.j2ee.project.EarUtilities;
import org.eclipse.wst.common.componentcore.ComponentCore;
import org.eclipse.wst.common.componentcore.datamodel.properties.ICreateReferenceComponentsDataModelProperties;
import org.eclipse.wst.common.componentcore.internal.operation.RemoveReferenceComponentsDataModelProvider;
import org.eclipse.wst.common.componentcore.internal.util.IModuleConstants;
import org.eclipse.wst.common.componentcore.resources.IVirtualComponent;
import org.eclipse.wst.common.frameworks.datamodel.AbstractDataModelOperation;
import org.eclipse.wst.common.frameworks.datamodel.DataModelFactory;
import org.eclipse.wst.common.frameworks.datamodel.IDataModel;
import org.eclipse.wst.common.frameworks.internal.operations.IOperationHandler;


/**
 * @author schacher
 * 
 * To change the template for this generated type comment go to Window - Preferences - Java - Code
 * Generation - Code and Comments
 */
public class EJBClientJARRemovalOperation extends AbstractDataModelOperation 
 implements IEjbClientProjectRemovalDataModelProperties{

	protected IProject ejbProject;
	
	protected IProject clientProject;
	
	protected IPath clientProjectPath, ejbProjectPath;

	protected List sourceContainers, libraryContainers;

	protected IContainer ejbSourceContainer;

	protected IPath ejbSourcePath;

	protected IPath outputPath;

	protected boolean shouldDelete;

	protected boolean yesToAll = false;
	
	protected IWorkspace workspace;
	
	protected IProgressMonitor monitor;
	
	protected IProgressMonitor moveResourceMonitor;
	
	protected IOperationHandler operationHandler;

	public EJBClientJARRemovalOperation(IDataModel dataModel) {
		super(dataModel);
		shouldDelete = true;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jst.j2ee.internal.internal.ejb.clientjarcreation.AbstractEJBClientJAROperation#initialize()
	 */
	protected void initialize() {
//		super.initialize();
		ejbProject = (IProject) model.getProperty( IEjbClientProjectRemovalDataModelProperties.EJB_PROJECT );
		clientProject = (IProject) model.getProperty( IEjbClientProjectRemovalDataModelProperties.EJB_CLIENT_VIEW_PROJECT );
		operationHandler = (IOperationHandler)model.getProperty( IEjbClientProjectRemovalDataModelProperties.OP_HANDLER );
		
		workspace = ejbProject.getWorkspace();
		clientProjectPath = clientProject.getFullPath();
		ejbProjectPath = ejbProject.getFullPath();
		sourceContainers = JemProjectUtilities.getSourceContainers(clientProject);
		libraryContainers = JemProjectUtilities.getLibraryContainers(clientProject);
		IJavaProject proj = JavaCore.create(clientProject);
		try {
			outputPath = proj.getOutputLocation().removeFirstSegments(1);
		} catch (JavaModelException e) {
			//Ignore
		}

		IContainer container = J2EEProjectUtilities.getSourceFolderOrFirst( ejbProject, null );
		if( container.getType() == IResource.FOLDER ){
			ejbSourceContainer = container;
		}

		ejbSourcePath = ejbSourceContainer.getFullPath();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jst.j2ee.internal.internal.ejb.clientjarcreation.AbstractEJBClientJAROperation#addAdditionalFilesForValidateEdit(java.util.List)
	 */
	protected void addAdditionalFilesForValidateEdit(final List roFiles) throws CoreException {
		IResourceVisitor visitor = new IResourceVisitor() {
			public boolean visit(IResource resource) throws CoreException {
				if (resource.isDerived())
					return false;
				switch (resource.getType()) {
					case IResource.PROJECT :
						return true;
					case IResource.FOLDER :
						return true;
					case IResource.FILE :
						if (resource.isReadOnly())
							roFiles.add(resource);
						break;
					default :
						break;
				}
				return false;
			}
		};

		clientProject.accept(visitor);
	}


	
	@Override
	public IStatus execute(IProgressMonitor aMonitor, IAdaptable info) throws ExecutionException {
		monitor = aMonitor;
		initialize();
		try{
			if (!verifyFilesInSync()) {
				monitor.done();
				throw new OperationCanceledException();
			}
			monitor.beginTask(ClientJARCreationConstants.REMOVING_CLIENT_JAR, 10);
			//It would be nice to only make one pass through the EARs. However, we can't.
			//The reason is that both JARs must be in the EAR when moving JAR dependencies.
			//Then when we are done we can remove the client JARs from the EARs.
			ensureEJBJARInAllEARs();
			updateEJBModuleJARDependencies();
			EJBClientJarCreationHelper.copyOutgoingClasspathEntries(clientProject, ejbProject, false);
			moveIncomingJARDependencies();
			updateDD();
			removeClientProjectFromEARs();
			moveFiles();
			// add all the source containers to the class path
			// add the root to the class path
			addSourceContainersToClassPath();
			//
			if (moveResourceMonitor.isCanceled())
				throw new InterruptedException();
			deleteClientProject();
		}catch(CoreException e){
			EjbPlugin.logError( e );
		}catch(InvocationTargetException e){
			EjbPlugin.logError( e );
		}catch(InterruptedException e){
			EjbPlugin.logError( e );
		}

		return OK_STATUS;
	}


	/**
	 * @throws JavaModelException
	 *  
	 */
	private void addSourceContainersToClassPath() throws JavaModelException {
		for (int x = 0; x < sourceContainers.size(); ++x) {
			if (sourceContainers.get(x) instanceof IResource) {
				IResource resource = (IResource) sourceContainers.get(x);
				if (clientProject == resource)
					return;
				IPath srcPath = ejbProjectPath.append(resource.getProjectRelativePath());
				IFolder existing = workspace.getRoot().getFolder(srcPath);
				if (existing != null && existing.exists())
					JemProjectUtilities.appendJavaClassPath(ejbProject, JavaCore.newSourceEntry(srcPath));
			}
		}
	}

	/*
	 * Remove the client JAR entry from the deployment descriptor
	 */
	private void updateDD() {
		IModelProvider ejbModel = ModelProviderManager.getModelProvider(ejbProject);
        ejbModel.modify(new Runnable() {
            public void run() {
                IModelProvider writableEjbModel = ModelProviderManager.getModelProvider(ejbProject);
                Object modelObject = writableEjbModel.getModelObject();
                
                if (modelObject instanceof org.eclipse.jst.javaee.ejb.EJBJar) {
                    org.eclipse.jst.javaee.ejb.EJBJar ejbres = (org.eclipse.jst.javaee.ejb.EJBJar) writableEjbModel.getModelObject();
                    if (ejbres != null)
                    	ejbres.setEjbClientJar(null);
                }
                else {
                    org.eclipse.jst.j2ee.ejb.EJBJar ejbres = (org.eclipse.jst.j2ee.ejb.EJBJar) writableEjbModel.getModelObject();
                    ejbres.setEjbClientJar(null);
                }
            }
        },null);
	}

	/*
	 * In cross EAR references, it is possible the EJB module is not included in the referencing
	 * EAR. If so, then we must add the EJB module as a utility JAR to the referencing EAR.
	 */
	private void ensureEJBJARInAllEARs() {
		//TODO switch to use component API
//		for (int i = 0; i < earNatures.length; i++) {
//			ensureEJBJARInEAR(earNatures[i]);
//		}
	}

	//TODO fix up ensure method to use component API
//	private void ensureEJBJARInEAR(EARNatureRuntime runtime) {
//		String ejbURI = runtime.getJARUri(ejbProject);
//		if (ejbURI != null)
//			return;
//		ejbURI = J2EEProjectUtilities.getUtilityJARUriInFirstEAR(ejbProject);
//		EAREditModel model = null;
//		try {
//			model = runtime.getEarEditModelForWrite(this);
//			AddUtilityJARMapCommand cmd = new AddUtilityJARMapCommand(model, ejbURI, ejbProject);
//			model.getCommandStack().execute(cmd);
//			IProgressMonitor subMonitor = createSubProgressMonitor(1);
//			model.saveIfNecessary(subMonitor, this);
//		} finally {
//			if (model != null)
//				model.releaseAccess(this);
//		}
//	}

	/*
	 * copy all JAR dependencies not already contained by the ejb module,
	 * from the client JAR to the ejb module,
	 * and remove the module dependency from the EJB module
	 */
	private void updateEJBModuleJARDependencies() throws InvocationTargetException, InterruptedException {

		
		ArrayList list = new ArrayList();
		list.add(clientProject.getName() + IJ2EEModuleConstants.JAR_EXT);
		
		IProject[] earProjects = EarUtilities.getReferencingEARProjects( ejbProject );
		if (earProjects != null && earProjects.length > 0)
		{
			UpdateManifestOperation removeOp = new EJBClientManifestUtility().getRemoveOperation(ejbProject, earProjects[0], list, clientProject);
			
			try {
				removeOp.execute( createSubProgressMonitor(1), null);
			} catch (ExecutionException e) {
				EjbPlugin.logError( e );
			}
			
			ArchiveManifest clientMf = J2EEProjectUtilities.readManifest(clientProject);
			if (clientMf == null)
				return;
			String[] mfEntries = clientMf.getClassPathTokenized();
			if (mfEntries.length == 0)
				return;
			
			createSubProgressMonitor( earProjects.length );
			
			//copy all JAR dependencies not already contained by the ejb module,
			//from the client JAR to the ejb module	
	
			for (int i = 0; i < earProjects.length; i++) {
				List result = EJBClientJarCreationHelper.normalize(mfEntries, earProjects[i], ejbProject, false);
				UpdateManifestOperation addOp = new EJBClientManifestUtility().getAddOperation(ejbProject, earProjects[0], result);
				
				try{
					addOp.execute( createSubProgressMonitor(1), null );
				}catch (ExecutionException e) {
					EjbPlugin.logError( e );
				}
			}
		}
	}

	/*
	 * For each module or JAR in each EAR that references the client JAR, replace the dependency
	 * from the client JAR to the EJB module
	 */
	private void moveIncomingJARDependencies() throws InvocationTargetException, InterruptedException {
		
		IProject[] earProjects = EarUtilities.getReferencingEARProjects( ejbProject );
		if (earProjects != null && earProjects.length > 0)
		{
			InvertClientJARDependencyCompoundOperation op = 
				new InvertClientJARDependencyCompoundOperation( earProjects,
							clientProject,
							ejbProject );
			try {
				op.execute(createSubProgressMonitor(1), null);
			} catch (ExecutionException e) {
				EjbPlugin.logError( e );
			}
		}
	}

	/*
	 * move all the non-derived files from the client JAR project into the EJB project. Use an
	 * overwrite handler to deal with collisions.
	 */
	private void moveFiles() throws CoreException {
		moveResourceMonitor = createSubProgressMonitor(1);
		IResourceVisitor visitor = getRootResourceVisitor();
		clientProject.accept(visitor);
	}

	private IResourceVisitor getRootResourceVisitor() {

		return new IResourceVisitor() {
			private boolean projectIsSource = sourceContainers.contains(clientProject);

			public boolean visit(IResource resource) throws CoreException {
				if (moveResourceMonitor.isCanceled())
					return false;
				switch (resource.getType()) {
					case IResource.FILE :
						if (!resource.isDerived())
							visitFile((IFile) resource);
						return false;
					case IResource.FOLDER :
						return visitFolder((IFolder) resource);
					case IResource.PROJECT :
						return true;
					default :
						return false;
				}
			}

			private void visitFile(IFile file) throws CoreException {
				if (isMetaFile(file))
					return;
				else if (projectIsSource)
					moveFile(file, clientProjectPath, ejbSourcePath);
				else
					moveFile(file, clientProjectPath, ejbProjectPath);

			}

			private boolean isMetaFile(IFile file) {
				String segment = file.getProjectRelativePath().toString();
				return ProjectUtilities.DOT_CLASSPATH.equals(segment) ||
						ProjectUtilities.DOT_PROJECT.equals(segment) ||
						segment.endsWith(IModuleConstants.COMPONENT_FILE_NAME) ||
						segment.startsWith(".settings"); //$NON-NLS-1$ 
			}

			private boolean visitFolder(IFolder folder) throws CoreException {
				if (isSourceFolder(folder)) {
					visitSourceFolder(folder);
					return false;
				} else if (isOutputFolder(folder)) {
					return false;
				} else if (isClassesFolder(folder)) {
					visitClassesFolder(folder);
					return false;
				} else
					return true;
			}

			private boolean isOutputFolder(IFolder folder) {
				IPath path = folder.getProjectRelativePath();
				while (path.segmentCount() > 0 && null != outputPath) {
					if (path.equals(outputPath)) {
						return true;
					}
					path = path.removeLastSegments(1);
				}
				return false;
			}

			private boolean isSourceFolder(IFolder folder) {
				return sourceContainers.contains(folder);
			}

			private void visitSourceFolder(IFolder folder) throws CoreException {
				folder.accept(getFolderResourceVisitor(folder.getFullPath(), computeEJBSourceFolder(folder)));
			}

			private IPath computeEJBSourceFolder(IFolder clientProjectFolder) {
				IPath clientFolderRelativePath = clientProjectFolder.getProjectRelativePath();
				return ejbProjectPath.append(clientFolderRelativePath);
			}

			private boolean isClassesFolder(IFolder folder) {
				return libraryContainers.contains(folder);
			}

			protected void visitClassesFolder(IFolder folder) throws CoreException {
				IPath classesPath = getEJBClassesPath();
				folder.accept(getFolderResourceVisitor(folder.getFullPath(), classesPath));
			}

			private IPath getEJBClassesPath() throws CoreException {
				IFolder folder = ejbProject.getFolder(LibCopyBuilder.IMPORTED_CLASSES_PATH);
				if (!folder.exists())
					folder.create(true, true, null);
				JemProjectUtilities.appendJavaClassPath(ejbProject, JavaCore.newLibraryEntry(folder.getFullPath(), null, null, true));
				return folder.getFullPath();
			}
		};
	}

	private IResourceVisitor getFolderResourceVisitor(final IPath sourceRoot, final IPath destinationRoot) {
		return new IResourceVisitor() {
			public boolean visit(IResource resource) throws CoreException {
				if (moveResourceMonitor.isCanceled())
					return false;
				switch (resource.getType()) {
					case IResource.FILE :
						if (!resource.isDerived() && !isManifest(sourceRoot, resource.getFullPath()))
							moveFile((IFile) resource, sourceRoot, destinationRoot);
						return false;
					case IResource.FOLDER :
						return true;
					default :
						return false;
				}
			}

			private boolean isManifest(IPath new_sourceRoot, IPath path) {
				String relativeURI = path.removeFirstSegments(new_sourceRoot.segmentCount()).toString();
				return J2EEConstants.MANIFEST_URI.equals(relativeURI);
			}
		};
	}

	private void moveFile(IFile file, IPath sourceRoot, IPath destinationRoot) throws CoreException {
		IPath filePath = file.getFullPath();
		IPath relativeFilePath = filePath.removeFirstSegments(sourceRoot.segmentCount());
		IPath newPath = destinationRoot.append(relativeFilePath);
		mkdirs(newPath, workspace.getRoot());
		IFile existing = workspace.getRoot().getFile(newPath);
		if (!yesToAll && existing.exists()) {
			String message = MessageFormat.format(ClientJARCreationConstants.SHOULD_OVERWRITE, new Object[]{filePath.toString(), newPath.toString()});
			int answer = IOperationHandler.YES_TO_ALL;
			if (operationHandler != null)
				answer = operationHandler.canContinueWithAllCheckAllowCancel(message);
			switch (answer) {
				case IOperationHandler.YES :
					break;
				case IOperationHandler.YES_TO_ALL :
					yesToAll = true;
					break;
				case IOperationHandler.NO :
					return;
				case IOperationHandler.CANCEL :
					moveResourceMonitor.setCanceled(true);
					return;
				default :
					break;
			}
		}
		if (!existing.exists())
			file.move(newPath, true, moveResourceMonitor);
		else
			existing.setContents(file.getContents(), true, true, moveResourceMonitor);
	}


	private void removeClientProjectFromEARs() {

		IProject[] earProjects = EarUtilities.getReferencingEARProjects( clientProject );
		for (int i = 0; i < earProjects.length; i++) {
			removeClientProjectFromEAR( earProjects[i] );
		}
	}


	private void removeClientProjectFromEAR( IProject earProject ) {
		
		IVirtualComponent earComp = ComponentCore.createComponent(earProject);
		IVirtualComponent component = ComponentCore.createComponent(clientProject);

		if (earComp.exists() && component.exists()) {
			IDataModel dm = DataModelFactory.createDataModel(new RemoveReferenceComponentsDataModelProvider());
			dm.setProperty(ICreateReferenceComponentsDataModelProperties.SOURCE_COMPONENT, earComp);

			List modList = (List) dm.getProperty(ICreateReferenceComponentsDataModelProperties.TARGET_COMPONENT_LIST);
			modList.add(component);
			dm.setProperty(ICreateReferenceComponentsDataModelProperties.TARGET_COMPONENT_LIST, modList);
			try {
				dm.getDefaultOperation().execute(monitor, null);
			} catch (ExecutionException e) {
				EjbPlugin.logError(e);
			}
		}
		
	}

	/*
	 * remove the client project from the workspace
	 */
	private void deleteClientProject() throws CoreException {
		if (shouldDelete)
			try{
				clientProject.delete(true, true, createSubProgressMonitor(1));
			}catch(ResourceException e){
				clientProject.delete(false, true, createSubProgressMonitor(1));
			}
	}

	protected IProgressMonitor createSubProgressMonitor(int ticks) {
		return new SubProgressMonitor(monitor, ticks);
	}
	
	protected boolean verifyFilesInSync() throws CoreException {
		if (verifyFilesInSync(ejbProject))
			return verifyFilesInSync(clientProject);
		return false;
	}
	
	protected boolean verifyFilesInSync(IProject project) throws CoreException {
		if (!project.exists())
			return true;
		if (!project.isSynchronized(IResource.DEPTH_INFINITE)) {
			String message = MessageFormat.format(ClientJARCreationConstants.FILES_OUT_OF_SYNC, new Object[]{project.getName()});
			if (operationHandler == null || operationHandler.canContinue(message)) 
				ejbProject.refreshLocal(IResource.DEPTH_INFINITE, createSubProgressMonitor(1));
			else 
				return false;
		}
		return true;
	}	
	
	protected void mkdirs(IPath newPath, IWorkspaceRoot root) throws CoreException {
		if (newPath.segmentCount() <= 2)
			return;
		IPath parentPath = newPath.removeLastSegments(1);
		IFolder folder = root.getFolder(parentPath);
		if (!folder.exists()) {
			mkdirs(parentPath, root);
			folder.create(true, true, null);
		}
	}	
}
