/*******************************************************************************
 * Copyright (c) 2003, 2004 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.j2ee.internal.plugin;


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

import org.eclipse.core.resources.ICommand;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceDelta;
import org.eclipse.core.resources.IResourceDeltaVisitor;
import org.eclipse.core.resources.IResourceVisitor;
import org.eclipse.core.resources.IncrementalProjectBuilder;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jem.workbench.utility.JemProjectUtilities;

/**
 * An example incremental project builder that copies additional class files from a library package
 * fragment root folder into a Java project's output directory.
 * 
 * General parameters:
 * <ul>
 * <li>The project should be a Java project.</li>
 * <li>The class files are in the "imported_classes" folder of the project.</li>
 * <li>This builder should run <b>after </b> the Java builder.</li>
 * <li>Full build should copy class files from a secondary library folder into the output folder
 * maintaining package hierarchy; existing class files must never be overwritten.</li>
 * <li>Only *.class files should be copied (not other resource files).</li>
 * <li>Incremental build and auto-build should will perform the copy when there is an add/change in
 * the "imported_classes" folder.</li>
 * <li>Changing the project's output folder should be handled.</li>
 * </ul>
 * Note: the builder is not currently invoking the Minimize helper, it is relying on the copy to not
 * replace existing class files, and the build path order to ensure that compiled classes override
 * imported ones.
 */
public class LibCopyBuilder extends IncrementalProjectBuilder {
	/**
	 * Internal debug tracing.
	 */
	static boolean DEBUG = false;

	/**
	 * Builder id of this incremental project builder.
	 */
	public static final String BUILDER_ID = J2EEPlugin.LIBCOPY_BUILDER_ID;

	/**
	 * The path where we expect to find the .class files to be copied.
	 */
	public static final String IMPORTED_CLASSES_PATH = "imported_classes"; //$NON-NLS-1$

	/**
	 * The path of the output folder that we last copied class files into, or <code>null</code> if
	 * this builder has not built this project before.
	 */
	private IPath lastOutputPath = null;

	private List sourceContainers;

	private boolean needOutputRefresh;

	/**
	 * Creates a new instance of the library copying builder.
	 * <p>
	 * All incremental project builders are required to have a public 0-argument constructor.
	 * </p>
	 */
	public LibCopyBuilder() {
		super();
	}


	/**
	 * 
	 * The <code>LibCopyBuilder</code> implementation of this
	 * <code>IncrementalProjectBuilder</code> method copies additional class files into the output
	 * folder.
	 * <p>
	 * [Issue: the implementation should report progress.]
	 * </p>
	 * <p>
	 * [Issue: the implementation should probably use a workspace runnable.]
	 * </p>
	 */
	protected IProject[] build(int kind, Map args, IProgressMonitor monitor) throws CoreException {
		sourceContainers = null;
		needOutputRefresh = false;
		if (DEBUG) {
			System.out.println(BUILDER_ID + J2EEPluginResourceHandler.getString("__Start_build_project_INFO_") + getProject().getName()); //$NON-NLS-1$
		}

		boolean builderOrderOK = checkBuilderOrdering();

		if (DEBUG && !builderOrderOK) {
			System.out.println(BUILDER_ID + J2EEPluginResourceHandler.getString("__Bad_builder_order_for_project_INFO_") + getProject().getName()); //$NON-NLS-1$
		}

		IFolder[] classFolders = getClassesFolders();
		if (classFolders.length == 0) {
			// no files to copy
			if (DEBUG)
				System.out.println(BUILDER_ID + J2EEPluginResourceHandler.getString("__No_imported_classes_folder,_quitting_INFO_")); //$NON-NLS-1$
			return null;
		}

		IJavaProject jproject = JavaCore.create(getProject());
		if (jproject == null) {
			// not a java project (anymore?)
			return null;
		}

		IPath outputPath = jproject.getOutputLocation();
		IFolder outputFolder = getProject().getParent().getFolder(outputPath);
		if (outputPath.equals(lastOutputPath)) {
			if (kind == INCREMENTAL_BUILD || kind == AUTO_BUILD) {
				processDelta(getDelta(getProject()), outputFolder, monitor, classFolders);
				refreshOutputIfNecessary(outputFolder);
				return null;
			}
		}

		if (DEBUG) {
			System.out.println(BUILDER_ID + J2EEPluginResourceHandler.getString("__Full/first_build_INFO_")); //$NON-NLS-1$
		}
		copyAllClassFolders(monitor, classFolders, outputFolder);
		lastOutputPath = outputPath;
		refreshOutputIfNecessary(outputFolder);
		return null;
	}

