/*******************************************************************************
 * Copyright (c) 2010, 2011 SAP AG 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:
 *     Kaloyan Raev (SAP AG) - initial API and implementation
 *******************************************************************************/
package org.eclipse.libra.facet;

import static org.eclipse.libra.facet.OSGiBundleFacetUtils.BUILD_PROPERTIES;
import static org.eclipse.libra.facet.OSGiBundleFacetUtils.JAVAX_EL_PACKAGE;
import static org.eclipse.libra.facet.OSGiBundleFacetUtils.JAVAX_PERSISTENCE_PACKAGE;
import static org.eclipse.libra.facet.OSGiBundleFacetUtils.JAVAX_SERVLET_HTTP_PACKAGE;
import static org.eclipse.libra.facet.OSGiBundleFacetUtils.JAVAX_SERVLET_JSP_EL_PACKAGE;
import static org.eclipse.libra.facet.OSGiBundleFacetUtils.JAVAX_SERVLET_JSP_PACKAGE;
import static org.eclipse.libra.facet.OSGiBundleFacetUtils.JAVAX_SERVLET_JSP_TAGEXT_PACKAGE;
import static org.eclipse.libra.facet.OSGiBundleFacetUtils.JAVAX_SERVLET_PACKAGE;
import static org.eclipse.libra.facet.OSGiBundleFacetUtils.JAVA_FACET;
import static org.eclipse.libra.facet.OSGiBundleFacetUtils.JPA_FACET;
import static org.eclipse.libra.facet.OSGiBundleFacetUtils.META_INF;
import static org.eclipse.libra.facet.OSGiBundleFacetUtils.META_PERSISTENCE_HEADER;
import static org.eclipse.libra.facet.OSGiBundleFacetUtils.REQUIRED_PLUGINS_CONTAINER_PATH;
import static org.eclipse.libra.facet.OSGiBundleFacetUtils.WEB_CONTEXT_PATH_HEADER;
import static org.eclipse.libra.facet.OSGiBundleFacetUtils.WEB_INF_CLASSES;
import static org.eclipse.libra.facet.OSGiBundleFacetUtils.getBundleProjectDescription;
import static org.eclipse.libra.facet.OSGiBundleFacetUtils.getContextRootFromWTPModel;
import static org.eclipse.libra.facet.OSGiBundleFacetUtils.getWebContentPath;
import static org.eclipse.libra.facet.OSGiBundleFacetUtils.hasPluginNature;
import static org.eclipse.libra.facet.OSGiBundleFacetUtils.hasRequiredPlugins;
import static org.eclipse.libra.facet.OSGiBundleFacetUtils.isJavaProject;
import static org.eclipse.libra.facet.OSGiBundleFacetUtils.isJpaProject;
import static org.eclipse.libra.facet.OSGiBundleFacetUtils.isWebProject;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IPackageFragment;
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jst.common.project.facet.core.internal.JavaFacetUtil;
import org.eclipse.libra.facet.internal.LibraFacetPlugin;
import org.eclipse.osgi.service.resolver.VersionRange;
import org.eclipse.pde.core.project.IBundleClasspathEntry;
import org.eclipse.pde.core.project.IBundleProjectDescription;
import org.eclipse.pde.core.project.IBundleProjectService;
import org.eclipse.pde.core.project.IPackageExportDescription;
import org.eclipse.pde.core.project.IPackageImportDescription;
import org.eclipse.wst.common.componentcore.ComponentCore;
import org.eclipse.wst.common.componentcore.internal.util.FacetedProjectUtilities;
import org.eclipse.wst.common.componentcore.resources.IVirtualComponent;
import org.eclipse.wst.common.componentcore.resources.IVirtualReference;
import org.eclipse.wst.common.project.facet.core.IDelegate;
import org.eclipse.wst.common.project.facet.core.IProjectFacetVersion;
import org.osgi.framework.Version;


public class OSGiBundleFacetInstallDelegate implements IDelegate {
	
	public void execute(IProject project, IProjectFacetVersion fv,
			Object configObject, IProgressMonitor monitor) throws CoreException {
		OSGiBundleFacetInstallConfig config = (OSGiBundleFacetInstallConfig) configObject;
		doExecute(project, config, monitor);
	}
	
	private static void doExecute(IProject project,
			OSGiBundleFacetInstallConfig config, IProgressMonitor monitor)
			throws CoreException {
		setBundleRoot(project);
		createBundleProjectDescription(project, config, monitor);
		addRequiredPluginsClasspathContainer(project, monitor);

		if (isJpaProject(project)) {
			moveMetaInfToRoot(project, monitor);
		}
	}

