/*******************************************************************************
 * Copyright (c) 2005 Oracle Corporation.
 * 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:
 *    Ian Trimble - initial API and implementation
 *******************************************************************************/ 
package org.eclipse.jst.jsf.core.jsfappconfig;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.StringTokenizer;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.emf.common.util.EList;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jst.j2ee.common.ParamValue;
import org.eclipse.jst.j2ee.internal.J2EEVersionConstants;
import org.eclipse.jst.j2ee.model.IModelProvider;
import org.eclipse.jst.j2ee.model.ModelProviderManager;
import org.eclipse.jst.j2ee.web.componentcore.util.WebArtifactEdit;
import org.eclipse.jst.j2ee.webapplication.ContextParam;
import org.eclipse.jst.j2ee.webapplication.WebApp;
import org.eclipse.jst.jsf.core.IJSFCoreConstants;
import org.eclipse.jst.jsf.core.internal.JSFCorePlugin;
import org.eclipse.jst.jsf.core.internal.Messages;
import org.eclipse.osgi.util.NLS;
import org.eclipse.wst.common.componentcore.ComponentCore;
import org.eclipse.wst.common.componentcore.resources.IVirtualComponent;
import org.eclipse.wst.common.componentcore.resources.IVirtualFolder;
import org.eclipse.wst.common.project.facet.core.IFacetedProject;
import org.eclipse.wst.common.project.facet.core.IProjectFacetVersion;
import org.eclipse.wst.common.project.facet.core.ProjectFacetsManager;

/**
 * JSFAppConfigUtils provides utility methods useful in processing of a JSF
 * application configuration.
 * 
 * <p><b>Provisional API - subject to change</b></p>
 * 
 * @author Ian Trimble - Oracle
 */
public class JSFAppConfigUtils {

	/**
	 * Name of JSF CONFIG_FILES context parameter ("javax.faces.CONFIG_FILES").
	 */
	public static final String CONFIG_FILES_CONTEXT_PARAM_NAME = "javax.faces.CONFIG_FILES"; //$NON-NLS-1$

	/**
	 * Location in JAR file of application configuration resource file
	 * ("META-INF/faces-config.xml"). 
	 */
	public static final String FACES_CONFIG_IN_JAR_PATH = "META-INF/faces-config.xml"; //$NON-NLS-1$

    
    /**
     * @param project
     * @param minVersion
     * @return true if project is a JSF facet project and the version of the project
     * is at least minVersion.
     */
    public static boolean isValidJSFProject(IProject project, String minVersion)
    {
        boolean isValid = false;
        
        final IProjectFacetVersion projectFacetVersion = getProjectFacet(project);
        
        if (projectFacetVersion != null)
        {
            try
            {
                final String versionString = 
                    projectFacetVersion.getVersionString();
                final Comparator comparator = 
                    projectFacetVersion.getProjectFacet().getVersionComparator();
                final int compareToMin = 
                    comparator.compare(versionString, minVersion);
                
                if (compareToMin >=0)
                {
                    return true;
                }
            }
            catch (CoreException ce)
            {
                JSFCorePlugin.log(ce, "Error checking facet version"); //$NON-NLS-1$
            }
        }
        return isValid;
    }
    
	/**
	 * Tests if the passed IProject instance is a valid JSF project in the
	 * following ways:
	 * <ul>
	 * <li>project is not null and is accessible, </li>
	 * <li>project has the JSF facet set on it.</li>
	 * </ul>
	 * 
	 * @param project IProject instance to be tested.
	 * @return true if the IProject instance is a valid JSF project, else
	 * false.
	 */
	public static boolean isValidJSFProject(IProject project) {
		boolean isValid = false;
        IProjectFacetVersion projectFacet = getProjectFacet(project);
        if (projectFacet != null)
        {
            isValid = true;
        }
		return isValid;
	}
    /**
     * Get the facet version for the project 
     * @param project
     * @return the project facet version or null if could not be found or if
     * project is not accessible
     */
    public static IProjectFacetVersion getProjectFacet(IProject project)
    {
        //check for null or inaccessible project
        if (project != null && project.isAccessible()) {
            //check for JSF facet on project
            try {
                IFacetedProject facetedProject = ProjectFacetsManager.create(project);
                if (facetedProject != null) {
                    Set projectFacets = facetedProject.getProjectFacets();
                    Iterator itProjectFacets = projectFacets.iterator();
                    while (itProjectFacets.hasNext()) {
                        IProjectFacetVersion projectFacetVersion = (IProjectFacetVersion)itProjectFacets.next();
                        if (IJSFCoreConstants.JSF_CORE_FACET_ID.equals(projectFacetVersion.getProjectFacet().getId()))
                        {
                            return projectFacetVersion;
                        }
                    }
                }
            } catch(CoreException ce) {
                //log error
                JSFCorePlugin.log(IStatus.ERROR, ce.getLocalizedMessage(), ce);
            }
        }
        return null;
    }
    
