/*******************************************************************************
 * Copyright (c) 2003, 2007 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.jee.ui.internal.deployables;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.ITypeHierarchy;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jem.util.emf.workbench.ProjectUtilities;
import org.eclipse.jst.j2ee.internal.project.J2EEProjectUtilities;
import org.eclipse.jst.j2ee.internal.web.jfaces.extension.FileURL;
import org.eclipse.jst.j2ee.internal.web.jfaces.extension.FileURLExtensionReader;
import org.eclipse.jst.j2ee.model.IModelProvider;
import org.eclipse.jst.j2ee.model.ModelProviderManager;
import org.eclipse.jst.j2ee.project.JavaEEProjectUtilities;
import org.eclipse.jst.javaee.core.UrlPatternType;
import org.eclipse.jst.javaee.web.IWebCommon;
import org.eclipse.jst.javaee.web.Servlet;
import org.eclipse.jst.javaee.web.ServletMapping;
import org.eclipse.jst.javaee.web.internal.impl.ServletImpl;
import org.eclipse.jst.jee.ui.plugin.JEEUIPlugin;
import org.eclipse.wst.common.componentcore.ComponentCore;
import org.eclipse.wst.common.componentcore.resources.IVirtualComponent;
import org.eclipse.wst.common.componentcore.resources.IVirtualResource;
import org.eclipse.wst.common.internal.emfworkbench.WorkbenchResourceHelper;
import org.eclipse.wst.server.core.IModule;
import org.eclipse.wst.server.core.IModuleArtifact;
import org.eclipse.wst.server.core.ServerUtil;
import org.eclipse.wst.server.core.internal.ModuleType;
import org.eclipse.wst.server.core.util.WebResource;

/**
 * @version 1.0
 * @author
 */
public class WebDeployableArtifactUtil {
	
	private final static String GENERIC_SERVLET_CLASS_TYPE = "javax.servlet.GenericServlet"; //$NON-NLS-1$
	private final static String CACTUS_SERVLET_CLASS_TYPE = "org.apache.cactus.server.ServletTestRedirector"; //$NON-NLS-1$

	public WebDeployableArtifactUtil() {
		super();
	}

	public static IModuleArtifact getModuleObject(Object obj) {
		IResource resource = null;
		if (obj instanceof IResource)
			resource = (IResource) obj;
		if (obj instanceof IModuleArtifact)
			resource = ((IModuleArtifact) obj).getModule().getProject();
		else if (obj instanceof IAdaptable)
			resource = (IResource) ((IAdaptable) obj).getAdapter(IResource.class);
		else if (obj instanceof EObject) {
			resource = ProjectUtilities.getProject((EObject) obj);
			if (obj instanceof Servlet) {
				ServletImpl servlet = ((ServletImpl) obj);
				Resource servResource = servlet.eResource();
				IVirtualResource[] resources = null;
				try {
					IResource eclipeServResoruce = WorkbenchResourceHelper.getFile(servResource);
					resources = ComponentCore.createResources(eclipeServResoruce);
				} catch (Exception e) {
					JEEUIPlugin.logError(e);
				}
				IVirtualComponent component = null;
				if (resources != null && resources[0] != null){
					component = resources[0].getComponent();
				}
				String mapping = null;
				java.util.List mappings = getServletMappings(resource, servlet.getServletClass());

				if (mappings != null && !mappings.isEmpty()) {
					ServletMapping map = (ServletMapping) mappings.get(0);
					UrlPatternType urlPattern = map.getUrlPatterns().get(0);
					mapping = urlPattern.getValue();
				}
				if (mapping != null) {
					return new WebResource(getModule(resource.getProject(), component), new Path(mapping));
				}
				
//				WebType webType = ((Servlet) obj).getWebType();
//				if (webType.isJspType()) {
//					resource = ((IProject) resource).getFile(((JSPType) webType).getJspFile()); //$NON-NLS-1$
//				} else if (webType.isServletType()) {
//					return new WebResource(getModule(resource.getProject(), component), new Path("servlet/" + ((ServletType) webType).getClassName())); //$NON-NLS-1$
//				}
			}
		}
		if (resource == null)
			return null;

		if (resource instanceof IProject) {
			IProject project = (IProject) resource;
			if (hasInterestedComponents(project))
				return new WebResource(getModule(project, null), project.getProjectRelativePath());
		}
		
		if (!hasInterestedComponents(resource.getProject()))
            return null;
		if (isCactusJunitTest(resource))
			return null;

		IPath resourcePath = resource.getFullPath();
		IVirtualResource[] resources = ComponentCore.createResources(resource);
		IVirtualComponent component = null;
		if (resources.length <= 0 || resources[0] == null )
			return null;
		component = resources[0].getComponent();
		String className = getServletClassName(resource);
		if (className != null && component != null) {
			String mapping = getServletMapping(resource, true, className, component.getName());
			if (mapping != null) {
				return new WebResource(getModule(resource.getProject(), component), new Path(mapping));
			}
			// if there is no servlet mapping, provide direct access to the servlet
			// through the fully qualified class name
			return new WebResource(getModule(resource.getProject(), component), new Path("servlet/" + className)); //$NON-NLS-1$

		}
		if (className == null) {
//			WebArtifactEdit webEdit = null;
//			try {
//				webEdit = WebArtifactEdit.getWebArtifactEditForRead(component);
//				List servlets = webEdit.getWebApp().getServlets();
//				for (int i=0; i<servlets.size(); i++) {
//					Servlet servlet = (Servlet) servlets.get(i);
//					WebType type = servlet.getWebType();
//					if (type.isJspType()) {
//						JSPType jsp = (JSPType)type;
//						String jspPath = resource.getProjectRelativePath().removeFirstSegments(1).toString();
//						if (jsp.getJspFile().equals(jspPath)) {
//							List mappings = servlet.getMappings();
//							String mapping = null;
//							if (mappings != null && !mappings.isEmpty()) {
//								ServletMapping map = (ServletMapping) mappings.get(0);
//								mapping = map.getUrlPattern();
//								if (mapping != null) 
//									return new WebResource(getModule(resource.getProject(), component), new Path(mapping));
//							}
//						}
//					}
//				}
//			} finally {
//				if (webEdit != null)
//					webEdit.dispose();
//			}
		}
        resourcePath = resources[0].getRuntimePath();
        
		try {//adding try/catch to avoid future issues that would require commenting this out.
			// Extension read to get the correct URL for Java Server Faces file if
			// the jsp is of type jsfaces.
			FileURL jspURL = FileURLExtensionReader.getInstance().getFilesURL();
			if (jspURL != null) {
				IPath correctJSPPath = jspURL.getFileURL(resource, resourcePath);
				if (correctJSPPath != null && correctJSPPath.toString().length() > 0)
					return new WebResource(getModule(resource.getProject(), component), correctJSPPath);
			}
		}catch (Exception e) {}
		
		return new WebResource(getModule(resource.getProject(), component), resourcePath);
	}

