/*******************************************************************************
 * Copyright (c) 2003, 2005 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.server.core;

import java.io.File;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.*;
import org.eclipse.jdt.core.*;
import org.eclipse.jdt.launching.JavaRuntime;
import org.eclipse.jst.server.core.internal.*;
import org.eclipse.wst.server.core.IRuntime;
import org.eclipse.wst.server.core.model.RuntimeTargetHandlerDelegate;
/**
 * A runtime target handler that supports changing the classpath of the
 * project by adding one or more classpath containers. Runtime providers
 * can extend this class and implement the abstract methods to provide
 * the correct build path for their runtime type. 
 * 
 * <p>
 * <b>Provisional API:</b> This class/interface is part of an interim API that is still under development and expected to 
 * change significantly before reaching stability. It is being made available at this early stage to solicit feedback 
 * from pioneering adopters on the understanding that any code that uses this API will almost certainly be broken 
 * (repeatedly) as the API evolves.
 * </p>
 * @plannedfor 1.0
 */
public abstract class ClasspathRuntimeTargetHandler extends RuntimeTargetHandlerDelegate {
	private class SourceAttachmentUpdate {
		String runtimeId;
		String id;
		IPath entry;
		IPath sourceAttachmentPath;
		IPath sourceAttachmentRootPath;
		IClasspathAttribute[] attributes;
	}

	private List sourceAttachments;

	/** (non-Javadoc)
	 * @see RuntimeTargetHandlerDelegate#setRuntimeTarget(IProject, IRuntime, IProgressMonitor)
	 */
	public void setRuntimeTarget(IProject project, IRuntime runtime, IProgressMonitor monitor) throws CoreException {
		if (project == null || runtime == null)
			return;

		IJavaProject javaProject = null;
		try {
			javaProject = (IJavaProject) project.getNature(JavaCore.NATURE_ID);
		} catch (Exception e) {
			// ignore
		}
		
		if (javaProject == null)
			return;
		
		try {
			List list = new ArrayList();
			IClasspathEntry[] cp = javaProject.getRawClasspath();
			int size = cp.length;
			for (int i = 0; i < size; i++) {
				if (cp[i].getEntryKind() == IClasspathEntry.CPE_CONTAINER) {
					if (!cp[i].getPath().segment(0).equals(RuntimeClasspathContainer.SERVER_CONTAINER))
						list.add(cp[i]);
				} else
					list.add(cp[i]);
			}
			
			List add = new ArrayList();
			IClasspathEntry[] entries = getDelegateClasspathEntries(runtime, monitor);
			if (entries != null) {
				size = entries.length;
				for (int i = 0; i < size; i++)
					add.add(entries[i]);
			}
			
			String[] ids = getClasspathEntryIds();
			if (ids != null) {
				size = ids.length;
				for (int i = 0; i < size; i++) {
					String id2 = getRuntimeTargetHandler().getId();
					IPath path = new Path(RuntimeClasspathContainer.SERVER_CONTAINER).append(id2).append(runtime.getId());
					if (ids[i] != null)
						path.append(ids[i]);
					add.add(JavaCore.newContainerEntry(path));
					String id = "";
					if (path.segmentCount() > 3)
						id = path.segment(3);
					RuntimeClasspathContainer rcc = new RuntimeClasspathContainer(path, this, runtime, id);
					JavaCore.setClasspathContainer(path, new IJavaProject[] { javaProject}, new IClasspathContainer[] { rcc }, monitor);
				}
			}
			
			// clean up duplicates
			cleanupDuplicateClasspath(javaProject, list, add);
			
			Iterator iterator = add.iterator();
			while (iterator.hasNext()) {
				list.add(iterator.next());
			}
			
			cp = new IClasspathEntry[list.size()];
			list.toArray(cp);
			javaProject.setRawClasspath(cp, monitor);
		} catch (Exception e) {
			Trace.trace(Trace.WARNING, "Error setting runtime target", e);
			throw new CoreException(new Status(IStatus.ERROR, JavaServerPlugin.PLUGIN_ID, 0, e.getLocalizedMessage(), e));
		}
	}

