/*******************************************************************************
 * Copyright (c) 2003, 2011 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.server.tomcat.core.internal;

import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.*;
import org.eclipse.jst.server.core.IWebModule;
import org.eclipse.osgi.util.NLS;

import org.eclipse.wst.server.core.IModule;
import org.eclipse.wst.server.core.ServerPort;
/**
 * Generic Tomcat server configuration.
 */
public abstract class TomcatConfiguration implements ITomcatConfiguration, ITomcatConfigurationWorkingCopy {
	public static final String NAME_PROPERTY = "name";
	public static final String PORT_PROPERTY = "port";
	public static final String MODIFY_PORT_PROPERTY = "modifyPort";
	public static final String ADD_MAPPING_PROPERTY = "addMapping";
	public static final String REMOVE_MAPPING_PROPERTY = "removeMapping";
	public static final String MODIFY_MAPPING_PROPERTY = "modifyMapping";
	
	public static final String MODIFY_WEB_MODULE_PROPERTY = "modifyWebModule";
	public static final String ADD_WEB_MODULE_PROPERTY = "addWebModule";
	public static final String REMOVE_WEB_MODULE_PROPERTY = "removeWebModule";
	
	protected IFolder configPath;

	// property change listeners
	private transient List<PropertyChangeListener> propertyListeners;

	/**
	 * TomcatConfiguration constructor.
	 * 
	 * @param path a path
	 */
	public TomcatConfiguration(IFolder path) {
		super();
		this.configPath = path;
		/*try {
			load(configPath, new NullProgressMonitor());
		} catch (Exception e) {
			// ignore
		}*/
	}
	
	protected IFolder getFolder() {
		return configPath;
	}

	/**
	 * Copies all files from the given directory in the workbench
	 * to the given location.  Can be overridden by version specific
	 * class to modify or enhance what publish does.
	 * 
	 * @param tomcatDir Destination tomcat directory.  Equivalent to catalina.base
	 *                  for Tomcat 4.x and up.
	 * @param doBackup Backup existing configuration files (true if not test mode).
	 * @param monitor Progress monitor to use
	 * @return result of operation
	 */
	protected IStatus backupAndPublish(IPath tomcatDir, boolean doBackup, IProgressMonitor monitor) {
		MultiStatus ms = new MultiStatus(TomcatPlugin.PLUGIN_ID, 0, Messages.publishConfigurationTask, null);
		if (Trace.isTraceEnabled())
			Trace.trace(Trace.FINER, "Backup and publish");
		monitor = ProgressUtil.getMonitorFor(monitor);

		try {
			IPath backup = null;
			if (doBackup) {
				// create backup directory
				backup = tomcatDir.append("backup");
				if (!backup.toFile().exists())
					backup.toFile().mkdir();
			}
			backupFolder(getFolder(), tomcatDir.append("conf"), backup, ms, monitor);
		} catch (Exception e) {
			Trace.trace(Trace.SEVERE, "backupAndPublish() error", e);
			IStatus s = new Status(IStatus.ERROR, TomcatPlugin.PLUGIN_ID, 0, NLS.bind(Messages.errorPublishConfiguration, new String[] {e.getLocalizedMessage()}), e);
			ms.add(s);
		}

		monitor.done();
		return ms;
	}
	
