/**********************************************************************
 * 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.wst.server.core;

import java.util.*;

import org.eclipse.core.resources.*;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.debug.core.ILaunchConfiguration;

import org.eclipse.osgi.util.NLS;
import org.eclipse.wst.server.core.internal.*;
/**
 * Server utility methods. These static methods can be used to perform
 * common operations on server artifacts.
 * 
 * @since 1.0
 */
public class ServerUtil {
	/**
	 * Static utility class - cannot create an instance.
	 */
	private ServerUtil() {
		// do nothing
	}

	/**
	 * Returns the module contained within the given project. If more than one module
	 * is contained with the project, this method will return an arbitrary module
	 * unless the module factory defines an ordering. If there might be multiple
	 * modules in a project, users should typically use getModules(IProject) instead.
	 * 
	 * @param project a project
	 * @return a module that is contained with the project, or null if no
	 *    modules are contained in the given project
	 * @see #getModules(IProject)
	 */
	public static IModule getModule(IProject project) {
		if (project == null)
			throw new IllegalArgumentException();
		
		ModuleFactory[] factories = ServerPlugin.getModuleFactories();
		if (factories != null) {
			int size = factories.length;
			for (int i = 0; i < size; i++) {
				IModule[] modules = factories[i].getModules();
				if (modules != null) {
					int size2 = modules.length;
					for (int j = 0; j < size2; j++) {
						if (project.equals(modules[j].getProject()) && isSupportedModule(factories[i].getModuleTypes(), modules[j].getModuleType())) {
							return modules[j];
						}
					}
				}
			}
		}
		
		return null;
	}

	/**
	 * Returns the modules contained within the given project.
	 * 
	 * @param project a project
	 * @return a possibly-empty array of modules
	 * @see #getModule(IProject)
	 */
	public static IModule[] getModules(IProject project) {
		if (project == null)
			throw new IllegalArgumentException();
		
		IModule[] modules = getModules();
		List list = new ArrayList();
		if (modules != null) {
			int size = modules.length;
			for (int i = 0; i < size; i++) {
				if (modules[i] != null && project.equals(modules[i].getProject()))
					list.add(modules[i]);
			}
		}
		IModule[] modules2 = new IModule[list.size()];
		list.toArray(modules2);
		return modules2;
	}

	/**
	 * Returns a module from the given moduleId. The moduleId must not be null.
	 * 
	 * @param moduleId a module id
	 * @return the module, or <code>null</code> if the module could not be found
	 */
	public static IModule getModule(String moduleId) {
		if (moduleId == null)
			throw new IllegalArgumentException();
		
		int index = moduleId.indexOf(":");
		if (index <= 0)
			return null;
		
		String factoryId = moduleId.substring(0, index);
		ModuleFactory moduleFactory = ServerPlugin.findModuleFactory(factoryId);
		if (moduleFactory == null)
			return null;

		String moduleSubId = moduleId.substring(index+1);
		IModule module = moduleFactory.getModule(moduleSubId);
		if (module != null)
			return module;
		return null;
	}

	/**
	 * Return all the available modules from all factories whose
	 * type matches the given module types.
	 * 
	 * @param moduleTypes an array of module types
	 * @return a possibly empty array of modules
	 */
	public static IModule[] getModules(IModuleType[] moduleTypes) {
		List list = new ArrayList();

		ModuleFactory[] factories = ServerPlugin.getModuleFactories();
		if (factories != null) {
			int size = factories.length;
			for (int i = 0; i < size; i++) {
				if (isSupportedModule(factories[i].getModuleTypes(), moduleTypes)) {
					IModule[] modules = factories[i].getModules();
					if (modules != null) {
						int size2 = modules.length;
						for (int j = 0; j < size2; j++)
							list.add(modules[j]);
					}
				}
			}
		}
		IModule[] modules = new IModule[list.size()];
		list.toArray(modules);
		return modules;
	}

