/*******************************************************************************
 * Copyright (c) 2007 BEA Systems, Inc.
 * 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
 *******************************************************************************/
package org.eclipse.jst.j2ee.internal.classpathdep;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
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.Status;
import org.eclipse.jdt.core.IClasspathAttribute;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jem.util.emf.workbench.ProjectUtilities;
import org.eclipse.jst.common.jdt.internal.javalite.IJavaProjectLite;
import org.eclipse.jst.common.jdt.internal.javalite.JavaCoreLite;
import org.eclipse.jst.j2ee.classpathdep.ClasspathDependencyUtil;
import org.eclipse.jst.j2ee.classpathdep.UpdateClasspathAttributeUtil;
import org.eclipse.jst.j2ee.internal.plugin.J2EEPlugin;
import org.eclipse.jst.j2ee.project.JavaEEProjectUtilities;
import org.eclipse.wst.common.frameworks.datamodel.AbstractDataModelOperation;
import org.eclipse.wst.common.frameworks.datamodel.IDataModel;

/**
 * DataModelOperation that updates the WTP component dependency attribute on the
 * the classpath entries for the target Java project.
 */
public class UpdateClasspathAttributesOperation extends AbstractDataModelOperation implements UpdateClasspathAttributesDataModelProperties {

	public UpdateClasspathAttributesOperation(final IDataModel dataModel) {
		super(dataModel);
	}
	
	@Override
	public IStatus execute(final IProgressMonitor monitor, final IAdaptable info)
			throws ExecutionException {
		final IProject project = ProjectUtilities.getProject(model.getStringProperty(PROJECT_NAME));
		final boolean webLibsOnly = JavaEEProjectUtilities.isDynamicWebProject(project) && !ClasspathDependencyEnablement.isAllowClasspathComponentDependency();

		try {
			if (project.hasNature(JavaCore.NATURE_ID)) {
				final IJavaProject javaProject = JavaCore.create(project);
				validateEdit(project);
				final Map entriesToAdd = (Map) model.getProperty(ENTRIES_TO_ADD_ATTRIBUTE);
				final boolean modifyComponentDep = model.getBooleanProperty(MODIFY_CLASSPATH_COMPONENT_DEPENDENCY);
				if (entriesToAdd == null) {
					final Map entriesToRemove = (Map ) model.getProperty(ENTRIES_TO_REMOVE_ATTRIBUTE);
					if (entriesToRemove == null) {
						final Map entriesToRuntimePath = (Map) model.getProperty(ENTRIES_WITH_ATTRIBUTE);
						final Map entriesToAttrib = new HashMap();
						final Iterator i = entriesToRuntimePath.keySet().iterator();
						while (i.hasNext()) {
							IClasspathEntry entry = (IClasspathEntry) i.next();
							IPath runtimePath = (IPath) entriesToRuntimePath.get(entry);
							IClasspathAttribute attrib = ClasspathDependencyUtil.checkForComponentDependencyAttribute(entry, 
									modifyComponentDep ? DependencyAttributeType.CLASSPATH_COMPONENT_DEPENDENCY : DependencyAttributeType.CLASSPATH_COMPONENT_NONDEPENDENCY);
							if (attrib == null) {
								if (modifyComponentDep) {
									attrib = UpdateClasspathAttributeUtil.createDependencyAttribute(runtimePath);
								} else {
									attrib = UpdateClasspathAttributeUtil.createNonDependencyAttribute();
								}
							}
							entriesToAttrib.put(entry, attrib);
						}
						updateDependencyAttributes(javaProject, entriesToAttrib, modifyComponentDep, webLibsOnly); 
					} else {
						removeDependencyAttributes(javaProject, entriesToRemove, modifyComponentDep); 
					}
				} else {
					
					addDependencyAttributes(javaProject, entriesToAdd, modifyComponentDep); 
				}
			}
		} catch (CoreException ce) {
			J2EEPlugin.logError(ce);
			return new Status(IStatus.ERROR, J2EEPlugin.PLUGIN_ID, 0, ce.getLocalizedMessage(), ce);
		}
		return Status.OK_STATUS;
	}

	/**
	 * Performs a validateEdit call on the files impacted by the operation.
	 */
	protected void validateEdit(final IProject project) throws CoreException {
		final List affectedFiles = ProjectUtilities.getFilesAffectedByClasspathChange(project);
		final IFile[] files = (IFile[]) affectedFiles.toArray(new IFile[affectedFiles.size()]);
		final IStatus result = J2EEPlugin.getWorkspace().validateEdit(files, null);
		if (!result.isOK()) {
			throw new CoreException(result);
		}
	}
	