	protected void backupFolder(IFolder folder, IPath confDir, IPath backup, MultiStatus ms, IProgressMonitor monitor) throws CoreException {
		IResource[] children = folder.members();
		if (children == null)
			return;
		
		int size = children.length;
		monitor.beginTask(Messages.publishConfigurationTask, size * 100);
		for (int i = 0; i < size; i++) {
			if (children[i] instanceof IFile) {
				try {
					IFile file = (IFile) children[i];
					String name = file.getName();
					monitor.subTask(NLS.bind(Messages.publisherPublishTask, new String[] {name}));
					if (Trace.isTraceEnabled())
						Trace.trace(Trace.FINEST, "Publishing " + name);

					// backup and copy file
					boolean copy = true;
					if (backup != null && !(backup.append(name).toFile().exists())) {
						IStatus status = FileUtil.copyFile(confDir.append(name).toOSString(), backup + File.separator + name);
						ms.add(status);
						if (!status.isOK())
							copy = false;
					}
					
					if (copy) {
						String destPath = confDir.append(name).toOSString();
						String destContents = null;
						String srcContents = null;
						File dest = new File(destPath);
						if (dest.exists()) {
							InputStream fis = new FileInputStream(destPath);
							destContents = TomcatVersionHelper.getFileContents(fis);
							if (destContents != null) {
								fis = file.getContents();
								srcContents = TomcatVersionHelper.getFileContents(fis);
							}
						}
						if (destContents == null || srcContents == null || !srcContents.equals(destContents)) {
							InputStream in = file.getContents();
							ms.add(FileUtil.copyFile(in, destPath));
						}
					}
				} catch (Exception e) {
					Trace.trace(Trace.SEVERE, "backupAndPublish() error", e);
					ms.add(new Status(IStatus.ERROR, TomcatPlugin.PLUGIN_ID, 0, NLS.bind(Messages.errorPublishConfiguration, new String[] {e.getLocalizedMessage()}), e));
				}
			}
			monitor.worked(100);
		}
	}
	
	protected void backupPath(IPath path, IPath confDir, IPath backup, MultiStatus ms, IProgressMonitor monitor) {
		File[] files = path.toFile().listFiles();
		if (files == null)
			return;
			
		int size = files.length;
		monitor.beginTask(Messages.publishConfigurationTask, size * 100);
		for (int i = 0; i < size; i++) {
			try {
				File file = files[i];
				String name = file.getName();
				monitor.subTask(NLS.bind(Messages.publisherPublishTask, new String[] {name}));
				if (Trace.isTraceEnabled())
					Trace.trace(Trace.FINEST, "Publishing " + name);

				// backup and copy file
				boolean copy = true;
				if (backup != null && !(backup.append(name).toFile().exists())) {
					IStatus status = FileUtil.copyFile(confDir.append(name).toOSString(), backup + File.separator + name);
					ms.add(status);
					if (!status.isOK())
						copy = false;
				}
				
				if (copy)
					ms.add(FileUtil.copyFile(file.getAbsolutePath(), confDir.append(name).toOSString()));
			} catch (Exception e) {
				Trace.trace(Trace.SEVERE, "backupAndPublish() error", e);
				ms.add(new Status(IStatus.ERROR, TomcatPlugin.PLUGIN_ID, 0, NLS.bind(Messages.errorPublishConfiguration, new String[] {e.getLocalizedMessage()}), e));
			}
			monitor.worked(100);
		}
	}
	
	protected IStatus publishContextConfig(IPath baseDir, IPath deployDir, IProgressMonitor monitor) {
		// Default implementation assumes nothing to do
		return Status.OK_STATUS;
	}

	
	protected IStatus updateContextsToServeDirectly(IPath baseDir, String tomcatVersion, String loader, IProgressMonitor monitor) {
		// Default implementation assumes nothing to do
		return Status.OK_STATUS;
	}
	
	protected IStatus cleanupServer(IPath confDir, IPath installDir, boolean removeKeptContextFiles, IProgressMonitor monitor) {
		// Default implementation assumes nothing to clean
		return Status.OK_STATUS;
	}
	
	/**
	 * Make any local changes to the server configuration at the specified runtime
	 * base directory needed to complete publishing the server.
	 * 
	 * @param baseDir runtime base directory for the server
	 * @param deployDir deployment directory for the server
	 * @param server server being localized
	 * @param monitor a progress monitor
	 * @return result of operation
	 */
	public abstract IStatus localizeConfiguration(IPath baseDir, IPath deployDir, TomcatServer server, IProgressMonitor monitor);

	/**
	 * Returns the main server port.
	 * @return ServerPort
	 */
	public abstract ServerPort getMainPort();