	/**
	 * Return all the available modules from all factories whose
	 * type matches the given module type id.
	 * 
	 * @param type a module type
	 * @return a possibly empty array of modules
	 */
	public static IModule[] getModules(String type) {
		List list = new ArrayList();

		ModuleFactory[] factories = ServerPlugin.getModuleFactories();
		if (factories != null) {
			int size = factories.length;
			for (int i = 0; i < size; i++) {
				if (isSupportedModule(factories[i].getModuleTypes(), type, null)) {
					IModule[] modules = factories[i].getModules();
					if (modules != null) {
						int size2 = modules.length;
						for (int j = 0; j < size2; j++)
							if(type.equals(modules[j].getModuleType().getId()))
								list.add(modules[j]);
					}
				}
			}
		}
		IModule[] modules = new IModule[list.size()];
		list.toArray(modules);
		return modules;
	}

	/**
	 * Returns <code>true</code> if any of the given moduleTypes have the given
	 * module type id and version id.
	 * 
	 * @param moduleTypes an array of module types
	 * @param typeId a module type id, or null for any module type
	 * @param versionId a module version, or null for any version
	 * @return <code>true</code> if the module type is supported, and
	 *    <code>false</code> otherwise
	 */
	public static boolean isSupportedModule(IModuleType[] moduleTypes, String typeId, String versionId) {
		if ("".equals(typeId))
			typeId = null;
		if ("".equals(versionId))
			versionId = null;
		
		if (moduleTypes != null) {
			int size = moduleTypes.length;
			for (int i = 0; i < size; i++) {
				if (isSupportedModule(moduleTypes[i], typeId, versionId))
					return true;
			}
		}
		return false;
	}

	private static boolean isSupportedModule(IModuleType[] moduleTypes, IModuleType[] mt) {
		if (mt != null) {
			int size = mt.length;
			for (int i = 0; i < size; i++) {
				if (isSupportedModule(moduleTypes, mt[i]))
					return true;
			}
		}
		return false;
	}

	/**
	 * Returns <code>true</code> if any of the given moduleTypes match the given
	 * module type.
	 * 
	 * @param moduleTypes an array of modules types
	 * @param mt a module type, may not be null
	 * @return <code>true</code> if the module type is supported, and
	 *    <code>false</code> otherwise
	 */
	public static boolean isSupportedModule(IModuleType[] moduleTypes, IModuleType mt) {
		if (mt == null)
			throw new IllegalArgumentException();
		
		if (moduleTypes != null) {
			int size = moduleTypes.length;
			for (int i = 0; i < size; i++) {
				if (isSupportedModule(moduleTypes[i], mt))
					return true;
			}
		}
		return false;
	}
	
	private static boolean isSupportedModule(IModuleType moduleType, String type, String version) {
		String type2 = moduleType.getId();
		if (matches(type, type2)) {
			String version2 = moduleType.getVersion();
			if (matches(version, version2))
				return true;
		}
		return false;
	}

	/**
	 * Returns true if the two given module types are compatible. The moduleTypes may not
	 * be null.
	 * 
	 * @param moduleType a module type
	 * @param mt a module type
	 * @return <code>true</code> if the module type is supported, and
	 *    <code>false</code> otherwise
	 */
	public static boolean isSupportedModule(IModuleType moduleType, IModuleType mt) {
		if (moduleType == null || mt == null)
			throw new IllegalArgumentException();
		
		String type2 = moduleType.getId();
		if (matches(mt.getId(), type2)) {
			String version2 = moduleType.getVersion();
			if (matches(mt.getVersion(), version2))
				return true;
		}
		return false;
	}

	private static boolean matches(String a, String b) {
		if (a == null || b == null || "*".equals(a) || "*".equals(b) || a.startsWith(b) || b.startsWith(a)
			|| (a.endsWith(".*") && b.startsWith(a.substring(0, a.length() - 1)))
			|| (b.endsWith(".*") && a.startsWith(b.substring(0, b.length() - 1))))
			return true;
		return false;
	}