	protected static IModule getModule(IProject project, IVirtualComponent component) {
		String componentName = null;
		if (component != null)
			componentName = component.getName();
		ModuleType[] moduleTypeArray = new ModuleType[]{
				ModuleType.getModuleType(J2EEProjectUtilities.DYNAMIC_WEB, null),
				ModuleType.getModuleType(J2EEProjectUtilities.WEBFRAGMENT, null)
		};
		IModule[] modules = ServerUtil.getModules(moduleTypeArray);
		for (IModule module : modules) {
			if ((project == null || project.equals(module.getProject()))
					&& (componentName == null || componentName.equals(module.getName())))
				return module;
				}
		
		// otherwise fall back to other types of web modules on the project
		if (project != null) {
			modules = ServerUtil.getModules(project);
			for (IModule module : modules) {
				if (componentName == null || componentName.equals(module.getName()))
					return module;
			}
		}
		return null;
	}

	/**
	 *  @deprecated - see getModule() for better logic for finding a project's IModule
	 */
	protected static IModule getModuleProject(IProject project, Iterator iterator) {
		IModule deployable = null;
		while (iterator.hasNext()) {
			Object next = iterator.next();
			if (next instanceof IModule) {
				deployable = (IModule) next;
				if (deployable.getProject().equals(project))
					return deployable;
			}
		}
		return null;
	}

	/**
	 * 
	 * Very temporary api - TODO - rip this out by 1.0
	 */
	private static boolean isCactusJunitTest(IResource resource) {
		return getClassNameForType(resource, CACTUS_SERVLET_CLASS_TYPE) != null;
	}



	private static IType[] getTypes(IJavaElement element) {
		try {
			if (element.getElementType() != IJavaElement.COMPILATION_UNIT)
				return null;

			return ((ICompilationUnit) element).getAllTypes();
		} catch (Exception e) {
			return null;
		}
	}

	public static String getServletClassName(IResource resource) {
		return getClassNameForType(resource, GENERIC_SERVLET_CLASS_TYPE);
	}

