/*******************************************************************************
 * 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.j2ee.internal.web.operations;

import java.util.Enumeration;
import java.util.Hashtable;
import java.util.List;
import java.util.Vector;

import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.SubProgressMonitor;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jem.workbench.utility.JemProjectUtilities;
import org.eclipse.jst.j2ee.internal.J2EEConstants;
import org.eclipse.jst.j2ee.internal.plugin.IJ2EEModuleConstants;
import org.eclipse.jst.j2ee.internal.project.ProjectSupportResourceHandler;
import org.eclipse.jst.j2ee.internal.web.plugin.WebPlugin;
import org.eclipse.wst.common.componentcore.ComponentCore;
import org.eclipse.wst.common.componentcore.resources.IVirtualComponent;
import org.eclipse.wst.common.componentcore.resources.IVirtualFolder;

import com.ibm.icu.util.StringTokenizer;

public class WebPropertiesUtil {
	// private static final char[] BAD_CHARS = {'/', '\\', ':'};
	private static final char[] BAD_CHARS = {':'};
	public static final String DEFAULT_JAVA_SOURCE_NAME = "Java Source"; //$NON-NLS-1$
	//TODO Port to flexible structure
	/**
	 * Update the Web Content folder to a new value if it is different. This applies to both Static
	 * and J2EE Web Projects. In the case of a J2EE Project, the library classpath entries will be
	 * modifies to reflect the new location.
	 * 
	 * @param project
	 *            The Web Project to update
	 * @param webContentName
	 *            The new name given to the Web Project's Web Content folder
	 * @param progressMonitor
	 *            Indicates progress of the update operation
	 * @return True if the web content rename was actually renamed, false if unneeded.
	 * @throws CoreException
	 *             The exception that occured during renaming of the the project's web content
	 *             folder
	 */
	public static boolean updateWebContentNameAndProperties(IProject project, String webContentName, IProgressMonitor progressMonitor) throws CoreException {
		boolean success = false;
		if (project.exists() && project.isOpen()) {

			/*
			 * IBaseWebNature webNature = J2EEWebNatureRuntimeUtilities.getRuntime(project); if
			 * (webContentName == null) { if (webNature.isStatic()) { webContentName =
			 * J2EEWebNatureRuntimeUtilities.getDefaultStaticWebContentName(); } else {
			 * webContentName = J2EEWebNatureRuntimeUtilities.getDefaultJ2EEWebContentName(); } }
			 */

			IPath newPath = new Path(webContentName);
			if (getModuleServerRoot(project).getProjectRelativePath().equals(newPath))
				return false;
			if (project.exists(newPath)) {
				IStatus status = new Status(IStatus.ERROR, "org.eclipse.jst.j2ee", IStatus.OK, ProjectSupportResourceHandler.getString(ProjectSupportResourceHandler.Could_not_rename_____2, new Object[]{webContentName}), null); //$NON-NLS-1$ 
				throw new CoreException(status);
			}

			moveWebContentFolder(project, webContentName, progressMonitor);
			updateWebContentNamePropertiesOnly(project, webContentName, progressMonitor);
			success = true;
		}
		return success;
	}

	/**
	 * Update the classpath entries and Server Root Name for this web project only.
	 * 
	 * @param project
	 * @param webContentName
	 * @return
	 */
	public static void updateWebContentNamePropertiesOnly(IProject project, String webContentName, IProgressMonitor progressMonitor) throws CoreException {
		IPath newPath = new Path(webContentName);
		if (getModuleServerRoot(project).equals(newPath))
			return;

		if (!getModuleServerRoot(project).equals(webContentName)) {

			// if (webModuleArtifact.isJ2EE) {
			// Update the library references
			IJavaProject javaProject = JemProjectUtilities.getJavaProject(project);

			IClasspathEntry[] classpath = javaProject.getRawClasspath();
			IClasspathEntry[] newClasspath = new IClasspathEntry[classpath.length];

			for (int i = 0; i < classpath.length; i++) {
				if (classpath[i].getEntryKind() == IClasspathEntry.CPE_LIBRARY) {
					IClasspathEntry library = classpath[i];
					IPath libpath = library.getPath();
					IPath modServerRootPath = getModuleServerRoot(project).getFullPath();
					if (modServerRootPath.isPrefixOf(libpath)) {
						IPath prunedPath = libpath.removeFirstSegments(modServerRootPath.segmentCount());
						IPath relWebContentPath = new Path(webContentName + "/" + prunedPath.toString()); //$NON-NLS-1$
						IResource absWebContentPath = project.getFile(relWebContentPath);

						IPath srcAttachmentPath = library.getSourceAttachmentPath();
						if (null != srcAttachmentPath) {
							prunedPath = srcAttachmentPath.removeFirstSegments(modServerRootPath.segmentCount());
						}
						IResource absWebContentSrcAttachmentPath = project.getFile(relWebContentPath);

						newClasspath[i] = JavaCore.newLibraryEntry(absWebContentPath.getFullPath(), absWebContentSrcAttachmentPath.getFullPath(), library.getSourceAttachmentRootPath(), library.isExported());

					} else {
						newClasspath[i] = classpath[i];
					}

				} else {
					newClasspath[i] = classpath[i];
				}
				// }

				// Set the java output folder
				IFolder outputFolder = project.getFolder(getModuleServerRoot(project).getFullPath());
				javaProject.setRawClasspath(newClasspath, outputFolder.getFullPath(), new SubProgressMonitor(progressMonitor, 1));
			}
			// update websettings
			// TODO add to WebArtifactEdit
			// webNature.setModuleServerRootName(webContentName);
		}
	}

	/**
	 * Moves the web content folder to the name indicated only if that path doesn't already exist in
	 * the project.
	 * 
	 * @param project
	 *            The web project to be updated.
	 * @param webContentName
	 *            The new web content name
	 * @param progressMonitor
	 *            Indicates progress
	 * @throws CoreException
	 *             The exception that occured during move operation
	 */
	public static void moveWebContentFolder(IProject project, String webContentName, IProgressMonitor progressMonitor) throws CoreException {
		IPath newPath = new Path(webContentName);
		if (!project.exists(newPath)) {
			if (newPath.segmentCount() > 1) {
				for (int i = newPath.segmentCount() - 1; i > 0; i--) {
					IPath tempPath = newPath.removeLastSegments(i);
					IFolder tempFolder = project.getFolder(tempPath);
					if (!tempFolder.exists()) {
						tempFolder.create(true, true, null);
					}
				}
			}
			newPath = project.getFullPath().append(newPath);
			IContainer webContentRoot = getModuleServerRoot(project);
			IPath oldPath = webContentRoot.getProjectRelativePath();
			webContentRoot.move(newPath, IResource.FORCE | IResource.KEEP_HISTORY, new SubProgressMonitor(progressMonitor, 1));
			for (int i = 0; i < oldPath.segmentCount(); i++) {
				IPath tempPath = oldPath.removeLastSegments(i);
				IFolder tempFolder = project.getFolder(tempPath);
				if (tempFolder.exists() && tempFolder.members().length == 0) {
					tempFolder.delete(true, true, null);
				}
			}
		}
	}

	/**
	 * Synchonizies the class path and the lib directories to catch any changes from the last use
	 * Creation date: (4/17/01 11:48:12 AM)
	 */
	protected static void synch(IProject project, IProgressMonitor monitor) {
		IProgressMonitor localMonitor = monitor;
		try {
			if (localMonitor == null) {
				localMonitor = new NullProgressMonitor();
			}
			localMonitor.beginTask(ProjectSupportResourceHandler.Sychronize_Class_Path_UI_, 4); 
			//$NON-NLS-1$ = "Sychronize Class Path"

			IContainer lib_folder = getWebLibFolder(project);
			// Nothing to do if the lib folder does not exist.
			if (lib_folder == null || !lib_folder.isAccessible())
				return;
			IJavaProject javaProject = JemProjectUtilities.getJavaProject(project);
			IPath lib_path = lib_folder.getProjectRelativePath();
			IPath lib_full_path = lib_folder.getFullPath();

			IClasspathEntry[] cp = javaProject.getRawClasspath();

			boolean needsToBeModified = false;
			// Create a map of the lib projects in the current project
			Hashtable lib_jars = new Hashtable();
			IResource[] children = lib_folder.members();
			localMonitor.subTask(ProjectSupportResourceHandler.Catalog_Lib_Directory__UI_); 
			//$NON-NLS-1$ = "Catalog Lib Directory:"
			for (int j = 0; j < children.length; j++) {
				IResource child = children[j];
				// monitor.setTaskName(ResourceHandler.getString("Catalog_Lib_Directory__UI_") +
				// child); //$NON-NLS-1$ = "Catalog Lib Directory:"
				// Make sure it is a zip or a jar file
				if (child.getType() == IResource.FILE && (child.getFullPath().toString().toLowerCase().endsWith(IJ2EEModuleConstants.JAR_EXT)
							|| child.getFullPath().toString().toLowerCase().endsWith(".zip"))) { //$NON-NLS-1$
					lib_jars.put(child.getFullPath(), child);
				}

			}

			localMonitor.worked(1);
			localMonitor.subTask(ProjectSupportResourceHandler.Update_ClassPath__UI_); 
			//$NON-NLS-1$ = "Update ClassPath:"
			// Loop through all the classpath dirs looking for ones that may have
			// been deleted
			Vector newClassPathVector = new Vector();
			for (int j = 0; j < cp.length; j++) {

				// If it is a lib_path
				if (cp[j].getPath().toString().startsWith(lib_path.toString()) || cp[j].getPath().toString().startsWith(lib_full_path.toString())) {
					// It was already in the class path
					if (lib_jars.get(cp[j].getPath()) != null) {
						newClassPathVector.add(cp[j]);
						// Remove it from the hash table of paths to add back
						// monitor.setTaskName(ResourceHandler.getString("Catalog_Lib_Directory__UI_")
						// + cp[j].getPath()); //$NON-NLS-1$ = "Catalog Lib Directory:"
						lib_jars.remove(cp[j].getPath());

					} else {
						// You have removed something form the class path you
						// will need to re-build
						// monitor.setTaskName(ResourceHandler.getString("Catalog_Lib_Directory_Remo_UI_")
						// + cp[j].getPath()); //$NON-NLS-1$ = "Catalog Lib Directory:Remove "
						needsToBeModified = true;
					}
				} else {
					localMonitor.subTask(ProjectSupportResourceHandler.Catalog_Lib_Directory__UI_ + cp[j].getPath()); 
					//$NON-NLS-1$ = "Catalog Lib Directory:"
					newClassPathVector.add(cp[j]);
				}
			}
			localMonitor.worked(1);
			localMonitor.subTask(ProjectSupportResourceHandler.Update_ClassPath__UI_); 
			//$NON-NLS-1$ = "Update ClassPath:"

			// Add any entries not already found
			Enumeration aenum = lib_jars.keys();
			while (aenum.hasMoreElements()) {
				IPath path = (IPath) aenum.nextElement();
				newClassPathVector.add(JavaCore.newLibraryEntry(path, null, null));
				// You have added something form the class path you
				// will need to re-build
				// monitor.setTaskName(ResourceHandler.getString("23concat_UI_", (new Object[] {
				// path }))); //$NON-NLS-1$ = "Catalog Lib Directory:Add {0}"
				needsToBeModified = true;
			}

			localMonitor.worked(1);
			localMonitor.subTask(ProjectSupportResourceHandler.Set_ClassPath__UI_); 
			//$NON-NLS-1$ = "Set ClassPath:"

			// Tansfer the vector to an array
			IClasspathEntry[] newClassPathArray = new IClasspathEntry[newClassPathVector.size()];

			for (int j = 0; j < newClassPathArray.length; j++) {
				newClassPathArray[j] = (IClasspathEntry) newClassPathVector.get(j);
			}

			// Only change the class path if there has been a modification
			if (needsToBeModified) {

				try {
					javaProject.setRawClasspath(newClassPathArray, localMonitor);
				} catch (Exception e) {
					WebPlugin.logError(e);
				}
			}

		} catch (ClassCastException ex) {
			WebPlugin.logError(ex);
		} catch (CoreException ex) {
			WebPlugin.logError(ex);
		} finally {
			localMonitor.done();
		}
	}

	public static void updateContextRoot(IProject project, String contextRoot) {
		
	}


	/**
	 * @param project
	 *            org.eclipse.core.resources.IProject
	 */
	/**
	 * Returns a error message that states whether a context root is valid or not returns null if
	 * context root is fine
	 * 
	 * @return java.lang.String
	 * @param contextRoot
	 *            java.lang.String
	 */
	public static String validateContextRoot(String contextRoot) {

		if (contextRoot == null)
			return null;

		String errorMessage = null;

		String name = contextRoot;
		if (name.equals("")) { //$NON-NLS-1$
			// this was added because the error message shouldnt be shown initially. It should be
			// shown only if context root field is edited to
			errorMessage = ProjectSupportResourceHandler.Context_Root_cannot_be_empty_2; 
			return errorMessage;
		}

		/*******************************************************************************************
		 * // JZ - fix to defect 204264, "/" is valid in context root if (name.indexOf("//") != -1) {
		 * //$NON-NLS-1$ errorMessage = "// are invalid characters in a resource name"; return
		 * errorMessage; }
		 ******************************************************************************************/

		if (name.trim().equals(name)) {
			StringTokenizer stok = new StringTokenizer(name, "."); //$NON-NLS-1$
			outer : while (stok.hasMoreTokens()) {
				String token = stok.nextToken();
				for (int i = 0; i < token.length(); i++) {
					if (!(token.charAt(i) == '_') && !(token.charAt(i) == '-') && !(token.charAt(i) == '/') && Character.isLetterOrDigit(token.charAt(i)) == false) {
						if (Character.isWhitespace(token.charAt(i))) {
							// Removed because context roots can contain white space
							// errorMessage =
							// ResourceHandler.getString("_Context_root_cannot_conta_UI_");//$NON-NLS-1$
							// = " Context root cannot contain whitespaces."
						} else {
							errorMessage = ProjectSupportResourceHandler.getString(ProjectSupportResourceHandler.The_character_is_invalid_in_a_context_root, new Object[]{(new Character(token.charAt(i))).toString()}); 
							break outer;
						}
					}
				}
			}
		} // en/ end of if(name.trim
		else
			errorMessage = ProjectSupportResourceHandler.Names_cannot_begin_or_end_with_whitespace_5; 

		return errorMessage;
	}


	/**
	 * Return true if the string contains any of the characters in the array.
	 */
	private static boolean contains(String str, char[] chars) {
		for (int i = 0; i < chars.length; i++) {
			if (str.indexOf(chars[i]) != -1)
				return true;
		}
		return false;
	}


	public static String validateFolderName(String folderName) {
		if (folderName.length() == 0)
			return ProjectSupportResourceHandler.Folder_name_cannot_be_empty_2; 

		if (contains(folderName, BAD_CHARS))
			return ProjectSupportResourceHandler.getString(ProjectSupportResourceHandler.Folder_name_is_not_valid, new Object[]{folderName}); 

		return null;
	}


	public static String validateWebContentName(String webContentName, IProject project, String javaSourceName) {

		String msg = validateFolderName(webContentName);
		if (msg != null)
			return msg;

		if (javaSourceName != null && webContentName.equals(javaSourceName))
			return ProjectSupportResourceHandler.Folder_names_cannot_be_equal_4; 

		// If given a java project, check to make sure current package fragment
		// root folders do not overlap with new web content name
		if (project != null) {
			IJavaProject javaProject = JemProjectUtilities.getJavaProject(project);
			if (javaProject != null) {
				try {
					IPackageFragmentRoot roots[] = javaProject.getPackageFragmentRoots();
					for (int i = 0; i < roots.length; i++) {
						IPackageFragmentRoot root = roots[i];
						if (!root.isArchive()) {
							IResource resource = root.getCorrespondingResource();
							if (resource.getType() == IResource.FOLDER) {
								IPath path = resource.getFullPath();
								String rootFolder = path.segment(1);
								if (webContentName.equals(rootFolder)) {
									if (root.getKind() == IPackageFragmentRoot.K_SOURCE)
										return ProjectSupportResourceHandler.Folder_name_cannot_be_the_same_as_Java_source_folder_5; 

									return ProjectSupportResourceHandler.Folder_name_cannot_be_the_same_as_Java_class_folder_6; 
								}
							}
						}
					}
				} catch (JavaModelException e) {
					return null;
				}
			}
		}

		return null;
	}


	/**
	 * Update given web nature to the current version if necessary.
	 * 
	 * @param webNature
	 *            The web Nature that should be examined.
	 * @return True if successful, false if unnecessary.
	 * @throws CoreException
	 *             The exception that occured during the version change operation.
	 */
	/*
	 * static public boolean updateNatureToCurrentVersion(J2EEWebNatureRuntime webNature) throws
	 * CoreException {
	 * 
	 * boolean success = false;
	 * 
	 * if (webNature.getVersion() != WEB.CURRENT_VERSION) {
	 * webNature.setVersion(J2EESettings.CURRENT_VERSION); success = true; }
	 * ((J2EEModuleWorkbenchURIConverterImpl)
	 * webNature.getResourceSet().getURIConverter()).recomputeContainersIfNecessary();
	 * 
	 * return success; }
	 */

	/**
	 * Move the old source folder to the new default folder.
	 * 
	 * @param project
	 *            The Web Project we are working with.
	 * @param oldSourceFolder
	 *            The old "Java Source" folder that will be moved.
	 * @param javaSourceName
	 *            The new name of the "Java Source" folder, or null for default.
	 * @return The location of the new folder, or null if no move was necessary.
	 * @throws CoreException
	 *             The exception that occured during the move operation.
	 */
	static public IContainer updateJavaSourceName(IProject project, IContainer oldSourceFolder, String javaSourceName, IProgressMonitor progressMonitor) throws CoreException {
		IContainer newSourceFolder = null;
		if (oldSourceFolder != null) {
			IPath newPath;
			if (javaSourceName == null)
				newPath = new Path(DEFAULT_JAVA_SOURCE_NAME);
			else
				newPath = new Path(javaSourceName);

			// Make sure new path is different form old path
			if (!project.getFolder(newPath).getFullPath().equals(oldSourceFolder.getFullPath())) {
				oldSourceFolder.move(newPath, IResource.FORCE | IResource.KEEP_HISTORY, new SubProgressMonitor(progressMonitor, 1));
				JemProjectUtilities.removeFromJavaClassPath(project, oldSourceFolder);
				newSourceFolder = project.getFolder(newPath);
				JemProjectUtilities.appendJavaClassPath(project, JavaCore.newSourceEntry(project.getFolder(newPath).getFullPath()));
			}
		}
		return newSourceFolder;
	}


	/**
	 * Get the source folder that should be used for migration.
	 * 
	 * @param project
	 *            The Web Project to examine.
	 * @return The source folder to use in migration, or null if it should be skipped.
	 */
	static public IContainer getJavaSourceFolder(IProject project) {
		List sourceRoots = JemProjectUtilities.getSourceContainers(project);
		IContainer oldSourceFolder = null;

		if (sourceRoots != null) {
			if (sourceRoots.size() == 1) {
				IContainer sourceFolder = (IContainer) sourceRoots.get(0);
				if (sourceFolder instanceof IFolder) {
					oldSourceFolder = sourceFolder;
				}
			}
		}
		return oldSourceFolder;
	}

	public static IFolder getModuleServerRoot(IProject project) {
		// TODO need to implement module server root properly
		IPath compRootPath = ComponentCore.createComponent(project).getRootFolder().getUnderlyingFolder().getProjectRelativePath();
		return project.getFolder(compRootPath);
		//return project.getFolder("WebContent");
		
	}

	public static IVirtualFolder getWebLibFolder(IVirtualComponent webComponent) {
		IPath path = new Path(J2EEConstants.WEB_INF + "/" + "lib");  //$NON-NLS-1$//$NON-NLS-2$
		IVirtualFolder libFolder = webComponent.getRootFolder().getFolder(path);
		return libFolder;
	}

	//TODO delete jsholl
	/**
	 * @deprecated use getWebLibFolder(IVirtualComponent webComponent)
	 * @param project
	 * @return
	 */
	public static IContainer getWebLibFolder(IProject project) {
		return getWebLibFolder(ComponentCore.createComponent(project)).getUnderlyingFolder();
	}

	//	
	// static public boolean isImportedClassesJARFileInLibDir(IResource resource) {
	// if (resource == null || !resource.exists())
	// return false;
	// return resource.getType() == resource.FILE &&
	// resource.getName().endsWith(IWebNatureConstants.IMPORTED_CLASSES_SUFFIX) && isZip(resource);
	// }
	//	
	// static public boolean isLibDirJARFile(IResource resource) {
	// if (resource == null || !resource.exists())
	// return false;
	// return resource.getType() == resource.FILE && isZip(resource);
	// }
	//	
	// static public boolean isZip(IResource resource) {
	// String path = resource.getLocation().toOSString();
	// ZipFile zip = null;
	//
	// try {
	// zip = new ZipFile(path);
	// } catch (IOException notAZip) {
	// return false;
	// } finally {
	// if (zip != null) {
	// try {
	// zip.close();
	// } catch (IOException ex) {}
	// }
	// }
	// return zip != null;
	// }


}