	/**
	 * Return all the available modules from all factories.
	 * 
	 * @return a possibly empty array of modules
	 */
	private static IModule[] getModules() {
		Set set = new HashSet();
		
		ModuleFactory[] factories = ServerPlugin.getModuleFactories();
		if (factories != null) {
			int size = factories.length;
			for (int i = 0; i < size; i++) {
				IModule[] modules = factories[i].getModules();
				if (modules != null) {
					int size2 = modules.length;
					for (int j = 0; j < size2; j++) {
						if (!set.contains(modules[j])) {
							if (isSupportedModule(factories[i].getModuleTypes(), modules[j].getModuleType()))
								set.add(modules[j]);
							else
								Trace.trace(Trace.WARNING, "Invalid module returned from factory, ignored: " + modules[j]);
						}
					}
				}
			}
		}
		IModule[] modules = new IModule[set.size()];
		set.toArray(modules);
		return modules;
	}

	/**
	 * Adds or removes modules from a server. Will search for the first parent module
	 * of each module and add it to the server instead. This method will handle multiple
	 * modules having the same parent (the parent will only be added once), but may not
	 * handle the case where the same module or parent is being both added and removed.
	 * 
	 * @param server a server
	 * @param add an array of modules to add, or <code>null</code> to not add any
	 * @param remove an array of modules to remove, or <code>null</code> to not remove any
	 * @param monitor a progress monitor, or <code>null</code> if progress
	 *    reporting and cancellation are not desired
	 * @throws CoreException if anything goes wrong
	 */
	public static void modifyModules(IServerWorkingCopy server, IModule[] add, IModule[] remove, IProgressMonitor monitor) throws CoreException {
		if (server == null)
			throw new IllegalArgumentException();
		
		if (add == null)
			add = new IModule[0];
		if (remove == null)
			remove = new IModule[0];
		
		int size = add.length;
		List addParentModules = new ArrayList();
		for (int i = 0; i < size; i++) {
			boolean found = false;
			try {
				IModule[] parents = server.getRootModules(add[i], monitor);
				if (parents != null && parents.length > 0) {				
					Object parent = parents[0];
					found = true;
					if (!addParentModules.contains(parent))
						addParentModules.add(parent);
				}
			} catch (Exception e) {
				Trace.trace(Trace.WARNING, "Could not find parent module", e);
			}
			
			if (!found)
				addParentModules.add(add[i]);
		}
		
		size = remove.length;
		List removeParentModules = new ArrayList();
		for (int i = 0; i < size; i++) {
			boolean found = false;
			try {
				IModule[] parents = server.getRootModules(remove[i], monitor);
				if (parents != null && parents.length > 0) {				
					Object parent = parents[0];
					found = true;
					if (!removeParentModules.contains(parent))
						removeParentModules.add(parent);
				}
			} catch (Exception e) {
				Trace.trace(Trace.WARNING, "Could not find parent module 2", e);
			}
			
			if (!found)
				removeParentModules.add(remove[i]);
		}
		
		IModule[] add2 = new IModule[addParentModules.size()];
		addParentModules.toArray(add2);
		IModule[] remove2 = new IModule[removeParentModules.size()];
		removeParentModules.toArray(remove2);
		
		server.modifyModules(add2, remove2, monitor);
	}

	/**
	 * Sets a default name on the given runtime.
	 * 
	 * @param runtime a runtime
	 */
	public static void setRuntimeDefaultName(IRuntimeWorkingCopy runtime) {
		String typeName = runtime.getRuntimeType().getName();
		
		String name = NLS.bind(Messages.defaultRuntimeName, typeName);
		int i = 2;
		while (isNameInUse(name)) {
			name = NLS.bind(Messages.defaultRuntimeName2, new String[] {typeName, i + ""});
			i++;
		}
		runtime.setName(name);
	}

	/**
	 * Sets a default name on the given server.
	 * 
	 * @param server a server
	 */
	public static void setServerDefaultName(IServerWorkingCopy server) {
		if (server == null)
			throw new IllegalArgumentException();
		
		String typeName = server.getServerType().getName();
		String host = server.getHost();
		
		String name = NLS.bind(Messages.defaultServerName, new String[] {typeName, host});
		int i = 2;
		while (isNameInUse(name)) {
			name = NLS.bind(Messages.defaultServerName2, new String[] {typeName, host, i + ""});
			i++;
		}
		server.setName(name);
	}