	private void cleanupDuplicateClasspath(IJavaProject project, List current, List add) {
		if (project == null || current == null || add == null)
			throw new IllegalArgumentException();
		
		// check if we even have to bother
		boolean sourceOnly = true;
		Iterator iterator = current.iterator();
		while (iterator.hasNext()) {
			IClasspathEntry entry = (IClasspathEntry) iterator.next();
			if (entry.getEntryKind() != IClasspathEntry.CPE_SOURCE)
				sourceOnly = false;
		}
		if (sourceOnly)
			return;
		
		// remove any of our own containers
		List remove = new ArrayList();
		iterator = current.iterator();
		while (iterator.hasNext()) {
			IClasspathEntry entry = (IClasspathEntry) iterator.next();
			
			if (entry.getEntryKind() == IClasspathEntry.CPE_CONTAINER) {
				try {
					if (RuntimeClasspathContainer.SERVER_CONTAINER.equals(entry.getPath().segment(0))
						|| JavaRuntime.JRE_CONTAINER.equals(entry.getPath().segment(0)))
						remove.add(entry);
				} catch (Exception e) {
					Trace.trace(Trace.FINEST, "Error resolving classpath container", e);
				}
			}
		}

		// expand the "add" list
		List addExpanded = new ArrayList();
		iterator = add.iterator();
		while (iterator.hasNext()) {
			IClasspathEntry entry = (IClasspathEntry) iterator.next();
			if (entry.getEntryKind() == IClasspathEntry.CPE_CONTAINER) {
				try {
					IClasspathContainer container = JavaCore.getClasspathContainer(entry.getPath(), project);
					IClasspathEntry[] entries = container.getClasspathEntries();
					int size = entries.length;
					for (int i = 0; i < size; i++) {
						if (entries[i] != null)
							addExpanded.add(entries[i]);
					}
				} catch (Exception e) {
					Trace.trace(Trace.FINEST, "Error resolving classpath container 2", e);
				}
			} else if (entry.getEntryKind() == IClasspathEntry.CPE_VARIABLE) {
				entry = JavaCore.getResolvedClasspathEntry(entry);
				if (entry != null)
					addExpanded.add(entry);
			} else
				addExpanded.add(entry);
		}
		
		// check for duplicates by also expanding the current list
		iterator = current.iterator();
		while (iterator.hasNext()) {
			IClasspathEntry entry = (IClasspathEntry) iterator.next();
			
			List currentExpanded = new ArrayList();
			if (entry.getEntryKind() == IClasspathEntry.CPE_CONTAINER) {
				try {
					IClasspathContainer container = JavaCore.getClasspathContainer(entry.getPath(), project);
					IClasspathEntry[] entries = container.getClasspathEntries();
					int size = entries.length;
					for (int i = 0; i < size; i++) {
						if (entries[i] != null)
							currentExpanded.add(entries[i]);
					}
				} catch (Exception e) {
					Trace.trace(Trace.FINEST, "Error resolving classpath container 3", e);
				}
			} else if (entry.getEntryKind() == IClasspathEntry.CPE_VARIABLE) {
				entry = JavaCore.getResolvedClasspathEntry(entry);
				if (entry != null)
					currentExpanded.add(entry);
			} else
				currentExpanded.add(entry);
			
			// loop over all of the expanded entries of this current entry
			boolean dup = false;
			Iterator iterator2 = currentExpanded.iterator();
			while (!dup && iterator2.hasNext()) {
				IClasspathEntry entry2 = (IClasspathEntry) iterator2.next();
				Iterator iterator3 = addExpanded.iterator();
				while (iterator3.hasNext()) {
					IClasspathEntry entry3 = (IClasspathEntry) iterator3.next();
					if (entry3.getPath().equals(entry2.getPath()))
						dup = true;
				}
			}
			if (dup && !remove.contains(entry))
				remove.add(entry);
		}
		
		// remove duplicates
		iterator = remove.iterator();
		while (iterator.hasNext()) {
			current.remove(iterator.next());
		}
	}

	/** (non-Javadoc)
	 * @see RuntimeTargetHandlerDelegate#removeRuntimeTarget(IProject, IRuntime, IProgressMonitor)
	 */
	public void removeRuntimeTarget(IProject project, IRuntime runtime, IProgressMonitor monitor) {
		Trace.trace(Trace.FINEST, "Removing runtime target");
		if (project == null || runtime == null)
			return;

		IJavaProject javaProject = null;
		try {
			javaProject = (IJavaProject) project.getNature(JavaCore.NATURE_ID);
		} catch (Exception e) {
			// ignore
		}

		if (javaProject == null)
			return;
		
		try {
			IClasspathEntry[] delegates = getDelegateClasspathEntries(runtime, monitor);
			int delegateSize = 0;
			if (delegates != null)
				delegateSize = delegates.length;

			List list = new ArrayList();
			IClasspathEntry[] cp = javaProject.getRawClasspath();
			int size = cp.length;
			for (int i = 0; i < size; i++) {
				boolean remove = false;
				
				if (cp[i].getPath().segment(0).equals(RuntimeClasspathContainer.SERVER_CONTAINER))
					remove = true;
				
				for (int j = 0; j < delegateSize; j++) {
					if (cp[i].equals(delegates[j]))
						remove = true;
				}
				if (!remove)
					list.add(cp[i]);
			}
			
			cp = new IClasspathEntry[list.size()];
			list.toArray(cp);
			javaProject.setRawClasspath(cp, monitor);
		} catch (Exception e) {
			Trace.trace(Trace.WARNING, "Error removing runtime target", e);
		}
	}
	
