/*******************************************************************************
 * Copyright (c) 2003, 2005 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.internal.project;


import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jem.internal.plugin.JavaProjectInfo;
import org.eclipse.jst.j2ee.internal.plugin.IJ2EEModuleConstants;
import org.eclipse.wst.server.core.IRuntime;
import org.eclipse.jst.j2ee.internal.plugin.J2EEPlugin;

/**
 * This class stores the info required for creating a new J2EE project; not all info will apply to
 * all kinds of projects
 */
public class J2EEJavaProjectInfo extends JavaProjectInfo {
	protected static final String SRCROOT_VAR = "JRE_SRCROOT"; //$NON-NLS-1$
	protected IProject project;
	protected String jdkRTJarPath;
	protected String projectName;
	protected IPath projectLocation;
	protected String javaOutputPath;
	protected IClasspathEntry[] classpathEntries;
	protected boolean shouldInitializeDefaultClasspath = true;
	protected String natureId;
	protected IRuntime serverTarget;
	protected int moduleVersion;

	/**
	 * EJBProjectInfo constructor comment.
	 */
	public J2EEJavaProjectInfo() {
		super();
	}

	/**
	 * EJBProjectInfo constructor comment.
	 */
	public J2EEJavaProjectInfo(IProject project) {
		super();
		setProject(project);
	}

	public IClasspathEntry[] calculateServerClasspathEntries() throws JavaModelException {
		IJavaProject javaProject = getJavaProject();
		if (javaProject == null)
			return null;
		if (getProject().exists()) {
			//We don't need to remove a server target anyomre as it need to be there
			//ServerTargetManager.removeServerTarget(getProject(),null);
			IClasspathEntry[] ces = javaProject.getRawClasspath();
			if (ces.length > 0)
				addToClasspathEntries(ces);
		}
		addServerJdkRuntimeToClasspathEntries();
		addServerJarsToClasspathEntries();
		return classpathEntries;
	}

	/**
	 * Sets up the default classpath for this project
	 */
	protected void addDefaultToClasspathEntries() {
		addToClasspathEntries(computeDefaultJavaClasspath());
	}

	/**
	 * Set the corresponding jsp and servlet levels. Creation date: (11/09/00 10:05:24 AM)
	 */
	public void setJ2EEVersion(int newVersion) {
	}


	/**
	 * add the source folder to classpath dir (IClasspathEntry.CPE_SOURCE)
	 */
	public void addJavaSourceToClasspathEntries() {
		IPath sourceClassPath = new Path(getFullSourcePath());
		addToClasspathEntries(new IClasspathEntry[]{JavaCore.newSourceEntry(sourceClassPath)});
	}

	public boolean addJdkJarToClasspathEntries(String jdkJarFullPathName) {

		IJavaProject javaProject = getJavaProject();
		if (javaProject == null)
			return false;

		IClasspathEntry[] entry = new IClasspathEntry[1];
		Path path = new Path(jdkJarFullPathName);
		if (!path.toFile().exists()) {
			J2EEPlugin.logError(J2EECreationResourceHandler.getString(J2EECreationResourceHandler.JdkJarFileDoesNotExist_UI, new Object[]{jdkJarFullPathName})); 
			return false;
		}

		entry[0] = JavaCore.newLibraryEntry(path, null, null);
		addToClasspathEntries(entry);

		return true;
	}

	/**
	 * add rt.jar form the server.jdk plugin
	 */
	public void addServerJdkRuntimeToClasspathEntries() {
		addToClasspathEntries(getServerJDKClasspathEntries());
	}

	public IClasspathEntry[] getServerJDKClasspathEntries() {
		List list = new ArrayList(4);
		//TODO This class should be deleted.
		//		if (isJ2EE13()
		//			|| !org.eclipse.jst.j2ee.internal.internal.plugin.J2EEPlugin.hasDevelopmentRole()) {
		//			list.add(JavaCore.newVariableEntry(new
		// Path(IEJBNatureConstants.SERVERJDK_50_PLUGINDIR_VARIABLE + "/jre/lib/rt.jar"),
		// //$NON-NLS-1$
		//			new Path(IEJBNatureConstants.SERVERJDK_50_PLUGINDIR_VARIABLE + "/src.jar"), //$NON-NLS-1$
		//			new Path(IEJBNatureConstants.SERVERJDK_SRCROOT_VARIABLE))); //$NON-NLS-1$
		//		} else {
		//			list.add(JavaCore.newVariableEntry(new
		// Path(IEJBNatureConstants.SERVERJDK_PLUGINDIR_VARIABLE + "/jre/lib/rt.jar"), //$NON-NLS-1$
		//			new Path(IEJBNatureConstants.SERVERJDK_PLUGINDIR_VARIABLE + "/src.jar"), //$NON-NLS-1$
		//			new Path(IEJBNatureConstants.SERVERJDK_SRCROOT_VARIABLE))); //$NON-NLS-1$
		//		}
		return (IClasspathEntry[]) list.toArray(new IClasspathEntry[list.size()]);
	}