	/**
	 * Adds the WTP component dependency attribute to the specified classpath entries.
	 * @param javaProject Target Java project.
	 * @param entries Classpath entries to which the component dependency attribute should be added.
 	 * @param modifyComponentDep True if adding the dependency attribute, false if adding the non-dependency attribute.
	 * @throws CoreException Thrown if an error is encountered.
	 */	
	private void addDependencyAttributes(final IJavaProject javaProject, final Map entries, final boolean modifyComponentDep) throws CoreException {
		alterDependencyAttributes(javaProject, entries, true, modifyComponentDep);
	}
	
	/**
	 * Removes the WTP component dependency attribute from the specified classpath entries.
	 * @param javaProject Target Java project.
	 * @param entries Classpath entries from which the component dependency attribute should be removed.
	 * @param modifyComponentDep True if removing the dependency attribute, false if removing the non-dependency attribute.
	 * @throws CoreException Thrown if an error is encountered.
	 */	
	private void removeDependencyAttributes(final IJavaProject javaProject, final Map entries, final boolean modifyComponentDep) throws CoreException {
		alterDependencyAttributes(javaProject, entries, false, modifyComponentDep);
	}

	private void alterDependencyAttributes(final IJavaProject javaProject, final Map entries, final boolean add, final boolean modifyComponentDep) throws CoreException {
		final boolean isWebApp = JavaEEProjectUtilities.isDynamicWebProject(javaProject.getProject());
		final boolean webLibsOnly = isWebApp && !ClasspathDependencyEnablement.isAllowClasspathComponentDependency();
		final IJavaProjectLite javaProjectLite = JavaCoreLite.create(javaProject);
		
		// initialize to the set of raw entries with the attrib
		final Map entriesWithAttrib = ClasspathDependencyUtil.getRawComponentClasspathDependencies(javaProjectLite, modifyComponentDep ? DependencyAttributeType.CLASSPATH_COMPONENT_DEPENDENCY : DependencyAttributeType.CLASSPATH_COMPONENT_NONDEPENDENCY, webLibsOnly);
		
		Iterator i = entries.keySet().iterator();
		while (i.hasNext()) {
			final IClasspathEntry entry = (IClasspathEntry) i.next();
			if (add) {
				if (getMatchingEntryIgnoreAttributes(entriesWithAttrib, entry) == null) {
					IPath runtimePath = (IPath) entries.get(entry);
					if (runtimePath == null) {
						// compute the default runtime path
						runtimePath = ClasspathDependencyUtil.getDefaultRuntimePath(isWebApp, ClasspathDependencyUtil.isClassFolderEntry(entry));
					}
					IClasspathAttribute attrib = null;
					if (modifyComponentDep) {
						attrib = UpdateClasspathAttributeUtil.createDependencyAttribute(runtimePath);
					} else {
						attrib = UpdateClasspathAttributeUtil.createNonDependencyAttribute();
					}
 					entriesWithAttrib.put(entry, attrib);
				}
			} else {
				IClasspathEntry matching = getMatchingEntryIgnoreAttributes(entriesWithAttrib, entry);
				if (matching != null) {
					entriesWithAttrib.remove(matching);
				}
			}
		}
		updateDependencyAttributes(javaProject, entriesWithAttrib, modifyComponentDep, webLibsOnly);
	}
	
	private IClasspathEntry getMatchingEntryIgnoreAttributes(final Map entries, final IClasspathEntry entry) {
		final Iterator i = entries.keySet().iterator();
		while (i.hasNext()) {
			final IClasspathEntry e = (IClasspathEntry) i.next();
			if (e.getEntryKind() == entry.getEntryKind()
					&& e.getPath().equals(entry.getPath())
					&& e.isExported() == entry.isExported()) {
				return e;
			}
		}
		return null;

	}

