/*******************************************************************************
 * 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.j2ee.internal.jca.archive.operations;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
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.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jem.util.logger.proxy.Logger;
import org.eclipse.jst.j2ee.commonarchivecore.internal.Archive;
import org.eclipse.jst.j2ee.commonarchivecore.internal.File;
import org.eclipse.jst.j2ee.commonarchivecore.internal.exception.ArchiveRuntimeException;
import org.eclipse.jst.j2ee.commonarchivecore.internal.exception.OpenFailureException;
import org.eclipse.jst.j2ee.commonarchivecore.internal.helpers.ArchiveOptions;
import org.eclipse.jst.j2ee.commonarchivecore.internal.util.ArchiveUtil;
import org.eclipse.jst.j2ee.internal.J2EEConstants;
import org.eclipse.jst.j2ee.internal.archive.operations.ComponentLoadStrategyImpl;
import org.eclipse.jst.j2ee.internal.project.J2EEProjectUtilities;
import org.eclipse.wst.common.componentcore.resources.IVirtualComponent;

public class ConnectorComponentLoadStrategyImpl extends ComponentLoadStrategyImpl {

	private int dotJavaLength = ArchiveUtil.DOT_JAVA.length();
	private List alreadyIndexed = new ArrayList();
	private Map classesMap;
	private IFile knownDD;

	public static String[] knownLibExtensions = {".jar", //$NON-NLS-1$
				".zip", //$NON-NLS-1$
				".so", //$NON-NLS-1$
				".o", //$NON-NLS-1$
				".sl", //$NON-NLS-1$
				".dll", //$NON-NLS-1$
	}; //$NON-NLS-1$

	public ConnectorComponentLoadStrategyImpl(IVirtualComponent vComponent) {
		super(vComponent);
		knownDD = vComponent.getRootFolder().getFile(J2EEConstants.RAR_DD_URI).getUnderlyingFile();
	}

	public List getFiles() {
		Collection nestedJars = getNestedJARsFromSourceRoots();
		Iterator interator = nestedJars.iterator();
		while (interator.hasNext()) {
			filesHolder.addFile((File) interator.next());
		}
		aggregateSourceFiles();
		return filesHolder.getFiles();
	}

	private Collection getNestedJARsFromSourceRoots() {
		List nestedJars = new ArrayList();
		IPackageFragmentRoot[] sourceRoots = J2EEProjectUtilities.getSourceContainers(vComponent.getProject());
		for (int i = 0; i < sourceRoots.length; i++) {
			File aFile;
			try {
				aFile = getNestedJar(sourceRoots[i]);
				if (null != aFile) {
					nestedJars.add(aFile);
				}
			} catch (JavaModelException e) {
				Logger.getLogger().logError(e);
			}
		}
		return nestedJars;
	}



	private File getNestedJar(IPackageFragmentRoot sourceRoot) throws JavaModelException {
		IPath outputPath = sourceRoot.getRawClasspathEntry().getOutputLocation();
		if (outputPath == null) {
			IProject project = vComponent.getProject();
			try {
				if (project.hasNature(JavaCore.NATURE_ID)) {
					IJavaProject javaProject = JavaCore.create(project);
					outputPath = javaProject.getOutputLocation();
				}
			} catch (CoreException e) {
				Logger.getLogger().logError(e);
			}
			if (outputPath == null) {
				return null;
			}
		}

		IFolder javaOutputFolder = ResourcesPlugin.getWorkspace().getRoot().getFolder(outputPath);
		indexClassesForOutputFolder(javaOutputFolder);
		IContainer sourceContainer = (IContainer) sourceRoot.getResource();

		int sourceContainerSegmentCount = sourceContainer.getProjectRelativePath().segmentCount();
		boolean isModuleRoot = knownDD.getProjectRelativePath().toString().startsWith(sourceContainer.getProjectRelativePath().toString());
		List iFiles = new ArrayList();
		boolean foundJava = gatherFilesForJAR(iFiles, sourceContainer, isModuleRoot, false, sourceContainerSegmentCount);
		if (!isModuleRoot || foundJava) {
			for (int i = 0; i < iFiles.size(); i++) {
				filesHolder.removeIFile((IFile) iFiles.get(i));
			}
			File nestedArchive = createNestedArchive(iFiles, sourceContainer, javaOutputFolder);
			return nestedArchive;
		}
		return null;
	}

	private boolean gatherFilesForJAR(List iFiles, IContainer current, boolean isModuleRoot, boolean foundJava, int sourceContainerSegmentCount) {
		IResource[] members;
		try {
			members = current.members();
		} catch (CoreException core) {
			throw new ArchiveRuntimeException(core);
		}
		for (int i = 0; i < members.length; i++) {
			IResource res = members[i];
			if (res.getType() == IResource.FOLDER) {
				foundJava = gatherFilesForJAR(iFiles, (IFolder) res, isModuleRoot, foundJava, sourceContainerSegmentCount) || foundJava;
			} else {// it must be a file
				IFile srcFile = (IFile) res;
				if (belongsInNestedJAR(srcFile, isModuleRoot)) {
					if (isJava(srcFile)) {
						if (exportSource) {
							iFiles.add(srcFile);
						}
						String className = srcFile.getProjectRelativePath().removeFirstSegments(sourceContainerSegmentCount).toString();
						className = className.substring(0, className.length() - dotJavaLength);
						List classes = retrieveClasses(className);
						if (null != classes) {
							Iterator iterator = classes.iterator();
							while (iterator.hasNext()) {
								IFile clazz = (IFile) iterator.next();
								iFiles.add(clazz);
							}
						}
					} else {
						iFiles.add(srcFile);
					}
					if (isModuleRoot)
						foundJava = foundJava || isJava(srcFile) || isClass(srcFile);
				}
			}
		}
		return foundJava;
	}

	private File createNestedArchive(List files, IContainer sourceContainer, IFolder javaOutputFolder) {
		ConnectorComponentNestedJARLoadStrategyImpl loader = new ConnectorComponentNestedJARLoadStrategyImpl(files, sourceContainer, javaOutputFolder);
		ArchiveOptions options = ((Archive) getContainer()).getOptions().cloneWith(loader);
		String uri = computeUniqueArchiveURI(sourceContainer);
		try {
			return getArchiveFactory().primOpenArchive(options, uri);
		} catch (OpenFailureException ex) {
			throw new ArchiveRuntimeException(ex);
		}
	}

	private String computeUniqueArchiveURI(IResource resource) {
		int increment = 0;
		String name = resource.getName();
		StringBuffer sb = null;
		do {
			sb = new StringBuffer(name.length() + 5);
			sb.append('_');
			sb.append(name);
			if (increment > 0)
				sb.append(increment);
			sb.append(".jar"); //$NON-NLS-1$
			increment++;
		} while (filesHolder.contains(sb.toString()));
		return sb.toString();
	}

	private boolean belongsInNestedJAR(IFile iFile, boolean isModuleRoot) {
		if (isModuleRoot && isDeploymentDescriptor(iFile)) {
			return false;
		}
		for (int i = 0; i < knownLibExtensions.length; i++) {
			if (hasExtension(iFile, knownLibExtensions[i]))
				return false;
		}
		return true;
	}

	protected boolean shouldInclude(String uri) {
		return !hasExtension(uri, ArchiveUtil.DOT_CLASS) && !hasExtension(uri, ArchiveUtil.DOT_JAVA);
	}

	/**
	 * Find all the .class files and index them so inner classes can be located.
	 */
	private void indexClassesForOutputFolder(IFolder javaOutputFolder) {
		if (null == javaOutputFolder || alreadyIndexed.contains(javaOutputFolder)) {
			return;
		}
		alreadyIndexed.add(javaOutputFolder);
		int segmentCount = javaOutputFolder.getProjectRelativePath().segmentCount();
		indexClasses(javaOutputFolder, segmentCount);
	}

	private void indexClasses(IResource resource, int javaOutputSegmentCount) {
		switch (resource.getType()) {
			case IResource.FILE :
				indexClass((IFile) resource, javaOutputSegmentCount);
				break;
			case IResource.FOLDER :
				try {
					IResource[] members = ((IFolder) resource).members();
					for (int i = 0; i < members.length; i++) {
						indexClasses(members[i], javaOutputSegmentCount);
					}
				} catch (CoreException e) {
					Logger.getLogger().logError(e);
				}
				break;
		}
	}

	private void indexClass(IFile iFile, int javaOutputSegmentCount) {
		if (!isClass(iFile))
			return;
		if (classesMap == null)
			classesMap = new HashMap();
		String name = iFile.getName();
		IPath relPath = iFile.getProjectRelativePath().removeFirstSegments(javaOutputSegmentCount);
		String key = relPath.toString();
		if (name.indexOf('$') != -1) {
			key = key.substring(0, key.indexOf('$'));
		} else {
			key = key.substring(0, key.indexOf('.'));
		}
		List inners = (List) classesMap.get(key);
		if (inners == null) {
			inners = new ArrayList(1);
			classesMap.put(key, inners);
		}
		inners.add(iFile);
	}

	public List retrieveClasses(String key) {
		if (classesMap == null)
			return null;
		return (List) classesMap.get(key);
	}

	public static boolean isJava(IFile iFile) {
		return hasExtension(iFile, ArchiveUtil.DOT_JAVA);
	}

	public static boolean isClass(IFile iFile) {
		return hasExtension(iFile, ArchiveUtil.DOT_CLASS);
	}

	private static boolean hasExtension(IFile iFile, String ext) {
		String name = iFile.getName();
		return hasExtension(name, ext);
	}

	private static boolean hasExtension(String name, String ext) {
		int offset = ext.length();
		return name.regionMatches(true, name.length() - offset, ext, 0, offset);
	}

	private boolean isDeploymentDescriptor(IFile iFile) {
		return knownDD.equals(iFile);
	}
}