	private static boolean isValidFilename(String name) {
		IStatus status = ResourcesPlugin.getWorkspace().validateName(name, IResource.FILE);
		if (status != null && !status.isOK())
			return false;
		
		status = ResourcesPlugin.getWorkspace().validateName(name, IResource.FOLDER);
		if (status != null && !status.isOK())
			return false;
		
		return true;
	}

	private static String getValidFileName(String name) {
		if (isValidFilename(name))
			return name;
	
		// remove invalid characters
		String[] s = new String[] {".", "\\", "/", "?", ":", "*", "\"", "|", "<", ">"};
		int ind = 0;
		while (ind < s.length) {
			int index = name.indexOf(s[ind]);
			while (index >= 0) {
				name = name.substring(0, index) + name.substring(index+1);
				index = name.indexOf(s[ind]);
			}
			ind++;
		}
		return name;
	}

	/**
	 * Returns an unused file in the given project.
	 * 
	 * @param project a project
	 * @param type a server type
	 * @return an unused file within the given project
	 */
	/*public static IFile getUnusedServerFile(IProject project, IServerType type) {
		if (project == null || type == null)
			throw new IllegalArgumentException();
		
		String typeName = getValidFileName(type.getName());
		String name = NLS.bind(Messages.defaultServerName3, typeName)+ "."  + Server.FILE_EXTENSION;
		int i = 2;
		while (isFileNameInUse(project, name)) {
			name = NLS.bind(Messages.defaultServerName4, new String[] {typeName, i + ""}) + "."  + Server.FILE_EXTENSION;
			i++;
		}
		return project.getFile(name);
	}*/

	/**
	 * Returns an unused file in the given project.
	 * 
	 * @param project a project
	 * @param server a server
	 * @return an unused file within the given project
	 */
	public static IFile getUnusedServerFile(IProject project, IServer server) {
		if (project == null || server == null)
			throw new IllegalArgumentException();
		
		String typeName = getValidFileName(server.getName());
		String name = NLS.bind(Messages.defaultServerName3, typeName)+ "."  + Server.FILE_EXTENSION;
		int i = 2;
		while (isFileNameInUse(project, name)) {
			name = NLS.bind(Messages.defaultServerName4, new String[] {typeName, i + ""}) + "."  + Server.FILE_EXTENSION;
			i++;
		}
		return project.getFile(name);
	}

	/**
	 * Returns true if a server or runtime exists with the given name.
	 *
	 * @param name a name
	 * @return <code>true</code> if the name is in use, and <code>false</code>
	 *    otherwise
	 */
	private static boolean isNameInUse(String name) {
		if (name == null)
			return true;
	
		List list = new ArrayList();
		
		addAll(list, ServerCore.getRuntimes());
		addAll(list, ServerCore.getServers());

		Iterator iterator = list.iterator();
		while (iterator.hasNext()) {
			Object obj = iterator.next();
			if (obj instanceof IServerAttributes && name.equalsIgnoreCase(((IServerAttributes)obj).getName()))
				return true;
			if (obj instanceof IRuntime && name.equalsIgnoreCase(((IRuntime)obj).getName()))
				return true;
		}

		return false;
	}
	
	private static void addAll(List list, Object[] obj) {
		if (obj == null)
			return;
		
		int size = obj.length;
		for (int i = 0; i < size; i++) {
			list.add(obj[i]);
		}
	}
	
	/**
	 * Returns true if an element exists with the given name.
	 *
	 * @param project a project
	 * @param name a file or folder name
	 * @return boolean <code>true</code> if the file or folder name is being
	 *    used, and <code>false</code> otherwise
	 */
	private static boolean isFileNameInUse(IProject project, String name) {
		if (name == null || project == null)
			return false;
		
		if (project.getFile(name).exists())
			return true;
		if (project.getFolder(name).exists())
			return true;
	
		return false;
	}