	/**
	 * Adds entries to the class path for this project
	 */
	public void addToClasspathEntries(IClasspathEntry[] entries) {

		java.util.List list = new ArrayList(10);
		// add the existing ones if any
		if (classpathEntries != null)
			list.addAll(Arrays.asList(classpathEntries));

		// add the new ones
		list.addAll(Arrays.asList(entries));

		// convert
		classpathEntries = new IClasspathEntry[list.size()];
		classpathEntries = (IClasspathEntry[]) list.toArray(classpathEntries);

	}

	public boolean addVariableJarToClasspathEntries(String fullPath) {

		IJavaProject javaProject = getJavaProject();
		if (javaProject == null)
			return false;

		IClasspathEntry[] entry = new IClasspathEntry[1];
		entry[0] = JavaCore.newVariableEntry(new Path(fullPath), null, null);
		addToClasspathEntries(entry);
		return true;
	}

	public boolean addVariableJarToClasspathEntriesWithAttachments(String fullPath, String srcPath, String srcRoot) {

		IJavaProject javaProject = getJavaProject();
		if (javaProject == null)
			return false;

		IClasspathEntry[] entry = new IClasspathEntry[1];
		entry[0] = JavaCore.newVariableEntry(new Path(fullPath), new Path(srcPath), new Path(srcRoot));
		addToClasspathEntries(entry);
		return true;
	}

	/**
	 * Return the default classpath for projects of this kind; subclasses should override for
	 * setting up new projects
	 */
	protected IClasspathEntry[] computeDefaultJavaClasspath() {
		IJavaProject javaProject = getJavaProject();
		if (javaProject == null)
			return null;
		addJavaSourceToClasspathEntries();
		if (serverTarget == null) {
			addServerJdkRuntimeToClasspathEntries();
			addServerJarsToClasspathEntries();
		}
		return classpathEntries;
	}

	/**
	 * Sublcasses have to overide this method to set the server jars
	 */
	public void addServerJarsToClasspathEntries() {

	}

	/**
	 * Creates a project handle with a specified path. The project resource should <b>not </b> be
	 * created concretely here;
	 */
	public IProject createProjectHandle(IPath projectPath) {
		return getWorkspace().getRoot().getProject(projectPath.segment(0));
	}

	public IClasspathEntry[] getClasspathEntries() {
		if (classpathEntries == null)
			initializeClasspathEntries();
		return classpathEntries;
	}

	/**
	 * Insert the method's description here. Creation date: (11/09/00 10:05:24 AM)
	 * 
	 * @return java.lang.String
	 */
	public java.lang.String getDefaultContextRoot() {
		return null;
	}

	/**
	 * Subclasses should override as necessary
	 */
	protected String getDefaultJavaOutputPath() {
		return DEFAULT_JAVA_OUTPUT_PATH;
	}

	/**
	 * Insert the method's description here. Creation date: (11/09/00 10:05:24 AM)
	 * 
	 * @return java.lang.String
	 */
	public java.lang.String getDefaultUri() {
		return projectName.replace(' ', '_') + IJ2EEModuleConstants.JAR_EXT;
	}

	/**
	 * Get the java output folder for the receiver, in the form of /project/ <output folder>
	 * 
	 * @return java.lang.String
	 */
	public String getFullJavaOutputPath() {
		return Path.ROOT.append(getProjectPath()).append(getJavaOutputPath()).toString();
	}

	/**
	 * Get the module path folder for the receiver in the form of /project/modulepath
	 * 
	 * @return java.lang.String
	 */
	protected String getFullSourcePath() {
		return Path.ROOT.append(getProjectPath()).append(getSourcePath()).toString();
	}

	/**
	 * Returns the project relative path of the java build destination
	 */
	public java.lang.String getJavaOutputPath() {
		if (javaOutputPath == null)
			javaOutputPath = getDefaultJavaOutputPath();
		return javaOutputPath;
	}

	/**
	 * @param i
	 */
	public void setModuleVersion(int version) {
		moduleVersion = version;
	}

	public IJavaProject getJavaProject() {
		// needed to get an IJavaProject to create classpaths from.
		IProject aProject = getProject();
		if (aProject == null)
			aProject = getWorkspace().getRoot().getProject(getProjectName());

		return JavaCore.create(aProject);
	}

	/**
	 * Return the absolute path of the default jdk rt.jar to use for this project
	 */
	public java.lang.String getJdkRTJarPath() {
		return jdkRTJarPath;
	}