	private static void setBundleRoot(IProject project) throws CoreException {
		IPath bundleRoot = null;
		if (isWebProject(project)) {
			bundleRoot = getWebContentPath(project);
		}
		
		if (bundleRoot != null) {
			IBundleProjectService bundleProjectService = LibraFacetPlugin.getDefault().getBundleProjectService();
			bundleProjectService.setBundleRoot(project, bundleRoot);
		}
	}
	
	private static void createBundleProjectDescription(IProject project,
			OSGiBundleFacetInstallConfig config, IProgressMonitor monitor)
			throws CoreException {
		IBundleProjectDescription bundleProjectDescription = getBundleProjectDescription(project);
		bundleProjectDescription.setSymbolicName(config.getSymbolicName());
		bundleProjectDescription.setBundleVersion(config.getVersion());
		
		String bundleName = config.getName();
		if (bundleName != null && bundleName.trim().length() > 0) {
			bundleProjectDescription.setBundleName(bundleName);
		}
		
		String bundleVendor = config.getVendor();
		if (bundleVendor != null && bundleVendor.trim().length() > 0) {
			bundleProjectDescription.setBundleVendor(bundleVendor);
		}
		
		bundleProjectDescription.setEquinox(true);
		bundleProjectDescription.setExtensionRegistry(false);
		bundleProjectDescription.setNatureIds(getNatureIds(bundleProjectDescription));
		bundleProjectDescription.setLaunchShortcuts(getLaunchShortcuts(project));
		
		Map<String, String> headers = getAdditionalHeaders(config, project);
		for (Map.Entry<String, String> entry : headers.entrySet()) {
			bundleProjectDescription.setHeader(entry.getKey(), entry.getValue());
		}
		
		bundleProjectDescription.setPackageExports(getPackageExports(project));
		bundleProjectDescription.setPackageImports(getPackageImports(bundleProjectDescription));
		bundleProjectDescription.setBinIncludes(getBinIncludes(bundleProjectDescription));
		bundleProjectDescription.setBundleClasspath(getBundleClasspath(bundleProjectDescription));
		setExecutionEnvironments(bundleProjectDescription);
		
		bundleProjectDescription.apply(monitor);
	}
	
	private static String[] getNatureIds(IBundleProjectDescription bundleProjectDescription) {
		String[] natureIds = bundleProjectDescription.getNatureIds();
		String[] newNatureIds = new String[natureIds.length + 1];
		for (int i = 0; i < natureIds.length; i++) {
			newNatureIds[i] = natureIds[i];
		}
		newNatureIds[newNatureIds.length - 1] = IBundleProjectDescription.PLUGIN_NATURE;
		
		return newNatureIds;
	}

	private static String[] getLaunchShortcuts(IProject project) throws CoreException {
		if (isWebProject(project)) {
			return new String[] {
					"org.eclipse.pde.ui.EquinoxLaunchShortcut",  //$NON-NLS-1$
					"org.eclipse.wst.server.launchShortcut" //$NON-NLS-1$
			};
		}
		// use default OSGi Framework launchers
		return null;
	}
	
	private static Map<String, String> getAdditionalHeaders(OSGiBundleFacetInstallConfig config, IProject project) throws CoreException {
		Map<String, String> headers = new HashMap<String, String>();
		
		if (isWebProject(project)) {
			// check if there is existing Web-ContextPath header in the manifest
			if (config.getHeaders().containsKey(WEB_CONTEXT_PATH_HEADER)) {
				// overwrite the context path in the WTP model with the one value from the OSGi header
				headers.put(WEB_CONTEXT_PATH_HEADER, config.getHeaders().get(WEB_CONTEXT_PATH_HEADER));
			} else {
				// use the context path from the WTP model
				headers.put(WEB_CONTEXT_PATH_HEADER, getContextRootFromWTPModel(project));
			}
		}
		
		if (isJpaProject(project)) {
			headers.put(META_PERSISTENCE_HEADER, ""); //$NON-NLS-1$
		}
		
		return headers;
	}

	private static IPackageExportDescription[] getPackageExports(IProject project) throws CoreException {
		IBundleProjectService bundleProjectService = LibraFacetPlugin.getDefault().getBundleProjectService();
		List<IPackageExportDescription> list = new ArrayList<IPackageExportDescription>();
		
		if (isJavaProject(project)) {
			IJavaProject javaProject = JavaCore.create(project);
			IPackageFragmentRoot[] fragmentRoots = javaProject.getAllPackageFragmentRoots();
			for (IPackageFragmentRoot fragmentRoot : fragmentRoots) {
				if (fragmentRoot.getKind() == IPackageFragmentRoot.K_SOURCE && fragmentRoot.getParent().equals(javaProject)) {
					IJavaElement[] elements = fragmentRoot.getChildren();
					for (IJavaElement element : elements) {
						IPackageFragment fragment = (IPackageFragment) element;
						if (fragment.containsJavaResources()) {
							list.add(bundleProjectService.newPackageExport(fragment.getElementName(), null, true, null));
						}
					}
				}
			}
		}
		
		return list.toArray(new IPackageExportDescription[list.size()]);
	}

