/*******************************************************************************
 * Copyright (c) 2003, 2007 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.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.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.
 * 
 * @deprecated This class is only used for backwards compatibility
 */
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>
	 */
	@Override
	protected IProject[] build(int kind, Map args, IProgressMonitor monitor) throws CoreException {
		// this builder is unnecessary in WTP 1.5
		return null;
//		sourceContainers = null;
//		needOutputRefresh = false;
//		if (DEBUG) {
//			System.out.println(BUILDER_ID + J2EEPluginResourceHandler.__Start_build_project_INFO_ + getProject().getName()); 
//		}
//
//		boolean builderOrderOK = checkBuilderOrdering();
//
//		if (DEBUG && !builderOrderOK) {
//			System.out.println(BUILDER_ID + J2EEPluginResourceHandler.__Bad_builder_order_for_project_INFO_ + getProject().getName()); 
//		}
//
//		IFolder[] classFolders = getClassesFolders();
//		if (classFolders.length == 0) {
//			// no files to copy
//			if (DEBUG)
//				System.out.println(BUILDER_ID + J2EEPluginResourceHandler.__No_imported_classes_folder__quitting_INFO_); 
//			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.__Full_first_build_INFO_);
//		}
//		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++) {
			if (!classFolders[i].equals(outputFolder))
				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.__Considering_delta_INFO_ + delta); 
		}
		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.__Delta_build_INFO_ + subdelta); 
								}
								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()]);
//	}
}