	/**
	 * Return the project being created; checks the workspace for an existing project
	 */
	public IProject getProject() {
		if (project == null) {
			IProject aProject = getWorkspace().getRoot().getProject(getProjectName());
			if (aProject.exists())
				project = aProject;
		}
		return project;
	}

	/**
	 * Return the location of the project in the file system.
	 * 
	 * @return org.eclipse.core.runtime.IPath
	 */
	public IPath getProjectLocation() {
		return projectLocation;
	}

	/**
	 * Insert the method's description here. Creation date: (11/09/00 10:05:24 AM)
	 * 
	 * @return java.lang.String
	 */
	public java.lang.String getProjectName() {
		if (projectName == null && project != null)
			projectName = project.getName();
		return projectName;
	}

	public IPath getProjectPath() {
		return new Path(getProjectName());
	}

	public IWorkspace getWorkspace() {
		return org.eclipse.jst.j2ee.internal.plugin.J2EEPlugin.getWorkspace();
	}

	/**
	 * Lazy initialization - useGetClasspathEntries
	 */
	protected void initializeClasspathEntries() {
		if (shouldInitializeDefaultClasspath())
			computeDefaultJavaClasspath();
		else
			classpathEntries = new IClasspathEntry[0];
	}

	/**
	 * Answer false by default
	 * 
	 * @deprecated - Use getModuleVersion() with J2EEVersionConstants
	 */
	protected boolean isJ2EE13() {
		return false;
	}

	public IProject primGetProject() {
		return project;
	}

	public void removeClasspathEntry(IClasspathEntry entry) {
		if (entry == null)
			return;

		List list = new ArrayList(Arrays.asList(getClasspathEntries()));
		list.remove(entry);
		classpathEntries = (IClasspathEntry[]) list.toArray(new IClasspathEntry[list.size()]);
	}

	/**
	 * Insert the method's description here. Creation date: (11/10/00 10:09:58 AM)
	 * 
	 * @param newClassPathEntries
	 *            org.eclipse.jdt.core.api.IClasspathEntry
	 */
	public void setClasspathEntries(IClasspathEntry[] newClasspathEntries) {
		classpathEntries = newClasspathEntries;
	}

	public void setJavaOutputPath(String path) {
		javaOutputPath = path;
	}

	public void setJdkRTJarPath(String path) {
		jdkRTJarPath = path;
	}

	public void setProject(IProject aProject) {
		project = aProject;
	}

	/**
	 * Set the location in the file system that the project is to be created.
	 * 
	 * @param newProjectLocation
	 *            IPath
	 */
	public void setProjectLocation(IPath newProjectLocation) {
		projectLocation = newProjectLocation;
	}

	/**
	 * Insert the method's description here. Creation date: (11/09/00 10:05:24 AM)
	 * 
	 * @param newProjectName
	 *            java.lang.String
	 */
	public void setProjectName(java.lang.String newProjectName) {
		if (projectName != newProjectName)
			setClasspathEntries(null);
		projectName = newProjectName;
	}

	public void setShouldInitializeDefaultClasspath(boolean value) {
		shouldInitializeDefaultClasspath = value;
	}

	public boolean shouldInitializeDefaultClasspath() {
		return shouldInitializeDefaultClasspath;
	}

	/**
	 * Gets the natureId.
	 * 
	 * @return Returns a String
	 */
	public String getNatureId() {
		if (natureId == null)
			return getDefaultNatureId();
		return natureId;
	}

	/**
	 * returns the correct nature id string based on the J2EE spec level being used
	 */
	public String getDefaultNatureId() {
		return null;
	}

	/**
	 * Sets the natureId.
	 * 
	 * @param natureId
	 *            The natureId to set
	 */
	public void setNatureId(String natureId) {
		this.natureId = natureId;
	}

	/**
	 * Get the correct WAS classpath variable based on the J2EE version.
	 */
	protected String getWASPluginVariable() {
		//TODO This class needs to be deleted.
		//	if (isJ2EE13()
		//		|| !org.eclipse.jst.j2ee.internal.internal.plugin.J2EEPlugin.hasDevelopmentRole())
		//		return IEJBNatureConstants.WAS_50_PLUGINDIR_VARIABLE;
		//	else
		//		return IEJBNatureConstants.WAS_PLUGINDIR_VARIABLE;
		return ""; //$NON-NLS-1$
	}

	public int getModuleVersion() {
		return moduleVersion;
	}

	/**
	 * @return
	 */
	public IRuntime getServerTarget() {
		return serverTarget;
	}

	/**
	 * @param target
	 */
	public void setServerTarget(IRuntime target) {
		serverTarget = target;
	}
}