	private static IPackageImportDescription[] getPackageImports(IBundleProjectDescription bundleProjectDescription) throws CoreException {
		IProject project = bundleProjectDescription.getProject();
		Map<String, IPackageImportDescription> packages = new TreeMap<String, IPackageImportDescription>();
		
		// look for existing package imports
		IPackageImportDescription[] imports = bundleProjectDescription.getPackageImports();
		if (imports != null) {
			for (IPackageImportDescription imp : imports) {
				packages.put(imp.getName(), imp);
			}
		}

		if (isWebProject(project)) {
			// add the most popular servlet packages
			addPackageImport(packages, JAVAX_SERVLET_PACKAGE, null, false);
			addPackageImport(packages, JAVAX_SERVLET_HTTP_PACKAGE, null, false);
			addPackageImport(packages, JAVAX_SERVLET_JSP_PACKAGE, null, false);
			addPackageImport(packages, JAVAX_SERVLET_JSP_EL_PACKAGE, null, false);
			addPackageImport(packages, JAVAX_SERVLET_JSP_TAGEXT_PACKAGE, null, false);
			addPackageImport(packages, JAVAX_EL_PACKAGE, null, false);

			// add packages exported by referenced components
			IVirtualComponent component = ComponentCore.createComponent(project);
			IVirtualReference[] references = component.getReferences();
			for (IVirtualReference ref : references) {
				IProject refProject = ref.getReferencedComponent().getProject();
				if (refProject != null && refProject != project && hasPluginNature(refProject)) {
					IPackageExportDescription[] exports = getBundleProjectDescription(refProject).getPackageExports();
					for (IPackageExportDescription export : exports) {
						String importName = export.getName();
						Version exportVersion = export.getVersion();
						VersionRange range = (exportVersion == null) ? null : new VersionRange(exportVersion.toString());
						addPackageImport(packages, importName, range, false);
					}
				}
			}
		}
		
		if (isJpaProject(project)) {
			String version = FacetedProjectUtilities.getProjectFacetVersion(project, JPA_FACET).getVersionString();
			addPackageImport(packages, String.format(JAVAX_PERSISTENCE_PACKAGE, version), null, false);
		}
		
		return packages.values().toArray(new IPackageImportDescription[packages.size()]);
	}
	
	private static void addPackageImport(Map<String, IPackageImportDescription> packages, String importName, VersionRange range, boolean optional) {
		IBundleProjectService bundleProjectService = LibraFacetPlugin.getDefault().getBundleProjectService();
		if (!packages.containsKey(importName)) {
			IPackageImportDescription imp = bundleProjectService.newPackageImport(importName, range, optional);
			packages.put(importName, imp);
		}
	}
	
	private static IPath[] getBinIncludes(IBundleProjectDescription bundleProjectDescription) throws CoreException {
		IProject project = bundleProjectDescription.getProject();
		IVirtualComponent component = ComponentCore.createComponent(project);
		
		if (isWebProject(project)) {
			IPath bundleRoot = component.getRootFolder().getProjectRelativePath();
			IResource[] resources = project.getFolder(bundleRoot).members();
			List<IPath> binPaths = new ArrayList<IPath>();
			
			for (int i = 0; i < resources.length; i++) {
				String token = resources[i].getName();
				if (resources[i].getType() == IResource.FOLDER) {
					token += '/';
				}
				
				if (!token.equals(BUILD_PROPERTIES)) {
					binPaths.add(new Path(token));
				}
			}
			
			return binPaths.toArray(new IPath[binPaths.size()]);
		} 

		// don't modify bin.includes by default
		return bundleProjectDescription.getBinIncludes();
	}