	private static void addJarFiles(File dir, List list, boolean includeSubdirectories) {
		int depth = 0;
		if (includeSubdirectories)
			depth = 2;
		addJarFiles(dir, list, depth);
	}
	
	private static void addJarFiles(File dir, List list, int depth) {
		if (dir == null)
			throw new IllegalArgumentException();
		
		File[] files = dir.listFiles();
		if (files != null) {
			int size = files.length;
			for (int i = 0; i < size; i++) {
				if (files[i].isDirectory() && depth > 0) {
					addJarFiles(files[i], list, depth - 1);
				} else if (files[i].getAbsolutePath().endsWith(".jar") || files[i].getAbsolutePath().endsWith(".zip")) {
					IPath path = new Path(files[i].getAbsolutePath());
					list.add(JavaCore.newLibraryEntry(path, null, null));
				}
			}
		}
	}
	
	/**
	 * Add library entries to the given list for every jar file found in the
	 * given directory. Optionally search subdirectories as well.
	 * 
	 * @param list a list
	 * @param dir a directory
	 * @param includeSubdirectories <code>true</code> to include subdirectories, and
	 *    <code>false</code> otherwise
	 */
	protected static void addLibraryEntries(List list, File dir, boolean includeSubdirectories) {
		if (dir == null)
			throw new IllegalArgumentException();
		addJarFiles(dir, list, includeSubdirectories);
	}

	/**
	 * Returns the classpath entries that correspond to the given runtime.
	 * 
	 * @param runtime a runtime
	 * @param monitor a progress monitor, or <code>null</code> if progress
	 *    reporting and cancellation are not desired
	 * @return an array of classpath entries
	 */
	public IClasspathEntry[] getDelegateClasspathEntries(IRuntime runtime, IProgressMonitor monitor) {
		return null;
	}

	/**
	 * Returns the classpath entry ids for this runtime target handler. These
	 * ids will be added to the classpath container id to create a new fully
	 * qualified classpath container id.
	 * <p>
	 * By default, there is a single classpath entry for the runtime, with no
	 * extra id (<code>new String[1]</code>). To create multiple ids, just
	 * return a string array containing the ids. For instance, to have two
	 * classpath containers with ids "id1" and "id2", use
	 * <code>new String[] { "id1", "id2" }</code>
	 * </p>
	 * 
	 * @return an array of classpath entry ids
	 */
	public String[] getClasspathEntryIds() {
		return new String[1];
	}

	/**
	 * Request that the classpath container for the given runtime and id be updated
	 * with the given classpath container entries.
	 * 
	 * @param runtime a runtime
	 * @param id an id
	 * @param entries an array of classpath entries
	 */
	public void requestClasspathContainerUpdate(IRuntime runtime, String id, IClasspathEntry[] entries) {
		// default behaviour is to save the source path entries
		if (runtime == null || entries == null)
			return;
		
		// find the source attachments
		sourceAttachments = new ArrayList();
		
		int size = entries.length;
		for (int i = 0; i < size; i++) {
			if (entries[i].getSourceAttachmentPath() != null || entries[i].getExtraAttributes() != null) {
				SourceAttachmentUpdate sau = new SourceAttachmentUpdate();
				sau.runtimeId = runtime.getId();
				sau.id = id;
				sau.entry = entries[i].getPath();
				sau.sourceAttachmentPath = entries[i].getSourceAttachmentPath();
				sau.sourceAttachmentRootPath = entries[i].getSourceAttachmentRootPath();
				sau.attributes = entries[i].getExtraAttributes();
				sourceAttachments.add(sau);
			}
		}
		save();
	}

	/**
	 * Returns the classpath container label for the given runtime and the given
	 * classpath container id (returned from getClasspathEntryIds()). This method
	 * must not return null.
	 * 
	 * @param runtime the runtime to resolve the container label for
	 * @param id the classpath entry id
	 * @return a classpath container label
	 */
	public abstract String getClasspathContainerLabel(IRuntime runtime, String id);

