/*******************************************************************************
 * 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.jem.util.logger.proxy.Logger;
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.internal.project.J2EEProjectUtilities;
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);
	}
	
	public IStatus execute(final IProgressMonitor monitor, final IAdaptable info)
			throws ExecutionException {
		final IProject project = ProjectUtilities.getProject(model.getStringProperty(PROJECT_NAME));

		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);
				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);
							if (attrib == null) {
								attrib = UpdateClasspathAttributeUtil.createDependencyAttribute(runtimePath); 
							}
							entriesToAttrib.put(entry, attrib);
						}
						updateDependencyAttributes(javaProject, entriesToAttrib); 
					} else {
						removeDependencyAttributes(javaProject, entriesToRemove); 
					}
				} else {
					addDependencyAttributes(javaProject, entriesToAdd); 
				}
			}
		} catch (CoreException ce) {
			Logger.getLogger(J2EEPlugin.PLUGIN_ID).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.
	 * @throws CoreException Thrown if an error is encountered.
	 */	
	private void addDependencyAttributes(final IJavaProject javaProject, final Map entries) throws CoreException {
		alterDependencyAttributes(javaProject, entries, true);
	}
	
	/**
	 * 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.
	 * @throws CoreException Thrown if an error is encountered.
	 */	
	private void removeDependencyAttributes(final IJavaProject javaProject, final Map entries) throws CoreException {
		alterDependencyAttributes(javaProject, entries, false);
	}

	private void alterDependencyAttributes(final IJavaProject javaProject, final Map entries, final boolean add) throws CoreException {
		// initialize to the set of raw entries with the attrib
		final Map entriesWithAttrib = ClasspathDependencyUtil.getRawComponentClasspathDependencies(javaProject);
		
		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
						final boolean isWebApp = J2EEProjectUtilities.isDynamicWebProject(javaProject.getProject());
						runtimePath = ClasspathDependencyUtil.getDefaultRuntimePath(isWebApp);
					}
					final IClasspathAttribute attrib =  UpdateClasspathAttributeUtil.createDependencyAttribute(runtimePath);
 					entriesWithAttrib.put(entry, attrib);
				}
			} else {
				IClasspathEntry matching = getMatchingEntryIgnoreAttributes(entriesWithAttrib, entry);
				if (matching != null) {
					entriesWithAttrib.remove(matching);
				}
			}
		}
		updateDependencyAttributes(javaProject, entriesWithAttrib);
	}
	
	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.
	 * @throws CoreException Thrown if an error is encountered.
	 */	
	private void updateDependencyAttributes(final IJavaProject javaProject, final Map entriesWithAttrib) 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();  
		for (int i = 0; i < rawClasspath.length; i++) {
			IClasspathEntry entry = rawClasspath[i];
			final int kind = entry.getEntryKind();
			boolean hasAttribute = ClasspathDependencyUtil.checkForComponentDependencyAttribute(entry) != 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()]);
	}
}
