/*******************************************************************************
 * Copyright (c) 2008, 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.jst.javaee.ltk.core.change;

import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import java.util.concurrent.ExecutionException;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.Path;
import org.eclipse.jem.util.emf.workbench.ProjectUtilities;
import org.eclipse.jst.j2ee.application.internal.operations.UpdateManifestDataModelProperties;
import org.eclipse.jst.j2ee.application.internal.operations.UpdateManifestDataModelProvider;
import org.eclipse.jst.j2ee.commonarchivecore.internal.helpers.ArchiveManifest;
import org.eclipse.jst.j2ee.internal.J2EEConstants;
import org.eclipse.jst.j2ee.internal.common.CreationConstants;
import org.eclipse.jst.j2ee.internal.plugin.IJ2EEModuleConstants;
import org.eclipse.jst.j2ee.internal.plugin.J2EEPlugin;
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.JavaEEProjectUtilities;
import org.eclipse.jst.javaee.ltk.core.nls.RefactoringResourceHandler;
import org.eclipse.ltk.core.refactoring.Change;
import org.eclipse.ltk.core.refactoring.ChangeDescriptor;
import org.eclipse.ltk.core.refactoring.RefactoringStatus;
import org.eclipse.osgi.util.NLS;
import org.eclipse.wst.common.componentcore.ComponentCore;
import org.eclipse.wst.common.componentcore.internal.resources.VirtualComponent;
import org.eclipse.wst.common.componentcore.resources.IVirtualComponent;
import org.eclipse.wst.common.componentcore.resources.IVirtualFile;
import org.eclipse.wst.common.componentcore.resources.IVirtualReference;
import org.eclipse.wst.common.frameworks.datamodel.DataModelFactory;
import org.eclipse.wst.common.frameworks.datamodel.IDataModel;


public class NonEARModuleReferenceRemoveChange extends Change {

	
	public NonEARModuleReferenceRemoveChange(IProject referencingEARProject, IProject projectToRemove) {
		super();
		this.referencingModuleProject = referencingEARProject;
		this.projectToRemove = projectToRemove;
		this.referencingModuleProjectComp = (VirtualComponent)ComponentCore.createComponent(referencingEARProject);
		cachedRefs = referencingModuleProjectComp.getReferences();
		this.projectToRemoveComp = ComponentCore.createComponent(projectToRemove);
	}
	
	IProject referencingModuleProject = null;
	VirtualComponent referencingModuleProjectComp = null;
	IProject projectToRemove = null;
	IVirtualComponent projectToRemoveComp = null;
	IVirtualReference[] cachedRefs = null;
	@Override
	public Object getModifiedElement() {
		return null;
	}

	@Override
	public String getName() {
		
		String name = NLS.bind(
				RefactoringResourceHandler.Remove_JavaEE_References,
				new Object[] {projectToRemove.getName()});
		
		name += referencingModuleProject.getName();
		return name;
		
	}

	@Override
	public void initializeValidationData(IProgressMonitor pm) {
	
	}

	@Override
	public RefactoringStatus isValid(IProgressMonitor pm) throws CoreException,
			OperationCanceledException {
		return null;
	}

	@Override
	public Change perform(IProgressMonitor pm) throws CoreException {
		
		try {
			removeModuleDependency();
			if(isEJBClientDeletion()){
				updateEJBDDWithEJBClientDeletion();
			}
		} catch (ExecutionException e) {
			J2EEPlugin.logError(e);
		}
		return null;
	}
	
	@Override
	public ChangeDescriptor getDescriptor() {
		return null;
	}
	
	private boolean isEJBClientDeletion(){
		
		if(!JavaEEProjectUtilities.isEJBProject(referencingModuleProject))
			return false;
		Properties props = referencingModuleProjectComp.getMetaProperties();
		String clientCompName = props.getProperty(CreationConstants.EJB_CLIENT_NAME);
		if(clientCompName == null || clientCompName.length() == 0){
			return false;
		}
			
		 if(clientCompName.equals(projectToRemove.getName())){
			 return true;
		 }
	        return false;
	}
	
	
	/*
	 * Remove the client JAR entry from the deployment descriptor
	 * This method is to be used only to remove EJB Client jar entry from
	 * EJB DD
	 */
	private void updateEJBDDWithEJBClientDeletion() {
		IModelProvider ejbModel = ModelProviderManager.getModelProvider(referencingModuleProject);
        ejbModel.modify(new Runnable() {
            public void run() {
                IModelProvider writableEjbModel = ModelProviderManager.getModelProvider(referencingModuleProject);
                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);
                }
            	Properties props = referencingModuleProjectComp.getMetaProperties();
            	props.remove(CreationConstants.CLIENT_JAR_URI);
            	props.remove(CreationConstants.EJB_CLIENT_NAME);
            	referencingModuleProjectComp.clearMetaProperties();
            	referencingModuleProjectComp.setMetaProperties(props);
         		
            }
        },null);
	}

	
	
	protected void removeModuleDependency() throws ExecutionException {
		
		// create IVirtualComponents for the dependent and the refactored project
		final IVirtualComponent refactoredComp = projectToRemoveComp;
		final IProgressMonitor monitor = new NullProgressMonitor();
		// Does the dependent project have a .component reference on the refactored project?
		
		// remove the component reference on the deleted project
		if (refactoredComp != null) {
			removeReferencedComponents(monitor);
		}
		
		// update the manifest
			updateManifestDependency(true);
	}
	
	
	protected void updateManifestDependency(final boolean remove) throws ExecutionException {
		final IVirtualComponent dependentComp = referencingModuleProjectComp;
		IProject project= dependentComp.getProject();
		if(project.isAccessible()){
			final String dependentProjName = referencingModuleProject.getName();
			final String refactoredProjName = projectToRemove.getName();
			final IVirtualFile vf = dependentComp.getRootFolder().getFile(new Path(J2EEConstants.MANIFEST_URI) );
			final IFile manifestmf = vf.getUnderlyingFile();
			// adding this check for https://bugs.eclipse.org/bugs/show_bug.cgi?id=170074
			// (some adopters have non-jst.ear module projects that are missing manifests)
			if (!manifestmf.exists()) {  
				return;
			}
			final IProgressMonitor monitor = new NullProgressMonitor();
			final IDataModel updateManifestDataModel = DataModelFactory.createDataModel(new UpdateManifestDataModelProvider());
			updateManifestDataModel.setProperty(UpdateManifestDataModelProperties.PROJECT_NAME, dependentProjName);
			updateManifestDataModel.setBooleanProperty(UpdateManifestDataModelProperties.MERGE, false);
			updateManifestDataModel.setProperty(UpdateManifestDataModelProperties.MANIFEST_FILE, manifestmf);
			final ArchiveManifest manifest = J2EEProjectUtilities.readManifest(manifestmf);
			String[] cp = manifest.getClassPathTokenized();
			List cpList = new ArrayList();
			String newjarCp = refactoredProjName + IJ2EEModuleConstants.JAR_EXT;
			String newrarCp = refactoredProjName + IJ2EEModuleConstants.RAR_EXT;
			for (int i = 0; i < cp.length; i++) {
				if (!cp[i].equals(newjarCp) && !cp[i].equals(newrarCp)) {
					cpList.add(cp[i]);
				}
			}
			
			updateManifestDataModel.setProperty(UpdateManifestDataModelProperties.JAR_LIST, cpList);
			try {
				updateManifestDataModel.getDefaultOperation().execute(monitor, null );
			} catch (org.eclipse.core.commands.ExecutionException e) {
				J2EEPlugin.logError(e);
			}
		}
	}
	
	protected void removeReferencedComponents(IProgressMonitor monitor) {
		
		if (referencingModuleProjectComp == null || !referencingModuleProjectComp.getProject().isAccessible() || referencingModuleProjectComp.isBinary()) return;
		
		IVirtualReference [] existingReferencesArray = cachedRefs;
		if(existingReferencesArray == null || existingReferencesArray.length == 0){
			return;
		}
		
		List existingReferences = new ArrayList();
		for(int i=0;i<existingReferencesArray.length; i++){
			existingReferences.add(existingReferencesArray[i]);
		}
		
		List targetprojectList = new ArrayList();
			if (projectToRemoveComp==null )
				return;

			IVirtualReference ref = findMatchingReference(existingReferences, projectToRemoveComp, null);
			//if a ref was found matching the specified deployPath, then remove it
			if(ref != null){
				removeRefereneceInComponent(referencingModuleProjectComp, ref);
				existingReferences.remove(ref);
				//after removing the ref, check to see if it was the last ref removed to that component
				//and if it was, then also remove the project reference
				ref = findMatchingReference(existingReferences, projectToRemoveComp);
				if(ref == null){
					IProject targetProject = projectToRemoveComp.getProject();
					targetprojectList.add(targetProject);
				}
			}
		
		
		try {
			ProjectUtilities.removeReferenceProjects(referencingModuleProjectComp.getProject(),targetprojectList);
		} catch (CoreException e) {
			J2EEPlugin.logError(e);
		}		
		
	}
	
	private IVirtualReference findMatchingReference(List existingReferences, IVirtualComponent comp) {
		return findMatchingReference(existingReferences, comp, null);
	}

	protected void removeRefereneceInComponent(IVirtualComponent component, IVirtualReference reference) {
		((VirtualComponent)component.getComponent()).removeReference(reference);
	}
	
	private IVirtualReference findMatchingReference(List existingReferences, IVirtualComponent comp, IPath path) {
		for(int i=0;i<existingReferences.size(); i++){
			IVirtualReference ref = (IVirtualReference)existingReferences.get(i);
			IVirtualComponent c = ref.getReferencedComponent();
			if(c != null && c.getName().equals(comp.getName())){
				if(path == null){
					return ref;
				} else if(path.equals(ref.getRuntimePath())){
					return ref;
				}
			}
		}
		return null;
	}
	
	
	/**
	 * Does the dependent project have a .component reference on the refactored project?
	 * @return IVirtualReference or null if one didn't exist.
	 */
	protected IVirtualReference hadReference() {
		final IVirtualComponent refactoredComp = projectToRemoveComp;
		if (refactoredComp == null) {
			return null;
		}
		final IVirtualReference[] refs = cachedRefs;
		IVirtualReference ref = null;
		for (int i = 0; i < refs.length; i++) {
			if (refs[i].getReferencedComponent().equals(refactoredComp)) {
				ref = refs[i];
				break;
			}
		}
		return ref;
	}
	
	/**
	 * Does the dependent project have a .project reference on the refactored project?
	 * (dynamic project refs don't count)
	 * @return True if a project reference exists.
	 */
	protected boolean hadProjectReference() {
		try {
			final IProject[] refs = referencingModuleProject.getDescription().getReferencedProjects();
			final IProject refactoredProject= projectToRemove;
			for (int i = 0; i < refs.length; i++) {
				if (refs[i].equals(refactoredProject)) {
					return true;
				}
			} 
		} catch (CoreException ce) {
			J2EEPlugin.logError(ce);
		}
		return false;
	}
	
	/**
	 * Returns true if the dependency was a web library dependency. 
	 * @param ref
	 * @return
	 */
	protected static boolean hasWebLibDependency(final IVirtualReference ref) {
		if (ref == null) {
			return false;
		}
		return ref.getRuntimePath().equals(new Path("/WEB-INF/lib")); //$NON-NLS-1$
	}

}
