/*******************************************************************************
 * 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.PrintWriter;
import java.util.Iterator;
import java.util.List;

import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.jst.javaee.core.JavaeeFactory;
import org.eclipse.jst.javaee.core.ParamValue;
import org.eclipse.jst.javaee.core.UrlPatternType;
import org.eclipse.jst.javaee.web.Servlet;
import org.eclipse.jst.javaee.web.ServletMapping;
import org.eclipse.jst.javaee.web.WebApp;
import org.eclipse.jst.javaee.web.WebAppVersionType;
import org.eclipse.jst.javaee.web.WebFactory;
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.wst.common.frameworks.datamodel.IDataModel;

/**
 * Utility file for JSF v1.2 model
 * 
 * @author Gerry Kessler - Oracle
 */
public class JSFUtils12 extends JSFUtils{

	/**
	 * @param webApp
	 * @return Servlet - the JSF Servlet for the specified WebApp or null if not present
	 */
	public static Servlet findJSFServlet(WebApp webApp) {

		Iterator it = webApp.getServlets().iterator();
		
		while (it.hasNext()) {
            Servlet servlet = (Servlet) it.next();
			if (servlet.getServletClass() != null &&
					servlet.getServletClass().equals (JSF_SERVLET_CLASS)) {
				return servlet;
			}
		}
        
        // if we get to here then we have finished the loop
        // without finding the servlet we're looking for
		return null;
	}

	/**
	 * Creates a stubbed JSF v1.2 configuration file for specified JSF version and path
	 * @param jsfVersion
	 * @param configPath
	 */
	public static void createConfigFile(String jsfVersion, IPath configPath) {
		FileOutputStream os = null;
		PrintWriter pw = 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);
			pw = new PrintWriter(os);
			pw.write("<?xml version=" + QUOTE + "1.0" + QUOTE + " encoding=" //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
					+ QUOTE + "UTF-8" + QUOTE + "?>\n\n"); //$NON-NLS-1$ //$NON-NLS-2$

