/*******************************************************************************
 * 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:
 *    Gerry Kessler - initial API and implementation
 *******************************************************************************/ 

package org.eclipse.jst.jsf.core.internal.project.facet;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.emf.common.util.EList;
import org.eclipse.jst.j2ee.model.IModelProvider;
import org.eclipse.jst.javaee.web.WebAppVersionType;
import org.eclipse.jst.jsf.core.JSFVersion;
import org.eclipse.jst.jsf.core.internal.JSFCorePlugin;
import org.eclipse.jst.jsf.core.internal.Messages;
import org.eclipse.jst.jsf.core.internal.jsflibraryregistry.ArchiveFile;
import org.eclipse.jst.jsf.core.internal.jsflibraryregistry.JSFLibrary;
import org.eclipse.osgi.util.NLS;
import org.eclipse.wst.common.frameworks.datamodel.IDataModel;


/**
 * 
 */
@SuppressWarnings("deprecation")
public abstract class JSFUtils {
    /**
	 * The default name for the Faces servlet
	 */
	public static final String JSF_DEFAULT_SERVLET_NAME = "Faces Servlet"; //$NON-NLS-1$
	/**
	 * The default name of the Faces servlet class
	 */
	public static final String JSF_SERVLET_CLASS = "javax.faces.webapp.FacesServlet"; //$NON-NLS-1$
	/**
	 * The name of the context parameter used for JSF configuration files
	 */
	public static final String JSF_CONFIG_CONTEXT_PARAM = "javax.faces.CONFIG_FILES"; //$NON-NLS-1$
	
	/**
	 * The name of the context parameter used for defining the default JSP file extension
	 */
	public static final String JSF_DEFAULT_SUFFIX_CONTEXT_PARAM = "javax.faces.DEFAULT_SUFFIX"; //$NON-NLS-1$
	
	/**
	 * The path to the default application configuration file
	 */
	public static final String JSF_DEFAULT_CONFIG_PATH = "/WEB-INF/faces-config.xml";  //$NON-NLS-1$

	/**
	 * Default URL mapping to faces servlet
	 */
	public static final String JSF_DEFAULT_URL_MAPPING = "/faces/*"; //$NON-NLS-1$

	/**
	 * the key for implementation libraries in persistent properties
	 */
	public static final String PP_JSF_IMPLEMENTATION_LIBRARIES = "jsf.implementation.libraries"; //$NON-NLS-1$
	/**
	 * the key for component libraries in persistent properties
	 */
	public static final String PP_JSF_COMPONENT_LIBRARIES = "jsf.component.libraries"; //$NON-NLS-1$
	/**
	 * the key for implementation type in persistent properties
	 */
	public static final String PP_JSF_IMPLEMENTATION_TYPE = "jsf.implementation.type"; //$NON-NLS-1$

	private static final String DEFAULT_DEFAULT_MAPPING_SUFFIX = "jsp"; //$NON-NLS-1$
	
	private final JSFVersion  _version;
    private final IModelProvider _modelProvider;
	
	/**
	 * @param version
	 * @param modelProvider 
	 */
	protected JSFUtils(final JSFVersion version, final IModelProvider modelProvider)
	{
	    _version = version;
	    _modelProvider = modelProvider;
	}
	
	/**
	 * @return the jsf version that this instance is for.
	 */
	public final JSFVersion getVersion()
    {
        return _version;
    }

	/**
	 * @param config
	 * @return servlet display name to use from wizard data model
	 */
	protected final String getDisplayName(IDataModel config) {
		String displayName = config.getStringProperty(IJSFFacetInstallDataModelProperties.SERVLET_NAME);
		if (displayName == null || displayName.trim().length() == 0)
			displayName = JSF_DEFAULT_SERVLET_NAME;
		return displayName.trim();
	}
	
	/**
	 * @param config
	 * @return servlet display name to use from wizard data model
	 */
	protected final String getServletClassname(IDataModel config) {
		String className = config.getStringProperty(IJSFFacetInstallDataModelProperties.SERVLET_CLASSNAME);
		if (className == null || className.trim().equals("")) //$NON-NLS-1$
			className = JSF_SERVLET_CLASS;
		return className.trim();
	}

	/**
	 * @return IModelProvider
	 */
	public final IModelProvider getModelProvider() {
		Object webAppObj = _modelProvider.getModelObject();
		if (webAppObj == null)
		{
			return null;
		}
		return _modelProvider;
	}