	/**
	 * Resolve the classpath container.
	 * 
	 * @param runtime a runtime
	 * @param id a container id
	 * @return a possibly empty array of classpath entries
	 */
	public IClasspathEntry[] resolveClasspathContainerImpl(IRuntime runtime, String id) {
		IClasspathEntry[] entries = resolveClasspathContainer(runtime, id);
		
		if (entries == null)
			entries = new IClasspathEntry[0];
		
		if (sourceAttachments == null)
			load();
		
		int size = entries.length;
		int size2 = sourceAttachments.size();
		for (int i = 0; i < size; i++) {
			for (int j = 0; j < size2; j++) {
				SourceAttachmentUpdate sau = (SourceAttachmentUpdate) sourceAttachments.get(j);
				if ((id != null && sau.id.equals(id)) || (id == null && sau.id == null)) {
					if (sau.runtimeId.equals(runtime.getId()) && sau.entry.equals(entries[i].getPath())) {
						entries[i] = JavaCore.newLibraryEntry(entries[i].getPath(), sau.sourceAttachmentPath, sau.sourceAttachmentRootPath, new IAccessRule[0], sau.attributes, false);
					}
				}
			}
		}
		
		return entries;
	}
	
	private void save() {
		if (sourceAttachments == null)
			return;
		String id = getRuntimeTargetHandler().getId();
		String filename = JavaServerPlugin.getInstance().getStateLocation().append(id + ".xml").toOSString();
		try {
			XMLMemento memento = XMLMemento.createWriteRoot("classpath");

			Iterator iterator = sourceAttachments.iterator();
			while (iterator.hasNext()) {
				SourceAttachmentUpdate sau = (SourceAttachmentUpdate) iterator.next();
				IMemento child = memento.createChild("source-attachment");
				child.putString("runtime-id", sau.runtimeId);
				if (sau.id != null)
					child.putString("id", sau.id);
				if (sau.entry != null)
					child.putString("entry", sau.entry.toPortableString());
				if (sau.sourceAttachmentPath != null)
					child.putString("source-attachment-path", sau.sourceAttachmentPath.toPortableString());
				if (sau.sourceAttachmentRootPath != null)
					child.putString("source-attachment-root-path", sau.sourceAttachmentRootPath.toPortableString());
				if (sau.attributes != null) {
					int size = sau.attributes.length;
					for (int i = 0; i < size; i++) {
						IClasspathAttribute attr = sau.attributes[i];
						IMemento attrChild = child.createChild("attribute");
						attrChild.putString("name", attr.getName());
						attrChild.putString("value", attr.getValue());
					}
				}
			}
			
			memento.saveToFile(filename);
		} catch (Exception e) {
			Trace.trace(Trace.SEVERE, "Error saving source path info", e);
		}
	}

	private void load() {
		sourceAttachments = new ArrayList();
		
		if (getRuntimeTargetHandler() == null)
			return;
		String id = getRuntimeTargetHandler().getId();
		String filename = JavaServerPlugin.getInstance().getStateLocation().append(id + ".xml").toOSString();
		
		try {
			IMemento memento = XMLMemento.loadMemento(filename);
			
			IMemento[] children = memento.getChildren("source-attachment");
			int size = children.length;
			
			for (int i = 0; i < size; i++) {
				try {
					SourceAttachmentUpdate sau = new SourceAttachmentUpdate();
					sau.runtimeId = children[i].getString("runtime-id");
					sau.id = children[i].getString("id");
					String temp = children[i].getString("entry");
					if (temp != null)
						sau.entry = new Path(temp);
					temp = children[i].getString("source-attachment-path");
					if (temp != null)
						sau.sourceAttachmentPath = new Path(temp);
					temp = children[i].getString("source-attachment-root-path");
					if (temp != null)
						sau.sourceAttachmentRootPath = new Path(temp);
					IMemento[] attrChildren = children[i].getChildren("attribute");
					if (attrChildren != null) {
						int size2 = attrChildren.length;
						sau.attributes = new IClasspathAttribute[size2];
						for (int j = 0; j < size2; j++) {
							String name = attrChildren[j].getString("name");
							String value = attrChildren[j].getString("value");
							sau.attributes[j] = JavaCore.newClasspathAttribute(name, value);
						}
					}
					sourceAttachments.add(sau);
				} catch (Exception e) {
					Trace.trace(Trace.WARNING, "Could not load monitor: " + e);
				}
			}
		} catch (Exception e) {
			Trace.trace(Trace.WARNING, "Could not load source path info: " + e.getMessage());
		}
	}

	/**
	 * Resolves (creates the classpath entries for) the classpath container with
	 * the given runtime and the given classpath container id (returned from
	 * getClasspathEntryIds()). If the classpath container cannot be resolved
	 * (for instance, if the runtime does not exist), return null.
	 * 
	 * @param runtime the runtime to resolve the container for
	 * @param id the classpath entry id
	 * @return an array of classpath entries for the container, or null if the
	 *   container could not be resolved
	 */
	public abstract IClasspathEntry[] resolveClasspathContainer(IRuntime runtime, String id);
}