/*******************************************************************************
 * Copyright (c) 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.j2ee.project;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.jem.util.emf.workbench.ProjectUtilities;
import org.eclipse.jst.j2ee.internal.J2EEConstants;
import org.eclipse.jst.j2ee.internal.J2EEVersionConstants;
import org.eclipse.jst.j2ee.internal.common.J2EEVersionUtil;
import org.eclipse.jst.j2ee.internal.componentcore.JavaEEBinaryComponentHelper;
import org.eclipse.jst.j2ee.internal.plugin.J2EEPlugin;
import org.eclipse.jst.j2ee.model.IEARModelProvider;
import org.eclipse.jst.j2ee.model.IModelProvider;
import org.eclipse.jst.j2ee.model.ModelProviderManager;
import org.eclipse.jst.j2ee.project.facet.IJ2EEFacetConstants;
import org.eclipse.jst.jee.util.internal.JavaEEQuickPeek;
import org.eclipse.wst.common.componentcore.ComponentCore;
import org.eclipse.wst.common.componentcore.internal.util.FacetedProjectUtilities;
import org.eclipse.wst.common.componentcore.internal.util.VirtualReferenceUtilities;
import org.eclipse.wst.common.componentcore.resources.IVirtualComponent;
import org.eclipse.wst.common.componentcore.resources.IVirtualFile;
import org.eclipse.wst.common.componentcore.resources.IVirtualReference;
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;

public class JavaEEProjectUtilities extends ProjectUtilities implements IJ2EEFacetConstants {
	protected static final IVirtualReference[] NO_REFERENCES = new IVirtualReference[0];
	public static final int FACET_VERSION = 0;
	public static final int DD_VERSION = 1;
	
	public JavaEEProjectUtilities() {
	}

	
	public static boolean isProjectOfType(IProject project, String typeID) {
		return getProjectFacetVersion(project, typeID) != null;
	}

	public static IProjectFacetVersion getProjectFacetVersion(IProject project, String typeID){
		return FacetedProjectUtilities.getProjectFacetVersion(project, typeID);
	}
	
	private static boolean isProjectOfType(IFacetedProject facetedProject, String typeID) {
		return FacetedProjectUtilities.isProjectOfType(facetedProject, typeID);
	}

	private static boolean isEARProject(IFacetedProject project) {
		return isProjectOfType(project, ENTERPRISE_APPLICATION);
	}

	private static boolean isDynamicWebProject(IFacetedProject project) {
		return isProjectOfType(project, DYNAMIC_WEB);
	}

	private static boolean isStaticWebProject(IFacetedProject project) {
		return isProjectOfType(project, STATIC_WEB);
	}

	private static boolean isEJBProject(IFacetedProject project) {
		return isProjectOfType(project, EJB);
	}

	private static boolean isJCAProject(IFacetedProject project) {
		return isProjectOfType(project, JCA);
	}

	private static boolean isApplicationClientProject(IFacetedProject project) {
		return isProjectOfType(project, APPLICATION_CLIENT);
	}

	private static boolean isUtilityProject(IFacetedProject project) {
		return isProjectOfType(project, UTILITY);
	}

	public static boolean isEARProject(IProject project) {
		return isProjectOfType(project, ENTERPRISE_APPLICATION);
	}
	
	public static boolean isDynamicWebComponent(IVirtualComponent component) {
		if (component.isBinary()) {
			return isBinaryType(component, JavaEEQuickPeek.WEB_TYPE);
		}
		return isProjectOfType(component.getProject(), DYNAMIC_WEB);
	}

	public static boolean isDynamicWebProject(IProject project) {
		return isProjectOfType(project, DYNAMIC_WEB);
	}
	
	public static boolean isWebFragmentProject(IProject project) {
		return isProjectOfType(project, WEBFRAGMENT);
	}
	
	public static boolean isWebFragmentProject(IFacetedProject project) {
		return isProjectOfType(project, WEBFRAGMENT);
	}
	
	public static boolean isWebFragmentProject(IVirtualComponent component) {
		if (component.isBinary()) {
			return isBinaryType(component, JavaEEQuickPeek.WEBFRAGMENT_TYPE);
		}
		return isProjectOfType(component.getProject(), WEBFRAGMENT);
	}

	public static boolean isStaticWebProject(IProject project) {
		return isProjectOfType(project, STATIC_WEB);
	}

	public static boolean isEJBComponent(IVirtualComponent component) {
		if (component.isBinary()) {
			return isBinaryType(component, JavaEEQuickPeek.EJB_TYPE);
		}
		return isProjectOfType(component.getProject(), EJB);
	}

	public static boolean isEJBProject(IProject project) {
		return isProjectOfType(project, EJB);
	}

	public static boolean isJCAComponent(IVirtualComponent component) {
		if (component.isBinary()) {
			return isBinaryType(component, JavaEEQuickPeek.CONNECTOR_TYPE);
		}
		return isProjectOfType(component.getProject(), JCA);
	}

	public static boolean isJCAProject(IProject project) {
		return isProjectOfType(project, JCA);
	}

	public static boolean isApplicationClientComponent(IVirtualComponent component) {
		if (component.isBinary()) {
			return isBinaryType(component, JavaEEQuickPeek.APPLICATION_CLIENT_TYPE);
		}
		return isProjectOfType(component.getProject(), APPLICATION_CLIENT);
	}

	public static boolean isApplicationClientProject(IProject project) {
		return isProjectOfType(project, APPLICATION_CLIENT);
	}

	public static boolean isUtilityProject(IProject project) {
		return isProjectOfType(project, UTILITY);
	}

	/**
	 * Return all projects in workspace of the specified type
	 * 
	 * @param type -
	 *            use one of the static strings on this class as a type
	 * @return IProject[]
	 */
	public static IProject[] getAllProjectsInWorkspaceOfType(String type) {
		IProject[] projects = ResourcesPlugin.getWorkspace().getRoot().getProjects();
		List result = new ArrayList();
		for (int i = 0; i < projects.length; i++) {
			if (isProjectOfType(projects[i], type))
				result.add(projects[i]);
		}
		return (IProject[]) result.toArray(new IProject[result.size()]);
	}

	private static boolean isBinaryType(IVirtualComponent aBinaryComponent, int quickPeekType){
		JavaEEQuickPeek qp = JavaEEBinaryComponentHelper.getJavaEEQuickPeek(aBinaryComponent);
		int type = qp.getType();
		return quickPeekType == type;
	}
	
	private static String convertQuickpeekResult(int type) {
		switch(type){
		case JavaEEQuickPeek.APPLICATION_CLIENT_TYPE:
			return APPLICATION_CLIENT;
		case JavaEEQuickPeek.WEB_TYPE:
			return DYNAMIC_WEB;
		case JavaEEQuickPeek.EJB_TYPE:
			return EJB;
		case JavaEEQuickPeek.CONNECTOR_TYPE:
			return JCA;
		case JavaEEQuickPeek.APPLICATION_TYPE:
			return ENTERPRISE_APPLICATION;
		case JavaEEQuickPeek.WEBFRAGMENT_TYPE:
			return WEBFRAGMENT;
		default:
			return UTILITY;
		}
	}
	public static String getJ2EEComponentType(IVirtualComponent component) {
		if (null != component) {
			if (component.isBinary()) {
				JavaEEQuickPeek qp = JavaEEBinaryComponentHelper.getJavaEEQuickPeek(component);
				return convertQuickpeekResult(qp.getType());
			}
			return getJ2EEProjectType(component.getProject());
		}
		return ""; //$NON-NLS-1$
	}
	public static String getJ2EEFileType(IPath path) {
		if( path != null && path.toFile().exists() && path.toFile().isFile()) {
			JavaEEQuickPeek qp = JavaEEBinaryComponentHelper.getJavaEEQuickPeek(path);
			return convertQuickpeekResult(qp.getType());
		}
		return null;
	}

	public static String getJ2EEProjectType(IProject project) {
		if (null != project && project.isAccessible()) {
			IFacetedProject facetedProject = null;
			try {
				facetedProject = ProjectFacetsManager.create(project);
			} catch (CoreException e) {
				return ""; //$NON-NLS-1$
			}
			if (isApplicationClientProject(facetedProject))
				return APPLICATION_CLIENT;
			else if (isDynamicWebProject(facetedProject))
				return DYNAMIC_WEB;
			else if (isEJBProject(facetedProject))
				return EJB;
			else if (isEARProject(facetedProject))
				return ENTERPRISE_APPLICATION;
			else if (isJCAProject(facetedProject))
				return JCA;
			else if (isStaticWebProject(facetedProject))
				return STATIC_WEB;
			else if (isUtilityProject(facetedProject))
				return UTILITY;
			else if (isWebFragmentProject(facetedProject))
				return WEBFRAGMENT;
		}
		return ""; //$NON-NLS-1$
	}
	
	
	/**
	 * Returns true if the Java EE Deployment Descriptor exists for the
	 * specified project.
	 * 
	 * @param virtualComponent
	 * @return
	 * @see #getDeploymentDescriptorQuickPeek(IProject)
	 */
	public static boolean deploymentDescriptorExists(IProject project) {
		IVirtualFile ddFile = getJavaEEDeploymentDescriptor(project);
		return ddFile != null;
	}

	/**
	 * Returns a JavaEEQuickPeek for the Java EE Deployment Descriptor for the
	 * specified project. If no Java EE Deployment Descriptor exists null will
	 * be returned.
	 * 
	 * @param project
	 * @return
	 * @see #deploymentDescriptorExists(IProject)
	 */
	public static JavaEEQuickPeek getDeploymentDescriptorQuickPeek(IProject project) {
		IVirtualFile ddFile = getJavaEEDeploymentDescriptor(project);
		if (ddFile == null) {
			return null;
		}
		InputStream in = null;
		try {
			in = ddFile.getUnderlyingFile().getContents();
			JavaEEQuickPeek quickPeek = new JavaEEQuickPeek(in);
			return quickPeek;
		} catch (CoreException e) {
			J2EEPlugin.logError(e);
		} finally {
			if (in != null) {
				try {
					in.close();
				} catch (IOException e) {
					J2EEPlugin.logError(e);
				}
			}
		}
		return null;
	}

	/**
	 * Returns an IVirtualFile for the Java EE Deployment Descriptor for the
	 * specified project if it exists. Returns null if there is no Java EE
	 * Deployment Descriptor
	 * 
	 * @param virtualComponent
	 * @return
	 */
	private static IVirtualFile getJavaEEDeploymentDescriptor(IProject project) {
		if (project == null) {
			throw new NullPointerException();
		}
		String ddURI = null;
		if (isEARProject(project)) {
			ddURI = J2EEConstants.APPLICATION_DD_URI;
		} else if (isEJBProject(project)) {
			ddURI = J2EEConstants.EJBJAR_DD_URI;
		} else if (isApplicationClientProject(project)) {
			ddURI = J2EEConstants.APP_CLIENT_DD_URI;
		} else if (isJCAProject(project)) {
			ddURI = J2EEConstants.RAR_DD_URI;
		} else if (isDynamicWebProject(project)) {
			ddURI = J2EEConstants.WEBAPP_DD_URI;
		} else {
			throw new IllegalArgumentException("Project:" + project.getName() + " is not a Java EE Project"); //$NON-NLS-1$//$NON-NLS-2$
		}

		IVirtualComponent comp = ComponentCore.createComponent(project);
		if (comp != null) {
			IVirtualFile vFile = comp.getRootFolder().getFile(new Path(ddURI));
			if (vFile.exists()) {
				return vFile;
			}
		}
		return null;
	}
	
	
	
	
	/**
	 * Returns the J2EE Module version based on the DD XML file
	 * @param project
	 * @return version String
	 */
	public static String getJ2EEDDProjectVersion(IProject project) {
		int type = J2EEVersionConstants.UNKNOWN;
		String ddURI = null;
		if (isEARProject(project)) {
			type = J2EEVersionConstants.APPLICATION_TYPE;
			ddURI = J2EEConstants.APPLICATION_DD_URI;
		} else if (isEJBProject(project)) {
			type = J2EEVersionConstants.EJB_TYPE;
			ddURI = J2EEConstants.EJBJAR_DD_URI;
		} else if (isApplicationClientProject(project)) {
			type = J2EEVersionConstants.APPLICATION_CLIENT_TYPE;
			ddURI = J2EEConstants.APP_CLIENT_DD_URI;
		} else if (isJCAProject(project)) {
			type = J2EEVersionConstants.CONNECTOR_TYPE;
			ddURI = J2EEConstants.RAR_DD_URI;
		} else if (isDynamicWebProject(project)) {
			type = J2EEVersionConstants.WEB_TYPE;
			ddURI = J2EEConstants.WEBAPP_DD_URI;
		} else if (isWebFragmentProject(project)) {
			type = J2EEVersionConstants.WEBFRAGMENT_TYPE;
			ddURI = J2EEConstants.WEBFRAGMENT_DD_URI;
		} 

		if(type != J2EEVersionConstants.UNKNOWN){
			IVirtualComponent comp = ComponentCore.createComponent(project);
			if (comp != null) {
				IVirtualFile vFile = comp.getRootFolder().getFile(new Path(ddURI));
				if(vFile.exists()){
					InputStream in= null;
					try{
						in = vFile.getUnderlyingFile().getContents();
						JavaEEQuickPeek quickPeek = new JavaEEQuickPeek(in);
						int vers = (quickPeek.getVersion() == J2EEVersionConstants.UNKNOWN) ? getLatestVersion(project) : quickPeek.getVersion();
						return J2EEVersionUtil.convertVersionIntToString(vers);
					} catch (CoreException e) {
						J2EEPlugin.logError(e);
					} finally {
						if(in != null){
							try {
								in.close();
							} catch (IOException e) {
								J2EEPlugin.logError(e);
							}
						}
					}
					
				}
				else
					return J2EEVersionUtil.convertVersionIntToString(getLatestVersion(project));
			}
		}
		
		return null;
	}


	private static int getLatestVersion(IProject project) {
		if (isEARProject(project) || isApplicationClientProject(project))
			return J2EEVersionConstants.VERSION_6_0;
		if (isEJBProject(project))
			return J2EEVersionConstants.VERSION_3_1;
		if (isDynamicWebProject(project))
			return J2EEVersionConstants.VERSION_3_0;
		if (isWebFragmentProject(project))
			return J2EEVersionConstants.VERSION_3_0;
		return J2EEVersionConstants.UNKNOWN;
			
	}

	public static int getJ2EEVersion(IProject javaEEProject)
	{
		int retVal = 0;
		return retVal;
	}
	
	/**
	 * Given a component returns whether the component has
	 * Java EE version greater than or equal to 5
	 * 
	 * @param component
	 * @return true if the component is Java EE version 5 or greater, false otherwise
	 * @throws NullPointerException if the component is null
	 */
	public static boolean isJEEComponent(IVirtualComponent component){
		if(component == null){
			throw new NullPointerException();
		}
		
		if(component.isBinary()){
			JavaEEQuickPeek qp = JavaEEBinaryComponentHelper.getJavaEEQuickPeek(component);
			int javaEEVersion = qp.getJavaEEVersion();
			return javaEEVersion >= J2EEConstants.JEE_5_0_ID;
		}
		IProject project = component.getProject();
		
		IProjectFacetVersion facetVersion = getProjectFacetVersion(project, ENTERPRISE_APPLICATION);
		if(facetVersion != null){
			if(facetVersion == IJ2EEFacetConstants.ENTERPRISE_APPLICATION_12 ||
			   facetVersion == IJ2EEFacetConstants.ENTERPRISE_APPLICATION_13 ||
			   facetVersion == IJ2EEFacetConstants.ENTERPRISE_APPLICATION_14){
				return false;
			}
			return true;
		}
		
		facetVersion = getProjectFacetVersion(project, APPLICATION_CLIENT);
		if(facetVersion != null){
			if(facetVersion == IJ2EEFacetConstants.APPLICATION_CLIENT_12 ||
			   facetVersion == IJ2EEFacetConstants.APPLICATION_CLIENT_13 ||
			   facetVersion == IJ2EEFacetConstants.APPLICATION_CLIENT_14){
				return false;
			}
			return true;
		}
		
		facetVersion = getProjectFacetVersion(project, EJB);
		if(facetVersion != null){
			if(facetVersion == IJ2EEFacetConstants.EJB_11 ||
			   facetVersion == IJ2EEFacetConstants.EJB_20 ||
			   facetVersion == IJ2EEFacetConstants.EJB_21){
				return false;
			}
			return true;
		}
		
		facetVersion = getProjectFacetVersion(project, DYNAMIC_WEB);
		if(facetVersion != null){
			if(facetVersion == IJ2EEFacetConstants.DYNAMIC_WEB_22 ||
			   facetVersion == IJ2EEFacetConstants.DYNAMIC_WEB_23 ||
			   facetVersion == IJ2EEFacetConstants.DYNAMIC_WEB_24){
				return false;
			}
			return true;
		}
		
		facetVersion = getProjectFacetVersion(project, JCA);
		if(facetVersion != null){
			if(facetVersion == IJ2EEFacetConstants.JCA_10 ||
			   facetVersion == IJ2EEFacetConstants.JCA_15 ){
				return false;
			}
			return true;
		}
		
		return false;
	}
	
	/**
	 * Given a component returns whether the component has
	 * Java EE version greater than or equal to 5
	 * 
	 * @param component   - IVirtualComponent
	 * @param versionType - flag to specify whether to use the facet version
	 *                      or the DD XML file version
	 * @return true if the component is Java EE version 5 or greater, false otherwise
	 */
	public static boolean isJEEComponent(IVirtualComponent component, int versionType){
		if (component.isBinary()) {
			JavaEEQuickPeek qp = JavaEEBinaryComponentHelper.getJavaEEQuickPeek(component);
			int javaEEVersion = qp.getJavaEEVersion();
			return javaEEVersion >= J2EEConstants.JEE_5_0_ID;
		} 
		
		IProject project = component.getProject();
		if (versionType == FACET_VERSION) {
			IProjectFacetVersion facetVersion = getProjectFacetVersion(project, ENTERPRISE_APPLICATION);
			if(facetVersion != null){
				if(facetVersion == IJ2EEFacetConstants.ENTERPRISE_APPLICATION_12 ||
				   facetVersion == IJ2EEFacetConstants.ENTERPRISE_APPLICATION_13 ||
				   facetVersion == IJ2EEFacetConstants.ENTERPRISE_APPLICATION_14){
					return false;
				}
				return true;
			}
			
			facetVersion = getProjectFacetVersion(project, APPLICATION_CLIENT);
			if(facetVersion != null){
				if(facetVersion == IJ2EEFacetConstants.APPLICATION_CLIENT_12 ||
				   facetVersion == IJ2EEFacetConstants.APPLICATION_CLIENT_13 ||
				   facetVersion == IJ2EEFacetConstants.APPLICATION_CLIENT_14){
					return false;
				}
				return true;
			}
			
			facetVersion = getProjectFacetVersion(project, EJB);
			if(facetVersion != null){
				if(facetVersion == IJ2EEFacetConstants.EJB_11 ||
				   facetVersion == IJ2EEFacetConstants.EJB_20 ||
				   facetVersion == IJ2EEFacetConstants.EJB_21){
					return false;
				}
				return true;
			}
			
			facetVersion = getProjectFacetVersion(project, DYNAMIC_WEB);
			if(facetVersion != null){
				if(facetVersion == IJ2EEFacetConstants.DYNAMIC_WEB_22 ||
				   facetVersion == IJ2EEFacetConstants.DYNAMIC_WEB_23 ||
				   facetVersion == IJ2EEFacetConstants.DYNAMIC_WEB_24){
					return false;
				}
				return true;
			}
			
			facetVersion = getProjectFacetVersion(project, JCA);
			if(facetVersion != null){
				if(facetVersion == IJ2EEFacetConstants.JCA_10 ||
				   facetVersion == IJ2EEFacetConstants.JCA_15 ){
					return false;
				}
				return true;
			}
			
			facetVersion = getProjectFacetVersion(project, WEBFRAGMENT);
			if(facetVersion != null){
				return true;
			}
			return false;
		}
		String ddVersion = getJ2EEDDProjectVersion(project);
		int j2eeLevel = 0;
		if (isEARProject(project))
			j2eeLevel = J2EEVersionUtil.convertVersionStringToInt(ddVersion);
		else if (isDynamicWebProject(project))
			j2eeLevel = J2EEVersionUtil.convertWebVersionStringToJ2EEVersionID(ddVersion);
		else if (isEJBProject(project))
			j2eeLevel = J2EEVersionUtil.convertEJBVersionStringToJ2EEVersionID(ddVersion);
		else if (isJCAProject(project))
			j2eeLevel = J2EEVersionUtil.convertConnectorVersionStringToJ2EEVersionID(ddVersion);
		else if (isApplicationClientProject(project))
			j2eeLevel = J2EEVersionUtil.convertAppClientVersionStringToJ2EEVersionID(ddVersion);
		else if (isWebFragmentProject(project))
			j2eeLevel = J2EEVersionUtil.convertWebFragmentVersionStringToJ2EEVersionID(ddVersion);
		return j2eeLevel >= J2EEVersionConstants.JEE_5_0_ID;
	}
	
	/**
	 * Given a component returns whether the component has Java EE version less than 5
	 * 
	 * @param component
	 * @return true if the component is less then Java EE version 5, false otherwise
	 */
	public static boolean isLegacyJ2EEComponent(IVirtualComponent component){
		return !isJEEComponent(component);
	}
	
	public static String getComponentURI(IVirtualComponent comp) {
		String name = null;
		//First find URI contained in EAR
		IProject[] earProjects = EarUtilities.getReferencingEARProjects(comp.getProject());
		if (earProjects.length > 0) {
			IModelProvider provider = ModelProviderManager.getModelProvider(earProjects[0]);
			if (provider instanceof IEARModelProvider)	{
				name = ((IEARModelProvider)provider).getModuleURI(comp);
			}
		}
		//If not found, then return the default name from the ModuleCore API
		if( name == null || name == "" ){ //$NON-NLS-1$ 
			return VirtualReferenceUtilities.INSTANCE.getDefaultProjectArchiveName(comp);
		}
		return name;
	}
	
}