   /**
     * @param configPath
     */
    public final void createConfigFile(IPath configPath)
    {
        FileOutputStream os = null;
//        final String QUOTE = new String(new char[] { '"' });
        try {
            IPath dirPath = configPath.removeLastSegments(1);
            dirPath.toFile().mkdirs();
            File file = configPath.toFile();
            file.createNewFile();
            os = new FileOutputStream(file);
            printConfigFile(os);
        } catch (FileNotFoundException e) {
            JSFCorePlugin.log(IStatus.ERROR, Messages.JSFUtils_ErrorCreatingConfigFile, e);
        } catch (IOException e) {
            JSFCorePlugin.log(IStatus.ERROR, Messages.JSFUtils_ErrorCreatingConfigFile, e);
        } finally {
            if (os != null) {
                try {
                    os.close();
                } catch (IOException e) {
                    JSFCorePlugin.log(IStatus.ERROR, Messages.JSFUtils_ErrorClosingConfigFile, e);
                }
            }
        }
    }
    
    /**
     * @param out
     */
    protected final void printConfigFile(final OutputStream out)
    {
        PrintWriter pw = null;
        try
        {
            pw = new PrintWriter(out);
            doVersionSpecificConfigFile(pw);
        }
        finally
        {
            if (pw != null)
            {
                pw.close();
            }
        }
    }
    
    /**
     * @param pw
     */
    public abstract void doVersionSpecificConfigFile(final PrintWriter pw);
    
    
    /**
     * @param webAppObj 
     * @return true if this going into a JavaEE (1.5 and later) or a J2EE (1.4 and earlier)
     * configured application.
     */
    public boolean isJavaEE(final Object webAppObj)
    {
      if (webAppObj instanceof org.eclipse.jst.javaee.web.WebApp)
      {
          org.eclipse.jst.javaee.web.WebApp webApp = (org.eclipse.jst.javaee.web.WebApp)webAppObj;
          return WebAppVersionType.VALUES.contains(webApp.getVersion());
      }
      return false;
    }

    /**
     * @param config
     * @return list of URL patterns from the datamodel
     */
    protected final List<String> getServletMappings(final IDataModel config) {
        final List<String> mappings = new ArrayList<String>();
        final String[] patterns = (String[])config.getProperty(IJSFFacetInstallDataModelProperties.SERVLET_URL_PATTERNS);
        if (patterns != null)
        {
            for (final String pattern : patterns)
            {
                mappings.add(pattern);
            }
        }
        return mappings;
    }
    /**
     * Does an update of the web application's config file.
     * 
     * @param webApp must be WebApp of the appropriate type.
     * @param config
     * @throws ClassCastException if webApp is not the appropriate type.
     */
    public abstract void updateWebApp(Object webApp, IDataModel config);


    /**
     * Called on a facet uninstall to remove JSF related changes.
     * @param webApp
     */
    public abstract void rollbackWebApp(Object webApp);
    
    /**
     * @param fileExtension
     * @return true if the file extension is deemed to be for a JSF.
     */
    protected boolean isValidKnownExtension(String fileExtension) {
        if (fileExtension != null &&
                (   fileExtension.equalsIgnoreCase(DEFAULT_DEFAULT_MAPPING_SUFFIX) ||  
                fileExtension.equalsIgnoreCase("jspx") ||  //$NON-NLS-1$
                fileExtension.equalsIgnoreCase("jsf") || //$NON-NLS-1$
                fileExtension.equalsIgnoreCase("xhtml"))) //$NON-NLS-1$
            return true;

        return false;
    }

    
    /**
     * @param resource
     * @return true if the resource is deemed to be a JSF page.
     */
    protected boolean isJSFPage(IResource resource) {
        // currently always return true.
        // need to find quick way of determining whether this is a JSF JSP Page
        return true;
    }
    
    /**
     * @param webApp
     * @return the default file extension from the context param. Default is
     *         "jsp" if no context param.
     */
    protected String getDefaultSuffix(Object webApp) {
    	String contextParam = null;
    	if(isJavaEE(webApp)) {
    		contextParam = JEEUtils.getContextParam((org.eclipse.jst.javaee.web.WebApp) webApp, JSF_DEFAULT_SUFFIX_CONTEXT_PARAM);
    	}
    	else {
    		contextParam = J2EEUtils.getContextParam((org.eclipse.jst.j2ee.webapplication.WebApp) webApp, JSF_DEFAULT_SUFFIX_CONTEXT_PARAM);
    	}
    	if(contextParam == null) {
    		return getDefaultDefaultSuffix();
    	}
   		return normalizeSuffix(contextParam);
    }
    