	private static IBundleClasspathEntry[] getBundleClasspath(IBundleProjectDescription bundleProjectDescription) throws CoreException {
		IProject project = bundleProjectDescription.getProject();
		IBundleClasspathEntry[] bundleClasspath = bundleProjectDescription.getBundleClasspath(); 
		
		if (OSGiBundleFacetUtils.isJavaProject(project)) {
			IJavaProject javaProject = JavaCore.create(project);
			if (bundleClasspath == null || bundleClasspath.length == 0) {
				IPath[] javaSourceFolderPaths = getJavaSourceFolderPaths(javaProject);
				
				if (javaSourceFolderPaths != null && javaSourceFolderPaths.length > 0) {
					IBundleProjectService bundleProjectService = LibraFacetPlugin.getDefault().getBundleProjectService();
					
					List<IBundleClasspathEntry> bundleClasspathList = new ArrayList<IBundleClasspathEntry>(); 
					
					IPath binary = getRelativePath(project, javaProject.getOutputLocation());
					IPath library = (isWebProject(project)) 
							? new Path(WEB_INF_CLASSES) 	// add WEB-INF/classes for WABs
							: null; 						// add . for other OSGi bundles
							
					// iterate over source folders and create IBundleClasspathEntry for each one.
					for (IPath iPath : javaSourceFolderPaths) {
						bundleClasspathList.add(bundleProjectService.newBundleClasspathEntry(
								getRelativePath(project, iPath), binary, library));
					}
					bundleClasspath = bundleClasspathList.toArray(new IBundleClasspathEntry[] { });
				}
			} else {
				// TODO
			}
		}
		
		// don't modify bin.includes by default
		return bundleClasspath;
	}
	
	private static void addRequiredPluginsClasspathContainer(IProject project, IProgressMonitor monitor) throws CoreException {
		if (isJavaProject(project)) {
			IJavaProject javaProject = JavaCore.create(project);
			IClasspathEntry[] entries = javaProject.getRawClasspath();
			if (!hasRequiredPlugins(entries)) {
				IClasspathEntry[] newEntries = new IClasspathEntry[entries.length + 1];
				System.arraycopy(entries, 0, newEntries, 0, entries.length);
				newEntries[newEntries.length - 1] = JavaCore.newContainerEntry(REQUIRED_PLUGINS_CONTAINER_PATH);
				javaProject.setRawClasspath(newEntries, monitor);
			}
		}
	}

	private static IPath[] getJavaSourceFolderPaths(IJavaProject javaProject) throws JavaModelException {
		List<IPath> paths = new ArrayList<IPath>();
		
		IPackageFragmentRoot[] fragmentRoots = javaProject.getAllPackageFragmentRoots();
		for (IPackageFragmentRoot fragmentRoot : fragmentRoots) {
			if (fragmentRoot.getKind() == IPackageFragmentRoot.K_SOURCE && fragmentRoot.getParent().equals(javaProject)) {
				paths.add(fragmentRoot.getPath());
			}
		}
		
		return paths.toArray(new IPath[paths.size()]);
	}
	
	private static IPath getRelativePath(IProject project, IPath path) {
		return path.makeRelativeTo(project.getFullPath()).addTrailingSeparator();
	}
	
	private static void setExecutionEnvironments(IBundleProjectDescription bundleProjectDescription) {
		IProject project = bundleProjectDescription.getProject();
		IProjectFacetVersion javaProjectFacetVersion = FacetedProjectUtilities.getProjectFacetVersion(project, JAVA_FACET);
		if (javaProjectFacetVersion != null) {
			String[] existingEEs = bundleProjectDescription.getExecutionEnvironments();
			String newEE = JavaFacetUtil.getCorrespondingExecutionEnvironment(javaProjectFacetVersion);
			//if there are existing EEs different from newEE add newEE. Else just set newEE.   
			if (existingEEs != null) {
				ArrayList<String> eeList = new ArrayList<String>(Arrays.asList(existingEEs));
				if (!eeList.contains(newEE)) {
					eeList.add(newEE);
					bundleProjectDescription.setExecutionEnvironments(eeList.toArray(new String[eeList.size()]));
				}
			} else {
				bundleProjectDescription.setExecutionEnvironments(new String[] { newEE } );
			}
		}
	}
	
	private static void moveMetaInfToRoot(IProject project, IProgressMonitor monitor) throws CoreException {
		// find the first META-INF folder as a second-level folder
		IFolder folder = null;
		IResource[] resources = project.members();
		for (IResource r : resources) {
			if (r.getType() == IResource.FOLDER) {
				IFolder f = (IFolder) r;
				IResource metaInf = f.findMember(META_INF);
				if (metaInf != null && metaInf.getType() == IResource.FOLDER) {
					folder = (IFolder) metaInf;
					break;
				}
			}
		}
		
		if (folder == null || !folder.exists())
			return;
		
		// copy all resources to /META-INF
		IResource[] members = folder.members();
		for (IResource member : members) {
			IPath destination = project.getFolder(META_INF).getFullPath().append(member.getName());  
			if (!project.getWorkspace().getRoot().exists(destination)) { // this check is needed for the /src/MANIFEST.MF added by the jst.utility facet
				member.move(destination, true, monitor);
			}
		}
		folder.delete(true, monitor);
	}

}