			if (jsfVersion.equals(IJSFCoreConstants.FACET_VERSION_1_2)) 
            {
				pw.write("<faces-config\n"); //$NON-NLS-1$
				pw.write("    " + "xmlns=" + QUOTE //$NON-NLS-1$ //$NON-NLS-2$
						+ "http://java.sun.com/xml/ns/javaee" + QUOTE + "\n"); //$NON-NLS-1$ //$NON-NLS-2$
				pw.write("    " + "xmlns:xsi=" + QUOTE //$NON-NLS-1$ //$NON-NLS-2$
						+ "http://www.w3.org/2001/XMLSchema-instance" + QUOTE //$NON-NLS-1$
						+ "\n"); //$NON-NLS-1$
				pw
						.write("    " //$NON-NLS-1$
								+ "xsi:schemaLocation=" //$NON-NLS-1$
								+ QUOTE
								+ "http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_1_2.xsd" //$NON-NLS-1$
								+ QUOTE + "\n"); //$NON-NLS-1$
				pw.write("    " + "version=" + QUOTE + "1.2" + QUOTE + ">\n\n"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
				pw.write("</faces-config>\n"); //$NON-NLS-1$
			}

			pw.close();
			pw = null;
		} catch (FileNotFoundException e) {
			JSFCorePlugin.log(IStatus.ERROR, Messages.JSFUtils_ErrorCreatingConfigFile, e);
		} catch (IOException e) {
			JSFCorePlugin.log(IStatus.ERROR, Messages.JSFUtils_ErrorCreatingConfigFile, e);
		} finally {
			if (pw != null)
				pw.close();
			if (os != null) {
				try {
					os.close();
				} catch (IOException e) {
					JSFCorePlugin.log(IStatus.ERROR, Messages.JSFUtils_ErrorClosingConfigFile, e);
				}
			}
		}
	}


	/**
	 * 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
	 */
	public static Servlet createOrUpdateServletRef(WebApp webApp,
			IDataModel config, org.eclipse.jst.javaee.web.Servlet servlet) {
		
		String displayName = getDisplayName(config);		
		String className = getServletClassname(config);
		
		if (servlet == null){			
			// Create the servlet instance and set up the parameters from data
			// model
			servlet = WebFactory.eINSTANCE.createServlet();
			servlet.setServletName(displayName);
			servlet.setServletClass(className);
			servlet.setLoadOnStartup(Integer.valueOf(1));
			// Add the servlet to the web application model
			webApp.getServlets().add(servlet);

		} else {
			// update
			servlet.setServletName(displayName);
			servlet.setLoadOnStartup(Integer.valueOf(1));
		}
		return servlet;
	}

	/**
	 * @param webAppObj as Object
	 * @return true if webApp instanceof org.eclipse.jst.javaee.web.WebApp and WebAppVersionType._25
	 */
	public static boolean isWebApp25(Object webAppObj) {
		if (webAppObj instanceof WebApp &&
				((WebApp)webAppObj).getVersion() == WebAppVersionType._25_LITERAL) 
			return true;
		return false;
	}
	
	/**
	 * 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
	 */
	public static void setUpURLMappings(WebApp webApp, List urlMappingList,
			Servlet servlet) {
		
		if (urlMappingList.size() > 0) {
			ServletMapping mapping = findServletMapping(webApp, servlet);
			if (mapping == null){
				mapping = WebFactory.eINSTANCE.createServletMapping();
				mapping.setServletName(servlet.getServletName());
				webApp.getServletMappings().add(mapping);
			}
			// Add patterns
			Iterator it = urlMappingList.iterator();
			while (it.hasNext()) {
				String pattern = (String) it.next();
				if (!(doesServletMappingPatternExist(webApp, mapping, pattern))){
					UrlPatternType urlPattern = JavaeeFactory.eINSTANCE.createUrlPatternType();
					urlPattern.setValue(pattern);				
					mapping.getUrlPatterns().add(urlPattern);
				}
			}
		}
	}
	
	private static ServletMapping findServletMapping(final WebApp webApp, final Servlet servlet) {
		for (Iterator it=webApp.getServletMappings().iterator();it.hasNext();){
			ServletMapping mapping = (ServletMapping)it.next();
			if (mapping.getServletName().equals(servlet.getServletName()))
				return mapping;
		}
		return null;
	}

	private static boolean doesServletMappingPatternExist(final WebApp webApp, final ServletMapping mapping,
			final String pattern) {	
		for (Iterator it=mapping.getUrlPatterns().iterator();it.hasNext();){
			if(pattern.equals(((UrlPatternType)it.next()).getValue()))
				return true;
		}
		return false;
	}
	
	/**
	 * Removes servlet-mappings for servlet using servlet-name for >= 2.5 WebModules.
	 * @param webApp
	 * @param servlet
	 */
	public static void removeURLMappings(WebApp webApp, Servlet servlet) {
		List mappings = webApp.getServletMappings();					
		String servletName = servlet.getServletName();
		if (servletName != null) {
			for (int i=mappings.size()-1;i>=0;--i){
				ServletMapping mapping = (ServletMapping)mappings.get(i);
				if (mapping != null && 
						mapping.getServletName() != null && 
						mapping.getServletName()
						.equals(servletName)) {
					mappings.remove(mapping);
				}
			}
		}
	}
	
	/**
	 * Creates or updates config file context-param in v2.5 WebApp if non default configuration file is specified.
	 * @param webApp
	 * @param config
	 */
	public static void setupConfigFileContextParamForV2_5(org.eclipse.jst.javaee.web.WebApp webApp,
			IDataModel config) {
		// if not default name and location, then add context param
		ParamValue foundCP = null;
		ParamValue cp = null;
		boolean found = false;
		if (!config.getStringProperty(IJSFFacetInstallDataModelProperties.CONFIG_PATH).equals(JSF_DEFAULT_CONFIG_PATH)) {
			// check to see if present
			Iterator it = webApp.getContextParams().iterator();
			while (it.hasNext()) {
				cp = (org.eclipse.jst.javaee.core.ParamValue) it.next();
				if (cp != null && 
						cp.getParamName()!= null &&
						cp.getParamName().equals(JSF_CONFIG_CONTEXT_PARAM)) {
					foundCP = cp;
					found = true;
				}
			}
			if (!found) {
				ParamValue pv = JavaeeFactory.eINSTANCE.createParamValue();
				pv.setParamName(JSF_CONFIG_CONTEXT_PARAM);
				pv.setParamValue(config.getStringProperty(IJSFFacetInstallDataModelProperties.CONFIG_PATH));
				webApp.getContextParams().add(pv);
			} else {
				cp = foundCP;
				if (cp.getParamValue().indexOf(config.getStringProperty(IJSFFacetInstallDataModelProperties.CONFIG_PATH)) < 0) {
					String curVal = cp.getParamValue();
					String val = config.getStringProperty(IJSFFacetInstallDataModelProperties.CONFIG_PATH);
					if (curVal != null && !"".equals(curVal.trim())) { //$NON-NLS-1$
						val = curVal + ",\n" + val; //$NON-NLS-1$
					}
					cp.setParamValue(val);
				}
			}
		}
	}

	/**
	 * @param webApp
	 * @return the default file extension from the context param.  Default is "jsp" if no context param
	 */
	public static String getDefaultSuffix(WebApp webApp) {
		String defaultSuffix = "jsp"; //$NON-NLS-1$
		for (Iterator it = webApp.getContextParams().iterator();it.hasNext();) {		
			ParamValue cp = (ParamValue) it.next();		
			if (cp != null && 
					cp.getParamName() != null && 
					cp.getParamName().equals(JSF_DEFAULT_SUFFIX_CONTEXT_PARAM)){				
				String defSuffix = cp.getParamValue();
				if (defSuffix.startsWith(".")) //$NON-NLS-1$
					defSuffix = defSuffix.substring(1);
								
				return defSuffix;
			}
		}
		return defaultSuffix;
	}
	
	/**
	 * @param map
	 * @return prefix mapping 
	 */
	public static String getPrefixMapping(ServletMapping map) {
		List urls = map.getUrlPatterns();
		for (Iterator it=urls.iterator();it.hasNext();){
			IPath extPath = new Path(((UrlPatternType)it.next()).getValue());
			if (extPath != null){
				String ext = extPath.getFileExtension();
				if (ext == null){
					String lastSeg = extPath.lastSegment();
					if (lastSeg.equals("*")) //$NON-NLS-1$
					{
						return extPath.removeLastSegments(1).toString();
					}
					
					return extPath.toString();				
				}
			}
		}
		return null;
	}
	
	/**
	 * @param map
	 * @return extension from map.  Will return null if file extension not found in url patterns.
	 */
	public static String getFileExtensionFromMap(ServletMapping map) {
		List urls = map.getUrlPatterns();
		for (Iterator it=urls.iterator();it.hasNext();){
			IPath extPath = new Path(((UrlPatternType)it.next()).getValue());
			if (extPath != null){
				String ext = extPath.getFileExtension();
				if (ext != null && !ext.equals("")) //$NON-NLS-1$
					return ext;
			}
		}
		return null;
	}
}