	/**
	 *  
	 */
	private void refreshOutputIfNecessary(IFolder outputFolder) throws CoreException {
		if (needOutputRefresh && outputFolder != null && outputFolder.exists())
			outputFolder.refreshLocal(IResource.DEPTH_INFINITE, null);
	}

	private void copyAllClassFolders(IProgressMonitor monitor, IFolder[] classFolders, IFolder outputFolder) throws CoreException {
		for (int i = 0; i < classFolders.length; i++) {
			copyClassFiles(classFolders[i], outputFolder, monitor);
		}

	}


	/**
	 * Process an incremental build delta.
	 * 
	 * @return <code>true</code> if the delta requires a copy
	 * @param dest
	 *            the destination folder; may or may not exist
	 * @param monitor
	 *            the progress monitor, or <code>null</code> if none
	 * @exception CoreException
	 *                if something goes wrong
	 */
	protected void processDelta(IResourceDelta delta, final IFolder outputFolder, final IProgressMonitor monitor, final IFolder[] classesFolders) {
		if (DEBUG) {
			System.out.println(BUILDER_ID + J2EEPluginResourceHandler.getString("__Considering_delta_INFO_") + delta); //$NON-NLS-1$
		}
		IResourceDeltaVisitor visitor = new IResourceDeltaVisitor() {
			private List copiedClassFolders = new ArrayList(classesFolders.length);

			public boolean visit(IResourceDelta subdelta) throws CoreException {
				IResource resource = subdelta.getResource();
				if (resource.getType() == IResource.FILE) {
					IFolder classesFolder = retrieveClassesFolder(resource, classesFolders);
					if (classesFolder != null && !copiedClassFolders.contains(classesFolder)) {
						int kind = subdelta.getKind();
						switch (kind) {
							case IResourceDelta.ADDED :
							case IResourceDelta.CHANGED :
								if (DEBUG) {
									System.out.println(BUILDER_ID + J2EEPluginResourceHandler.getString("__Delta_build_INFO_") + subdelta); //$NON-NLS-1$
								}
								copyClassFiles(classesFolder, outputFolder, monitor);
								break;
							case IResourceDelta.REMOVED :
								deleteCorrespondingFile((IFile) resource, classesFolder, outputFolder, monitor);
								break;
							case IResourceDelta.ADDED_PHANTOM :
								break;
							case IResourceDelta.REMOVED_PHANTOM :
								break;
						}

					}
				} else if (resource.getType() == IResource.FOLDER && resource.equals(outputFolder)) {
					copyAllClassFolders(null, classesFolders, outputFolder);
					return false;
				}
				return true;
			}
		};
		if (delta != null) {
			try {
				delta.accept(visitor);
			} catch (CoreException e) {
				// should not happen
			}
		}
	}

	/**
	 * @param file
	 * @param classesFolder
	 * @param outputFolder
	 * @param monitor
	 */
	protected void deleteCorrespondingFile(IFile file, IFolder classesFolder, IFolder outputFolder, IProgressMonitor monitor) throws CoreException {
		IPath path = file.getFullPath();
		int segCount = classesFolder.getFullPath().segmentCount();
		path = path.removeFirstSegments(segCount);
		IFile javaFile = findCorrespondingJavaFile(path);
		if (javaFile != null && javaFile.exists())
			return; //There is nothing to do because the file in the output location is from the
		// java compilation not the copy.
		IFile outFile = outputFolder.getFile(path);
		if (outFile.exists())
			outFile.delete(true, false, monitor);
	}