	/**
	 * Return a list of all runtime targets that match the given type and version.
	 * If type or version is null, it matches all of that type or version.
	 * 
	 * @param type a module type
	 * @param version a module version
	 * @return a possibly-empty array of runtime instances {@link IRuntime}
	 */
	public static IRuntime[] getRuntimes(String type, String version) {
		List list = new ArrayList();
		IRuntime[] runtimes = ServerCore.getRuntimes();
		if (runtimes != null) {
			int size = runtimes.length;
			for (int i = 0; i < size; i++) {
				IRuntimeType runtimeType = runtimes[i].getRuntimeType();
				if (runtimeType != null && isSupportedModule(runtimeType.getModuleTypes(), type, version)) {
					list.add(runtimes[i]);
				}
			}
		}
		
		IRuntime[] runtimes2 = new IRuntime[list.size()];
		list.toArray(runtimes2);
		return runtimes2;
	}

	/**
	 * Return a list of all runtime types that match the given type and version.
	 * If type or version is null, it matches all of that type or version.
	 * 
	 * @param type a module type
	 * @param version a module version
	 * @return a possibly-empty array of runtime type instances {@link IRuntimeType}
	 */
	public static IRuntimeType[] getRuntimeTypes(String type, String version) {
		List list = new ArrayList();
		IRuntimeType[] runtimeTypes = ServerCore.getRuntimeTypes();
		if (runtimeTypes != null) {
			int size = runtimeTypes.length;
			for (int i = 0; i < size; i++) {
				if (isSupportedModule(runtimeTypes[i].getModuleTypes(), type, version)) {
					list.add(runtimeTypes[i]);
				}
			}
		}
		
		IRuntimeType[] rt = new IRuntimeType[list.size()];
		list.toArray(rt);
		return rt;
	}
	
	/**
	 * Return a list of all runtime types that match the given type, version,
	 * and partial runtime type id. If type, version, or runtimeTypeId is null,
	 * it matches all of that type or version.
	 * 
	 * @param type a module type
	 * @param version a module version
	 * @param runtimeTypeId the id of a runtime type
	 * @return a possibly-empty array of runtime type instances {@link IRuntimeType}
	 */
	public static IRuntimeType[] getRuntimeTypes(String type, String version, String runtimeTypeId) {
		List list = new ArrayList();
		IRuntimeType[] runtimeTypes = ServerCore.getRuntimeTypes();
		if (runtimeTypes != null) {
			int size = runtimeTypes.length;
			for (int i = 0; i < size; i++) {
				if (isSupportedModule(runtimeTypes[i].getModuleTypes(), type, version)) {
					if (runtimeTypeId == null || runtimeTypes[i].getId().startsWith(runtimeTypeId))
						list.add(runtimeTypes[i]);
				}
			}
		}
		
		IRuntimeType[] rt = new IRuntimeType[list.size()];
		list.toArray(rt);
		return rt;
	}

	/**
	 * Returns a list of all servers that this deployable is not currently
	 * configured on, but could be added to. If includeErrors is true, this
	 * method return servers where the parent deployable may throw errors. For
	 * instance, this deployable may be the wrong spec level.
	 *
	 * @param module a module
	 * @param includeErrors <code>true</code> to include servers that returned
	 *    errors when trying to add the module, and <code>false</code> otherwise
	 * @param monitor a progress monitor, or <code>null</code> if progress
	 *    reporting and cancellation are not desired
	 * @return a possibly empty array of servers
	 */
	public static IServer[] getAvailableServersForModule(IModule module, boolean includeErrors, IProgressMonitor monitor) {
		if (module == null)
			return new IServer[0];

		// do it the slow way - go through all servers and
		// see if this deployable is not configured in it
		// but could be added
		List list = new ArrayList();
		IServer[] servers = ServerCore.getServers();
		if (servers != null) {
			int size = servers.length;
			for (int i = 0; i < size; i++) {
				if (!containsModule(servers[i], module, monitor)) {
					try {
						IModule[] parents = servers[i].getRootModules(module, monitor);
						if (parents != null && parents.length > 0) {
							boolean found = false;
							if (parents != null) {
								int size2 = parents.length;
								for (int j = 0; !found && j < size2; j++) {
									IModule parent = parents[j];
									IStatus status = servers[i].canModifyModules(new IModule[] { parent }, new IModule[0], monitor);
									if (status == null || status.isOK()){
										list.add(servers[i]);
										found = true;
									}
								}
							}
						}
					} catch (Exception se) {
						if (includeErrors)
							list.add(servers[i]);
					}
				}
			}
		}
		
		// make sure that the preferred server is the first one
		//IServer server = ServerCore.getServerPreferences().getDeployableServerPreference(deployable);
		//if (server != null && list.contains(server) && list.indexOf(server) != 0) {
		//	list.remove(server);
		//	list.add(0, server);
		//}

		IServer[] allServers = new IServer[list.size()];
		list.toArray(allServers);
		return allServers;
	}