    /**
     * @return the default value for the default mapping suffix
     */
    protected String getDefaultDefaultSuffix()
    {
        return DEFAULT_DEFAULT_MAPPING_SUFFIX;
    }

    /**
     * @param name 
     * @param value 
     * @return the 
     */
    protected final String calculateSuffix(final String name, final String value)
    {
        if (name != null
                && JSF_DEFAULT_SUFFIX_CONTEXT_PARAM.equals(name
                        .trim()))
        {
            return normalizeSuffix(value != null ? value.trim() : null);
        }
        return null;
    }

    /**
     * @param defSuffix
     * @return the suffix value with any leading dot removed
     */
    protected final String normalizeSuffix(String defSuffix)
    {
        if (defSuffix != null && defSuffix.startsWith(".")) //$NON-NLS-1$
        {
            defSuffix = defSuffix.substring(1);
        }
        return defSuffix;
    }

    /**
     * Holds all the obsolete JSF Library stuff.  This will go away post-Helios.
     * @author cbateman
     *
     */
    public static class JSFLibraryHandler
    {
        /**
         * Construct an array that hold paths for all JARs in a JSF library. 
         * 
         * @param jsfLib
         * @param logMissingJar true to log an error for each invalid JAR.
         * @return elements
         */
        public final IPath[] getJARPathforJSFLib(JSFLibrary jsfLib, boolean logMissingJar) {        
            EList archiveFiles = jsfLib.getArchiveFiles();
            int numJars = archiveFiles.size();
            IPath[] elements = new IPath[numJars];
            ArchiveFile ar = null;
            for (int i= 0; i < numJars; i++) {
                ar = (ArchiveFile)archiveFiles.get(i); 
                if ( !ar.exists() && logMissingJar ) {
                    logErroronMissingJAR(jsfLib, ar);
                }
                elements[i] = new Path(((ArchiveFile)archiveFiles.get(i)).getResolvedSourceLocation()).makeAbsolute();
            }
            return elements;
        }   
        
        private int numberofValidJar(EList archiveFiles) {
            int total = 0;
            final Iterator it = archiveFiles.iterator();
            ArchiveFile ar = null;
            while(it.hasNext()) {
                ar = (ArchiveFile) it.next();
                if (ar.exists()) {
                    total++;
                }
            }
            return total;
        }
        
        private void logErroronMissingJAR(JSFLibrary jsfLib, ArchiveFile ar) {
            String msg = NLS.bind(Messages.JSFUtils_MissingJAR, 
                            ar.getName(),
                            jsfLib.getLabel());
            JSFCorePlugin.log(IStatus.ERROR, msg);
        }
        
        /**
         * Construct an array that hold paths for all JARs in a JSF library. 
         * However, archive files that no longer exist are filtered out.  
         * 
         * @param jsfLib
         * @param logMissingJar true to log an error for each invalid JAR.
         * @return elements
         */
        public final IPath[] getJARPathforJSFLibwFilterMissingJars(JSFLibrary jsfLib, boolean logMissingJar) {
            EList archiveFiles = jsfLib.getArchiveFiles();
            int numJars = numberofValidJar(archiveFiles);
            IPath[] elements = new IPath[numJars];
            ArchiveFile ar = null;
            int idxValidJar = 0;
            for (int i= 0; i < archiveFiles.size(); i++) {
                ar = (ArchiveFile)archiveFiles.get(i); 
                if ( !ar.exists() ) {
                    if (logMissingJar) {
                        logErroronMissingJAR(jsfLib, ar);
                    }
                } else {
                    elements[idxValidJar] = new Path(((ArchiveFile)archiveFiles.get(i)).getResolvedSourceLocation()).makeAbsolute();
                    idxValidJar++;
                }
            }
            return elements;        
        }

    }
    
	/**
	 * Finds and returns a JSF Servlet definition, or null if servlet is not defined.
	 * 
	 * @param webApp
	 * @return Servlet or null
	 */    
    protected Object findJSFServlet(Object webApp) {
    	if(isJavaEE(webApp)) {
    		return JEEUtils.findServlet((org.eclipse.jst.javaee.web.WebApp) webApp, JSF_SERVLET_CLASS);
    	}
   		return J2EEUtils.findServlet((org.eclipse.jst.j2ee.webapplication.WebApp) webApp, JSF_SERVLET_CLASS);
    }