	/**
	 * Gets an IVirtualFolder instance which represents the root context's
	 * web content folder.
	 * 
	 * @param project IProject instance for which to get the folder.
	 * @return IVirtualFolder instance which represents the root context's
	 * web content folder.
	 */
	public static IVirtualFolder getWebContentFolder(IProject project) {
		IVirtualFolder folder = null;
		IVirtualComponent component = ComponentCore.createComponent(project);
		if (component != null) {
			folder = component.getRootFolder();
		}
		return folder;
	}

	/**
	 * Gets an IPath instance representing the path of the passed IFile
	 * instance relative to the web content folder.
	 * 
	 * @param file IFile instance for which a path is required.
	 * @return IPath instance representing the path relative to the web content
	 * folder.
	 */
	public static IPath getWebContentFolderRelativePath(IFile file) {
		IPath path = null;
		if (file != null) {
			IVirtualFolder webContentFolder = getWebContentFolder(file.getProject());
			if (webContentFolder != null) {
				IPath webContentPath = webContentFolder.getProjectRelativePath();
				IPath filePath = file.getProjectRelativePath();
				int matchingFirstSegments = webContentPath.matchingFirstSegments(filePath);
				path = filePath.removeFirstSegments(matchingFirstSegments);
			}
		}
		return path;
	}

	/**
	 * Gets list of application configuration file names as listed in the JSF
	 * CONFIG_FILES context parameter ("javax.faces.CONFIG_FILES"). Will return
	 * an empty list if WebArtifactEdit is null, if WebApp is null, if context
	 * parameter does not exist, or if trimmed context parameter's value is
	 * an empty String.
	 * 
	 * @param project IProject instance for which to get the context
	 * parameter's value.
	 * @return List of application configuration file names as listed in the
	 * JSF CONFIG_FILES context parameter ("javax.faces.CONFIG_FILES"); list
	 * may be empty.
	 */
	public static List getConfigFilesFromContextParam(IProject project) {
		List filesList = Collections.EMPTY_LIST;
		if (isValidJSFProject(project)) {
			IModelProvider provider = ModelProviderManager.getModelProvider(project);
			Object webAppObj = provider.getModelObject();
			if (webAppObj != null){
				if (webAppObj instanceof WebApp)
					filesList = getConfigFilesForJ2EEApp(project);
				else if (webAppObj instanceof org.eclipse.jst.javaee.web.WebApp)
					filesList = getConfigFilesForJEEApp((org.eclipse.jst.javaee.web.WebApp)webAppObj);
			}
			
		}
		return filesList;
	}

	private static List getConfigFilesForJEEApp(org.eclipse.jst.javaee.web.WebApp webApp) {
		String filesString = null;
		List contextParams = webApp.getContextParams();
		Iterator itContextParams = contextParams.iterator();
		while (itContextParams.hasNext()) {
			org.eclipse.jst.javaee.core.ParamValue paramValue = (org.eclipse.jst.javaee.core.ParamValue)itContextParams.next();
			if (paramValue.getParamName().equals(CONFIG_FILES_CONTEXT_PARAM_NAME)) {
				filesString = paramValue.getParamValue();
				break;
			}
		}		
		return parseFilesString(filesString);	
	}