	/**
	 * Updates the specified Java project so that only the specified classpath entries have
	 * the WTP component dependency attribute.
	 * @param javaProject Target Java project.
	 * @param entries Classpath entries that should have the component dependency attribute. Map from IClasspathEntry
	 * to the IClasspathAttribute for the WTP classpath component dependency.
	 * @param modifyComponentDep True if modifying the dependency attribute, false if modifying the non-dependency attribute.
	 * @throws CoreException Thrown if an error is encountered.
	 */	
	private void updateDependencyAttributes(final IJavaProject javaProject, final Map entriesWithAttrib, final boolean modifyComponentDep, final boolean webLibsOnly) throws CoreException {
		if (javaProject == null || !javaProject.getProject().isAccessible()) {
			return;
		}
		
		final List updatedClasspath = new ArrayList();
		final IClasspathEntry[] rawClasspath = javaProject.getRawClasspath();
		boolean needToUpdateClasspath = false;
		IClasspathAttribute attrib = UpdateClasspathAttributeUtil.createDependencyAttribute();
		if (!modifyComponentDep) {
			attrib = UpdateClasspathAttributeUtil.createNonDependencyAttribute();
		}
		for (int i = 0; i < rawClasspath.length; i++) {
			IClasspathEntry entry = rawClasspath[i];
			final int kind = entry.getEntryKind();
			boolean hasAttribute = ClasspathDependencyUtil.checkForComponentDependencyAttribute(entry, 
					modifyComponentDep ? DependencyAttributeType.CLASSPATH_COMPONENT_DEPENDENCY : DependencyAttributeType.CLASSPATH_COMPONENT_NONDEPENDENCY, webLibsOnly) != null;
			boolean shouldHaveAttribute = entriesWithAttrib.containsKey(entry);
			boolean updateAttributes = false;
			IClasspathAttribute[] updatedAttributes = null;
			if (shouldHaveAttribute) {
				if (!hasAttribute) {
					// should have the attribute and currently missing it
					attrib = (IClasspathAttribute) entriesWithAttrib.get(entry);
					updatedAttributes = updateAttributes(entry.getExtraAttributes(), attrib, true);
					needToUpdateClasspath = true;
					updateAttributes = true;
				}
			} else if (hasAttribute) {
				// should not have the attribute and currently has it
				updatedAttributes = updateAttributes(entry.getExtraAttributes(), attrib, false);
				needToUpdateClasspath = true;
				updateAttributes = true;				
			}
			
			if (updateAttributes) {
				switch(kind) {
				case IClasspathEntry.CPE_CONTAINER:
					entry = JavaCore.newContainerEntry(entry.getPath(), entry.getAccessRules(), updatedAttributes, entry.isExported());
					break;
				case IClasspathEntry.CPE_LIBRARY:
					entry = JavaCore.newLibraryEntry(entry.getPath(), entry.getSourceAttachmentPath(), entry.getSourceAttachmentRootPath(), entry.getAccessRules(), updatedAttributes, entry.isExported());
					break;
				case IClasspathEntry.CPE_VARIABLE:
					entry = JavaCore.newVariableEntry(entry.getPath(), entry.getSourceAttachmentPath(), entry.getSourceAttachmentRootPath(), entry.getAccessRules(), updatedAttributes, entry.isExported());
					break;					
				case IClasspathEntry.CPE_PROJECT: // although project entries are not yet supported, allow the attribute here and let the validator flag as an error
					entry = JavaCore.newProjectEntry(entry.getPath(), entry.getAccessRules(), entry.combineAccessRules(), updatedAttributes, entry.isExported());
					break;										
				case IClasspathEntry.CPE_SOURCE: // although source entries are not supported, allow the attribute here and let the validator flag as an error
					entry = JavaCore.newSourceEntry(entry.getPath(), entry.getInclusionPatterns(), entry.getExclusionPatterns(), entry.getOutputLocation(), updatedAttributes);
					break;															
				}
			}
			
			updatedClasspath.add(entry);
		}
		if (needToUpdateClasspath) {
			final IClasspathEntry[] updatedCPArray = (IClasspathEntry[]) updatedClasspath.toArray(new IClasspathEntry[updatedClasspath.size()]);
			javaProject.setRawClasspath(updatedCPArray, null);
		}
	}

	private IClasspathAttribute[] updateAttributes(final IClasspathAttribute[] currentAttribs, final IClasspathAttribute targetAttrib, final boolean add) {
		final List updatedAttribs = new ArrayList();
		boolean hasAttrib = false;
		for (int i = 0; i < currentAttribs.length; i++) {
			if (currentAttribs[i].getName().equals(targetAttrib.getName())) {
				hasAttrib = true;
				if (!add) {
					continue;
				}
			}
			updatedAttribs.add(currentAttribs[i]);
		}
		if (add && !hasAttrib) {
			updatedAttribs.add(targetAttrib);
		}
		return (IClasspathAttribute[]) updatedAttribs.toArray(new IClasspathAttribute[updatedAttribs.size()]);
	}
}