	/**
	 * Returns the prefix that is used in front of the
	 * web module path property. (e.g. "webapps")
	 *
	 * @return java.lang.String
	 */
	public String getDocBasePrefix() {
		return "";
	}

	/**
	 * Returns the partial URL applicable to this module.
	 * 
	 * @param webModule a web module
	 * @return the partial URL
	 */
	protected String getWebModuleURL(IModule webModule) {
		WebModule module = getWebModule(webModule);
		if (module != null)
			return module.getPath();
		
		IWebModule webModule2 = (IWebModule) webModule.loadAdapter(IWebModule.class, null);
		return "/" + webModule2.getContextRoot();
	}

	/**
	 * Returns the given module from the config.
	 *
	 * @param module a web module
	 * @return a web module
	 */
	public WebModule getWebModule(IModule module) {
		if (module == null)
			return null;
	
		String memento = module.getId();
	
		List modules = getWebModules();
		int size = modules.size();
		for (int i = 0; i < size; i++) {
			WebModule webModule = (WebModule) modules.get(i);
			if (memento.equals(webModule.getMemento())) {
				return webModule;
			}
		}
		return null;
	}

	protected abstract void save(IFolder folder, IProgressMonitor monitor) throws CoreException;

	protected void firePropertyChangeEvent(String propertyName, Object oldValue, Object newValue) {
		if (propertyListeners == null)
			return;
	
		PropertyChangeEvent event = new PropertyChangeEvent(this, propertyName, oldValue, newValue);
		try {
			Iterator iterator = propertyListeners.iterator();
			while (iterator.hasNext()) {
				try {
					PropertyChangeListener listener = (PropertyChangeListener) iterator.next();
					listener.propertyChange(event);
				} catch (Exception e) {
					Trace.trace(Trace.SEVERE, "Error firing property change event", e);
				}
			}
		} catch (Exception e) {
			Trace.trace(Trace.SEVERE, "Error in property event", e);
		}
	}

	/**
	 * Adds a property change listener to this server.
	 *
	 * @param listener java.beans.PropertyChangeListener
	 */
	public void addPropertyChangeListener(PropertyChangeListener listener) {
		if (propertyListeners == null)
			propertyListeners = new ArrayList<PropertyChangeListener>();
		propertyListeners.add(listener);
	}

	/**
	 * Removes a property change listener from this server.
	 *
	 * @param listener java.beans.PropertyChangeListener
	 */
	public void removePropertyChangeListener(PropertyChangeListener listener) {
		if (propertyListeners != null)
			propertyListeners.remove(listener);
	}

	public void importFromPath(IPath path, boolean isTestEnv, IProgressMonitor monitor) throws CoreException {
		load(path, monitor);
	}

	/*public void importFromRuntime(IRuntime runtime, IProgressMonitor monitor) throws CoreException {
		load(runtime.getLocation().append("conf"), monitor);
	}*/
	
	protected abstract void load(IPath path, IProgressMonitor monitor) throws CoreException;
	
	protected abstract void load(IFolder folder, IProgressMonitor monitor) throws CoreException;
	
	/**
	 * @see ITomcatConfigurationWorkingCopy#addWebModule(int, ITomcatWebModule)
	 */
	public abstract void addWebModule(int index, ITomcatWebModule module);
	
	/**
	 * @see ITomcatConfigurationWorkingCopy#removeWebModule(int)
	 */
	public abstract void removeWebModule(int index);

	/**
	 * Gets the work directory for the server.
	 * 
	 * @param basePath path to server runtime directory
	 * @return path for the server's work directory
	 */
	public abstract IPath getServerWorkDirectory(IPath basePath);

	/**
	 * Gets the work directory for the specified module on the
	 * server.
	 * 
	 * @param basePath path to server runtime directory
	 * @param module a Tomcat web module
	 * @return path for the module's work directory on the server
	 */
	public abstract IPath getContextWorkDirectory(IPath basePath, ITomcatWebModule module);

	/**
	 * Return a string representation of this object.
	 * @return java.lang.String
	 */
	public String toString() {
		return "TomcatConfiguration[" + getFolder() + "]";
	}
}