    /**
     * Creates servlet reference in WebApp if not present or updates servlet
     * name if found using the passed configuration.
     * 
     * @param webApp
     * @param config
     * @param servlet
     * @return Servlet servlet - if passed servlet was null, will return created
     *         servlet
     */
    protected Object createOrUpdateServletRef(final Object webApp,
            final IDataModel config, Object servlet)
    {
        String displayName = getDisplayName(config);
        String className = getServletClassname(config);
    	if(isJavaEE(webApp)) {
    		return JEEUtils.createOrUpdateServletRef((org.eclipse.jst.javaee.web.WebApp) webApp, displayName, className, (org.eclipse.jst.javaee.web.Servlet) servlet);
    	}
   		return J2EEUtils.createOrUpdateServletRef((org.eclipse.jst.j2ee.webapplication.WebApp) webApp, displayName, className, (org.eclipse.jst.j2ee.webapplication.Servlet) servlet);
    }

    /**
     * Creates servlet-mappings for the servlet for 2.5 WebModules or greated
     * 
     * @param webApp
     * @param urlMappingList
     *            - list of string values to be used in url-pattern for
     *            servlet-mapping
     * @param servlet
     */
    protected void setUpURLMappings(final Object webApp,
            final List<String> urlMappingList, final Object servlet)
    {
    	if(isJavaEE(webApp)) {
    		JEEUtils.setUpURLMappings((org.eclipse.jst.javaee.web.WebApp) webApp, urlMappingList, (org.eclipse.jst.javaee.web.Servlet) servlet);
    	}
    	else {
    		J2EEUtils.setUpURLMappings((org.eclipse.jst.j2ee.webapplication.WebApp) webApp, urlMappingList, (org.eclipse.jst.j2ee.webapplication.Servlet) servlet);
    	}
    }

	/**
	 * Removes servlet-mappings for servlet using servlet-name for >= 2.5 WebModules.
	 * @param webApp
	 * @param servlet
	 */
	protected void removeURLMappings(final Object webApp, final Object servlet) {
    	if(isJavaEE(webApp)) {
    		JEEUtils.removeURLMappings((org.eclipse.jst.javaee.web.WebApp) webApp, (org.eclipse.jst.javaee.web.Servlet) servlet);
    	}
    	else {
    		J2EEUtils.removeURLMappings((org.eclipse.jst.j2ee.webapplication.WebApp) webApp, (org.eclipse.jst.j2ee.webapplication.Servlet) servlet);
    	}
	}
	
	/**
	 * Removes servlet definition
	 * @param webApp
	 * @param servlet
	 */
	protected void removeJSFServlet(final Object webApp, final Object servlet) {
    	if(isJavaEE(webApp)) {
    		JEEUtils.removeServlet((org.eclipse.jst.javaee.web.WebApp) webApp, (org.eclipse.jst.javaee.web.Servlet) servlet);
    	}
    	else {
    		J2EEUtils.removeServlet((org.eclipse.jst.j2ee.webapplication.WebApp) webApp, (org.eclipse.jst.j2ee.webapplication.Servlet) servlet);
    	}
	}
	
    /**
     * Removes context-param
     * @param webApp
     */
    protected void removeJSFContextParams(final Object webApp) {
    	if(isJavaEE(webApp)) {
    		JEEUtils.removeContextParam((org.eclipse.jst.javaee.web.WebApp) webApp, JSF_CONFIG_CONTEXT_PARAM);
    	}
    	else {
    		J2EEUtils.removeContextParam((org.eclipse.jst.j2ee.webapplication.WebApp) webApp, JSF_CONFIG_CONTEXT_PARAM);
    	}
    }
    
	/**
	 * Creates or updates context-params
	 * @param webApp
	 * @param config
	 */
	protected void setupContextParams(final Object webApp, final IDataModel config) {
        final String paramValue = config.getStringProperty(IJSFFacetInstallDataModelProperties.CONFIG_PATH);
        if (paramValue != null && !paramValue.equals(JSF_DEFAULT_CONFIG_PATH)) {
        	if(isJavaEE(webApp)) {
        		JEEUtils.setupContextParam((org.eclipse.jst.javaee.web.WebApp) webApp, JSF_CONFIG_CONTEXT_PARAM, paramValue);
        	}
        	else {
        		J2EEUtils.setupContextParam((org.eclipse.jst.j2ee.webapplication.WebApp) webApp, JSF_CONFIG_CONTEXT_PARAM, paramValue);
        	}
        }

	}
	