	public static String getClassNameForType(IResource resource, String superType) {
		if (resource == null)
			return null;

		try {
			IProject project = resource.getProject();
			IPath path = resource.getFullPath();
			if (!project.hasNature(JavaCore.NATURE_ID) || path == null)
				return null;

			IJavaProject javaProject = (IJavaProject) project.getNature(JavaCore.NATURE_ID);
			if (!javaProject.isOpen())
				javaProject.open(new NullProgressMonitor());

			// output location may not be on classpath
			IPath outputPath = javaProject.getOutputLocation();
			if (outputPath != null && "class".equals(path.getFileExtension()) && outputPath.isPrefixOf(path)) { //$NON-NLS-1$
				int count = outputPath.segmentCount();
				path = path.removeFirstSegments(count);
			}

			// remove initial part of classpath
			IClasspathEntry[] classPathEntry = javaProject.getResolvedClasspath(true);
			if (classPathEntry != null) {
				int size = classPathEntry.length;
				for (int i = 0; i < size; i++) {
					IPath classPath = classPathEntry[i].getPath();
					if (classPath.isPrefixOf(path)) {
						int count = classPath.segmentCount();
						path = path.removeFirstSegments(count);
						i += size;
					}
				}
			}

			// get java element
			IJavaElement javaElement = javaProject.findElement(path);

			IType[] types = getTypes(javaElement);
			if (types != null) {
				int size2 = types.length;
				for (int i = 0; i < size2; i++) {
					if (hasSuperclass(types[i], superType))
						return types[i].getFullyQualifiedName();
				}
			}
			return null;
		} catch (Exception e) {
			return null;
		}
	}

	public static boolean hasSuperclass(IType type, String superClassName) {
		try {
			ITypeHierarchy hierarchy = type.newSupertypeHierarchy(null);
			IType[] superClasses = hierarchy.getAllSuperclasses(type);

			int size = superClasses.length;
			for (int i = 0; i < size; i++) {
				if (superClassName.equals(superClasses[i].getFullyQualifiedName()))
					return true;
			}
			return false;
		} catch (Exception e) {
			return false;
		}
	}

	public static String getServletMapping(IResource resource, boolean isServlet, String typeName, String componentName) {
		if (typeName == null || typeName.equals("")) //$NON-NLS-1$
			return null;
		
		IModelProvider provider = ModelProviderManager.getModelProvider( resource.getProject() );
		Object mObj = provider.getModelObject();
		
		if ( mObj instanceof org.eclipse.jst.javaee.web.WebApp){
			org.eclipse.jst.javaee.web.WebApp webApp= (org.eclipse.jst.javaee.web.WebApp) mObj;
			List servlets = webApp.getServlets();
			// Ensure the display does not already exist in the web application
			if (servlets != null && !servlets.isEmpty()) {
				for (int i = 0; i < servlets.size(); i++) {
					org.eclipse.jst.javaee.web.Servlet servlet = (org.eclipse.jst.javaee.web.Servlet)servlets.get(i);
					if( servlet.getServletClass().equals(typeName)){
				
						java.util.List mappings = webApp.getServletMappings();
						if (mappings != null && !mappings.isEmpty()) {
							Iterator it = mappings.iterator();
							while( it.hasNext() ){
								org.eclipse.jst.javaee.web.ServletMapping map = (org.eclipse.jst.javaee.web.ServletMapping) it.next();
								if( map.getServletName().equals(servlet.getServletName())){
									org.eclipse.jst.javaee.core.UrlPatternType urlPattern = map.getUrlPatterns().get(0);
									return  urlPattern.getValue();
								}
							}

						}
					}
				
				}
			}

			
		}
		return null;

	}

	protected static boolean hasInterestedComponents(IProject project) {
		return (JavaEEProjectUtilities.isDynamicWebProject(project) ||
				JavaEEProjectUtilities.isWebFragmentProject(project));
	}

	private static List getServletMappings(IResource resource, String typeName){ 
		IModelProvider provider = ModelProviderManager.getModelProvider( resource.getProject() );
		IWebCommon webApp = (IWebCommon)provider.getModelObject();
		
		List servlets = webApp.getServlets();
		List list = new ArrayList();

		if (servlets != null && !servlets.isEmpty()) {
			for (int i = 0; i < servlets.size(); i++) {
				Servlet servlet = (Servlet)servlets.get(i);
				if( servlet.getServletClass().equals(typeName)){
			
					java.util.List mappings = webApp.getServletMappings();
					if (mappings != null && !mappings.isEmpty()) {
						Iterator it = mappings.iterator();
						while( it.hasNext() ){
							org.eclipse.jst.javaee.web.ServletMapping map = (org.eclipse.jst.javaee.web.ServletMapping) it.next();
							if( map.getServletName().equals(servlet.getServletName())){
								list.add(map);
							}
						}
					}
				}
			
			}
		}
		return list;
	}
}