	/**
	 * Method retrieveClassesFolder.
	 * 
	 * @param resource
	 * @return IFolder
	 */
	protected IFolder retrieveClassesFolder(IResource resource, IFolder[] classesFolders) {
		for (int i = 0; i < classesFolders.length; i++) {
			if (classesFolders[i].getName().equals(resource.getProjectRelativePath().segment(0)))
				return classesFolders[i];
		}
		return null;
	}


	/**
	 * Checks whether this builder is configured to run <b>after </b> the Java builder.
	 * 
	 * @return <code>true</code> if the builder order is correct, and <code>false</code>
	 *         otherwise
	 * @exception CoreException
	 *                if something goes wrong
	 */
	private boolean checkBuilderOrdering() throws CoreException {
		// determine relative builder position from project's buildspec
		ICommand[] cs = getProject().getDescription().getBuildSpec();
		int myIndex = -1;
		int javaBuilderIndex = -1;
		for (int i = 0; i < cs.length; i++) {
			if (cs[i].getBuilderName().equals(JavaCore.BUILDER_ID)) {
				javaBuilderIndex = i;
			} else if (cs[i].getBuilderName().equals(BUILDER_ID)) {
				myIndex = i;
			}
		}
		return myIndex > javaBuilderIndex;
	}

	/**
	 * Copies class files from the given source folder to the given destination folder. The
	 * destination folder will be created if required, but only if at least one class file is
	 * copied.
	 * 
	 * @param source
	 *            the source folder; must exist
	 * @param dest
	 *            the destination folder; may or may not exist
	 * @param monitor
	 *            the progress monitor, or <code>null</code> if none
	 * @exception CoreException
	 *                if something goes wrong
	 */
	private void copyClassFiles(IFolder source, final IFolder dest, final IProgressMonitor monitor) throws CoreException {
		if (DEBUG) {
			System.out.println(BUILDER_ID + ": Begin copying class files from " + source.getFullPath() + " to " + dest.getFullPath()); //$NON-NLS-1$ //$NON-NLS-2$
		}

		final int sourcePathLength = source.getFullPath().segmentCount();

		class Visitor implements IResourceVisitor {
			public boolean visit(IResource res) throws CoreException {
				if (res.getType() == IResource.FILE) {
					IFile file = (IFile) res;

					// compute relative path from source folder to this file
					IPath filePath = file.getFullPath();
					IPath dpath = filePath.removeFirstSegments(sourcePathLength);
					IFile targetFile = dest.getFile(dpath);
					copyFile(file, targetFile, dpath, monitor);
				}
				return true;
			}
		}

		try {
			source.accept(new Visitor());
		} catch (CoreException e) {
			// should not happen
		}

	}

	/**
	 * Copies the given file to the given destination file. Does nothing if the destination file
	 * already exists.
	 * 
	 * @param source
	 *            the source file; must exist
	 * @param dest
	 *            the destination file; may or may not exist; never overwritten
	 * @param monitor
	 *            the progress monitor, or <code>null</code> if none
	 * @exception CoreException
	 *                if something goes wrong
	 */
	private void copyFile(IFile source, IFile dest, IPath fileRelativePath, IProgressMonitor monitor) throws CoreException {
		if (pruneForJavaSource(source, fileRelativePath, monitor))
			return; //no copy necessary.
		File sourceFile = null, destFile = null;
		if (source.exists())
			sourceFile = source.getLocation().toFile();
		if (dest.exists())
			destFile = dest.getLocation().toFile();

		if (destFile != null && sourceFile != null) {
			if (DEBUG)
				System.out.println(BUILDER_ID + ": " + dest.getFullPath() + " already exists."); //$NON-NLS-1$ //$NON-NLS-2$
			if (destFile.lastModified() == sourceFile.lastModified())
				return;
			dest.setContents(source.getContents(false), true, false, monitor); //we have to force
			// b/c set the mod
			// stamp makes it
			// think it is out of
			// synch.
			synchronizeModificationStamps(sourceFile, destFile);
			return;
		}
		if (DEBUG) {
			System.out.println(BUILDER_ID + ": Creating " + dest.getFullPath()); //$NON-NLS-1$
		}

		IContainer parent = dest.getParent();
		if (parent.getType() == IResource.FOLDER) {
			mkdirs((IFolder) parent, monitor);
		}
		dest.create(source.getContents(false), false, monitor);
		destFile = dest.getLocation().toFile();
		synchronizeModificationStamps(sourceFile, destFile);
		dest.setDerived(true);
	}