	/**
	 * Returns a list of all servers that this module is configured on.
	 * 
	 * @param module a module
	 * @param monitor a progress monitor, or <code>null</code> if progress
	 *    reporting and cancellation are not desired
	 * @return a possibly-empty array of server instances {@link IServer}
	 */
	public static IServer[] getServersByModule(IModule module, IProgressMonitor monitor) {
		if (module == null)
			return new IServer[0];

		// do it the slow way - go through all servers and
		// see if this module is configured in it
		List list = new ArrayList();
		IServer[] servers = ServerCore.getServers();
		if (servers != null) {
			int size = servers.length;
			for (int i = 0; i < size; i++) {
				if (containsModule(servers[i], module, monitor))
					list.add(servers[i]);
			}
		}
		
		IServer[] allServers = new IServer[list.size()];
		list.toArray(allServers);
		return allServers;
	}

	/**
	 * Returns true if the given server currently contains the given module.
	 *
	 * @param server a server
	 * @param module a module
	 * @param monitor a progress monitor, or <code>null</code> if progress
	 *    reporting and cancellation are not desired
	 * @return boolean <code>true</code> if the module is contained on the server,
	 *    or <code>false</code> otherwise
	 */
	public static boolean containsModule(IServer server, final IModule module, IProgressMonitor monitor) {
		if (server == null)
			return false;
		Trace.trace(Trace.FINEST, "containsModule() " + server + " " + module);
		
		final boolean[] b = new boolean[1];
		
		((Server)server).visit(new IModuleVisitor() {
			public boolean visit(IModule[] modules) {
				int size = modules.length;
				if (modules[size - 1].equals(module)) {
					b[0] = true;
					return false;
				}
				return true;
			}
		}, null);
		return b[0];
	}

	/**
	 * Returns the server associated with the given launch configuration.
	 * 
	 * @param configuration a launch configuration
	 * @return the server associated with the launch configuration, or
	 *    <code>null</code> if no server could be found
	 * @throws CoreException if there is a problem getting the attribute from
	 *    the launch configuration
	 */
	public static IServer getServer(ILaunchConfiguration configuration) throws CoreException {
		String serverId = configuration.getAttribute(Server.ATTR_SERVER_ID, (String) null);

		if (serverId != null)
			return ServerCore.findServer(serverId);
		return null;
	}

	/**
	 * Validates whether this server can be editted.
	 * 
	 * @param context the context (Shell)
	 * @param server the server
	 * @return a status object with code <code>IStatus.OK</code> if the server
	 *   can be edited, otherwise a status object indicating what when wrong
	 *   with the checkout
	 */
	public static IStatus validateEdit(Object context, IServer server) {
		return ((Server)server).validateEdit(context);
	}

	/**
	 * Returns the port that is being used to monitor the given port on the server.
	 * This method can be used whenever creating a 'client' for the server, and allows
	 * the client to seamlessly use a monitored port instead of going directly to the
	 * server.
	 * 
	 * <b>Provisional API:</b> This class/interface is part of an interim API that is still under development and expected to 
	 * change significantly before reaching stability. It is being made available at this early stage to solicit feedback 
	 * from pioneering adopters on the understanding that any code that uses this API will almost certainly be broken 
	 * (repeatedly) as the API evolves.
	 * </p>
	 * 
	 * @param server a server
	 * @param port a port on the server
	 * @param contentType the content type, e.g. "web"
	 * @return the monitored port, or the original port number if the port is not
	 *    currently being monitored
	 */
	public static int getMonitoredPort(IServer server, int port, String contentType) {
		return ServerMonitorManager.getInstance().getMonitoredPort(server, port, contentType);
	}
}