/*******************************************************************************
 * 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>
 * @since 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);
}