	/**
	 * Return true if a corresponding .java file is found. Remove the .class file from the
	 * imported_classes folder (i.e., delete the source file).
	 * 
	 * @param source
	 * @param monitor
	 * @return
	 */
	private boolean pruneForJavaSource(IFile classFile, IPath fileRelativePath, IProgressMonitor monitor) throws CoreException {
		if (classFile.exists()) {
			IFile javaFile = findCorrespondingJavaFile(fileRelativePath);
			if (javaFile != null && javaFile.exists()) {
				ResourcesPlugin.getWorkspace().validateEdit(new IFile[]{javaFile}, null);
				classFile.delete(true, false, monitor);
				return true;
			}
		}
		return false;
	}


	/**
	 * @param classFilePath
	 * @return
	 */
	private IFile findCorrespondingJavaFile(IPath classFilePath) {
		IPath javaPath = convertToJavaPath(classFilePath);
		List sourceFolders = getSourceContainers();
		IContainer cont;
		IFile javaFile;
		for (int i = 0; i < sourceFolders.size(); i++) {
			cont = (IContainer) sourceFolders.get(i);
			javaFile = cont.getFile(javaPath);
			if (javaFile.exists())
				return javaFile;
		}
		return null;
	}


	private List getSourceContainers() {
		if (sourceContainers == null)
			sourceContainers = JemProjectUtilities.getSourceContainers(getProject());
		return sourceContainers;
	}


	/**
	 * @param classFile
	 * @return
	 */
	private IPath convertToJavaPath(IPath classFilePath) {
		IPath javaPath = classFilePath.removeFileExtension();
		//handle inner classes...look for outermost java file
		String fileName = classFilePath.lastSegment();
		int innerIndex = fileName.indexOf('$');
		if (innerIndex > -1) {
			javaPath = javaPath.removeLastSegments(1);
			javaPath = javaPath.append(fileName.substring(0, innerIndex));
		}
		javaPath = javaPath.addFileExtension("java"); //$NON-NLS-1$
		return javaPath;
	}


	/**
	 * @param source
	 * @param dest
	 */
	private void synchronizeModificationStamps(File sourceFile, File destFile) {
		if (destFile != null && sourceFile != null) {
			destFile.setLastModified(sourceFile.lastModified());
			needOutputRefresh = true;
		}
	}


	/**
	 * Creates the given folder, and its containing folders, if required. Does nothing if the given
	 * folder already exists.
	 * 
	 * @param folder
	 *            the folder to create
	 * @param monitor
	 *            the progress monitor, or <code>null</code> if none
	 * @exception CoreException
	 *                if something goes wrong
	 */
	private void mkdirs(IFolder folder, IProgressMonitor monitor) throws CoreException {
		if (folder.exists()) {
			return;
		}
		IContainer parent = folder.getParent();
		if (!parent.exists() && parent.getType() == IResource.FOLDER) {
			mkdirs((IFolder) parent, monitor);
		}
		folder.create(false, true, monitor);
	}

	private IFolder[] getClassesFolders() {
		IProject project = getProject();
		IJavaProject javaProj = JemProjectUtilities.getJavaProject(project);
		if (javaProj == null)
			return new IFolder[0];
		List result = null;
		IClasspathEntry[] entries;
		try {
			entries = javaProj.getResolvedClasspath(true);
		} catch (JavaModelException e) {
			return new IFolder[0];
		}
		for (int i = 0; i < entries.length; i++) {
			IClasspathEntry entry = entries[i];
			if (entry.getEntryKind() == IClasspathEntry.CPE_LIBRARY) {
				IPath path = entry.getPath();
				IResource res = project.getWorkspace().getRoot().findMember(path);
				if (res != null && res.isAccessible() && res.getType() == IResource.FOLDER && res.getProject().equals(project)) {
					if (result == null)
						result = new ArrayList(1);
					result.add(res);
				}
			}
		}
		if (result == null)
			return new IFolder[0];
		return (IFolder[]) result.toArray(new IFolder[result.size()]);
	}
}