	private static List getConfigFilesForJ2EEApp(IProject project){
		List filesList = new ArrayList();
		WebArtifactEdit webArtifactEdit = WebArtifactEdit.getWebArtifactEditForRead(project);
		if (webArtifactEdit != null) {
			try {
				WebApp webApp = null;
				try {
					webApp = webArtifactEdit.getWebApp();
				} catch(ClassCastException cce) {
					//occasionally thrown from WTP code in RC3 and possibly later
					JSFCorePlugin.log(IStatus.ERROR, cce.getLocalizedMessage(), cce);
					return filesList;
				}
				if (webApp != null) {
					String filesString = null;
					//need to branch here due to model version differences (BugZilla #119442)
					if (webApp.getVersionID() == J2EEVersionConstants.WEB_2_3_ID) {
						EList contexts = webApp.getContexts();
						Iterator itContexts = contexts.iterator();
						while (itContexts.hasNext()) {
							ContextParam contextParam = (ContextParam)itContexts.next();
							if (contextParam.getParamName().equals(CONFIG_FILES_CONTEXT_PARAM_NAME)) {
								filesString = contextParam.getParamValue();
								break;
							}
						}
					} else {
						EList contextParams = webApp.getContextParams();
						Iterator itContextParams = contextParams.iterator();
						while (itContextParams.hasNext()) {
							ParamValue paramValue = (ParamValue)itContextParams.next();
							if (paramValue.getName().equals(CONFIG_FILES_CONTEXT_PARAM_NAME)) {
								filesString = paramValue.getValue();
								break;
							}
						}
					}					
					filesList = parseFilesString(filesString);				
				}
			} finally {
				webArtifactEdit.dispose();
			}
		}

		return filesList;
	}
	
	private static List parseFilesString(String filesString) {
		List filesList = new ArrayList();
		if (filesString != null && filesString.trim().length() > 0) {			
			StringTokenizer stFilesString = new StringTokenizer(filesString, ","); //$NON-NLS-1$
			while (stFilesString.hasMoreTokens()) {
				String configFile = stFilesString.nextToken().trim();
				filesList.add(configFile);
			}
		}
		return filesList;
	}

	/**
	 * Gets list of JAR file names, where each file name represents a JAR on
	 * the classpath that contains a /META-INF/faces-config.xml entry. Will
	 * return an empty list if no such JAR files are located.
	 * 
	 * @param project IProject instance for which to scan the classpath.
	 * @return List of JAR file names, where each file name represents a JAR
	 * on the classpath that contains a ...META-INF/faces-config.xml entry;
	 * list may be empty.
	 * @throws CoreException Thrown when underlying calls into JavaCore fail.
	 * @throws IOException Thrown when attempt to open JAR to determine if it
	 * contains a /META-INF/faces-config.xml entry fails.
	 */
	public static List getConfigFileJARsFromClasspath(IProject project) throws CoreException, IOException {
		ArrayList JARsList = new ArrayList();
		if (project.isAccessible()
		        && project.hasNature(JavaCore.NATURE_ID)) {
			IJavaProject javaProject = JavaCore.create(project);
			if (javaProject != null) {
				IClasspathEntry[] classpathEntries = javaProject.getResolvedClasspath(true);
				if (classpathEntries != null && classpathEntries.length > 0) {
					IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot();
					for (int i = 0; i < classpathEntries.length; i++) {
						IClasspathEntry classpathEntry = classpathEntries[i];
						if (classpathEntry.getEntryKind() == IClasspathEntry.CPE_LIBRARY) {
							IPath libraryPath = classpathEntry.getPath();
							if (libraryPath.getFileExtension() != null && libraryPath.getFileExtension().length() > 0) {
								if (libraryPath.getDevice() == null && workspaceRoot.getProject(libraryPath.segment(0)).exists()) {
									libraryPath = workspaceRoot.getFile(libraryPath).getLocation();
								}
								String libraryPathString = libraryPath.toString();
								JarFile jarFile = null;
								try {
									//check existence first [222249]
									File file = new File(libraryPathString);
									if (file.exists()) {
										jarFile = new JarFile(file, false);
										if (jarFile != null) {
											JarEntry jarEntry = jarFile.getJarEntry(FACES_CONFIG_IN_JAR_PATH);
											if (jarEntry != null) {
												JARsList.add(libraryPathString);
											}
										}
									}
								} catch (FileNotFoundException fnfex) {
									//should not get here, but eat error since this could only occur in under strange circumstances [222249]
								} catch(IOException ioe) {
									JSFCorePlugin.log(
											IStatus.ERROR,
											NLS.bind(Messages.JSFAppConfigUtils_ErrorOpeningJarFile, libraryPathString),
											ioe);
								} finally {
									if (jarFile != null) {
										jarFile.close();
									}
								}
							}
						}
					}
				}
			}
		}
		return JARsList;
	}

}