    /**
     * @param map
     * @param webApp
     * @return extension from map. Will return null if file extension not found
     *         in url patterns.
     */
    protected String getFileExtensionFromMap(final Object webApp, final Object map) {
    	if(isJavaEE(webApp)) {
    		return JEEUtils.getFileExtensionFromMap((org.eclipse.jst.javaee.web.ServletMapping) map);
    	}
   		return J2EEUtils.getFileExtensionFromMap((org.eclipse.jst.j2ee.webapplication.ServletMapping) map);
    }

    /**
     * @param webApp 
     * @param map
     * @return prefix mapping. may return null.
     */
    protected String getPrefixMapping(final Object webApp, final Object map) {
    	if(isJavaEE(webApp)) {
    		return JEEUtils.getPrefixMapping((org.eclipse.jst.javaee.web.ServletMapping) map);
    	}
   		return J2EEUtils.getPrefixMapping((org.eclipse.jst.j2ee.webapplication.ServletMapping) map);
    }
    
    /**
     * @param webAppObj
     * @param resource
     * @param existingURL
     * @return the modified url path for the (possibly) jsf resource.
     */
    public IPath getFileUrlPath(Object webAppObj, IResource resource,
            IPath existingURL) {
        // if not a JSF page, do nothing
        if (!isJSFPage(resource))
        {
            return null;
        }

        Object servlet = findJSFServlet(webAppObj);
        if (servlet == null)
        {// if no faces servlet, do nothing
            return null;
        }

        String defaultSuffix = getDefaultSuffix(webAppObj);
        // is the resource using default_suffix
        String fileExtension = resource.getFileExtension();
        boolean canUseExtensionMapping = fileExtension != null && fileExtension.equalsIgnoreCase(defaultSuffix);
        // if not using default extension and is not a known file extension,
        // then we will abort
        if (!canUseExtensionMapping
                && !isValidKnownExtension(resource.getFileExtension()))
            return null;

    	if(isJavaEE(webAppObj)) {
    		org.eclipse.jst.javaee.web.WebApp webApp =  (org.eclipse.jst.javaee.web.WebApp) webAppObj;

            final String servletName = ((org.eclipse.jst.javaee.web.Servlet) servlet).getServletName();

            String foundFileExtension = null;
            for (final org.eclipse.jst.javaee.web.ServletMapping map : webApp.getServletMappings())
            {
                if (map != null &&
                        map.getServletName() != null &&
                        map.getServletName().trim().equals(servletName.trim()))
                {
                    foundFileExtension = getFileExtensionFromMap(webAppObj, map);
                    if (foundFileExtension != null && canUseExtensionMapping)
                    {
                        return existingURL.removeFileExtension()
                                .addFileExtension(foundFileExtension);
                    }

                    String foundPrefixMapping = getPrefixMapping(webAppObj, map);
                    if (foundPrefixMapping != null)
                    {
                        return new Path(foundPrefixMapping).append(existingURL);
                    }
                }
            }

            if (!canUseExtensionMapping && foundFileExtension != null)
            {
                // we could prompt user that this may not work...
                // for now we will return the extension mapping
                return existingURL.removeFileExtension().addFileExtension(
                        foundFileExtension);
            }

            // we could, at this point, add a url mapping to the faces servlet,
            // or prompt user that it may be a good idea to add one... 

    	}
    	else {
            Iterator mappings = ((org.eclipse.jst.j2ee.webapplication.Servlet)servlet).getMappings().iterator();
            org.eclipse.jst.j2ee.webapplication.ServletMapping map = null;
            String foundFileExtension = null;
            String foundPrefixMapping = null;
            while (mappings.hasNext())
            {
                map = (org.eclipse.jst.j2ee.webapplication.ServletMapping)mappings.next();

                foundFileExtension = getFileExtensionFromMap(webAppObj, map);
                if (foundFileExtension != null && canUseExtensionMapping) 
                {
                    return existingURL.removeFileExtension().addFileExtension(foundFileExtension);
                }
                
                if (foundPrefixMapping == null)
                {
                    foundPrefixMapping = getPrefixMapping(webAppObj, map);
                }
            }
            if (foundPrefixMapping != null)
            {
                return new Path(foundPrefixMapping).append(existingURL); 
            }
            if (! canUseExtensionMapping && foundFileExtension != null){
                //we could prompt user that this may not work...
                //for now we will return the extension mapping
                return existingURL.removeFileExtension().addFileExtension(foundFileExtension);
            }
            
            // we could, at this point, add a url mapping to the faces servlet, 
            // or prompt user that it may be a good idea to add one...

    	}
    	return null;
    }
}
