/*******************************************************************************
 * Copyright (c) 2007, 2008 SAS Institute, Inc. 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:
 *     Larry Isaacs - Initial API and implementation
 *******************************************************************************/
package org.eclipse.jst.server.tomcat.ui.internal;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.MultiStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.IJobChangeEvent;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.core.runtime.jobs.JobChangeAdapter;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jst.server.core.IWebModule;
import org.eclipse.jst.server.tomcat.core.internal.ITomcatWebModule;
import org.eclipse.jst.server.tomcat.core.internal.TomcatServerBehaviour;
import org.eclipse.jst.server.tomcat.core.internal.WebModule;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.PlatformUI;
import org.eclipse.wst.server.core.IModule;
import org.eclipse.wst.server.core.IServer;
import org.eclipse.wst.server.core.ServerUtil;
import org.eclipse.wst.server.core.IServer.IOperationListener;

/**
 * Dialog to confirm deletion of the work directory for a module on a
 * server, or the work directory for the entire server.  Handling
 * includes stopping and restarting the server if it is running at
 * the time of the deletion. 
 *
 */
public class CleanWorkDirDialog extends Dialog {
	protected IServer server;
	protected IModule module;
	protected int state;
	protected String mode;
	protected IStatus completionStatus;
	
	/**
	 * Creates a dialog instance confirm deletion of the work directory for a
	 * module on a server, or the work directory for the entire server.
	 * 
	 * @param parentShell the parent shell, or <code>null</code> to create a
	 *  top-level shell
	 * @param server server on which to delete the work directory
	 * @param module module whose work directory is to be deleted, or <code>null</code> if
	 *  if these server's entire work directory is to be deleted.
	 */
	public CleanWorkDirDialog(Shell parentShell, IServer server, IModule module) {
		super(parentShell);
		
		if (server == null)
			throw new IllegalArgumentException();

		this.server = server;
		this.module = module;
		
	}
	
	protected void configureShell(Shell newShell) {
		super.configureShell(newShell);
		newShell.setText(Messages.confirmCleanWorkDirTitle);
	}

	protected Control createDialogArea(Composite parent) {
		if (state < 0 || state == IServer.STATE_UNKNOWN) 
			captureServerState();

		// create a composite with standard margins and spacing
		Composite composite = (Composite)super.createDialogArea(parent);
		// Since there are only label widgets on this page, set the help on the parent
		PlatformUI.getWorkbench().getHelpSystem().setHelp(parent, ContextIds.SERVER_CLEAN_WORK_DIR);

		Label label = new Label(composite, SWT.WRAP);
		if (state == IServer.STATE_STARTING || state == IServer.STATE_STOPPING || state == IServer.STATE_UNKNOWN) {
			label.setText(NLS.bind(Messages.cleanServerStateChanging, server.getName()));
		}
		else {
			if (module != null)
				label.setText(NLS.bind(Messages.cleanModuleWorkDir, module.getName(), server.getName()));
			else
				label.setText(NLS.bind(Messages.cleanServerWorkDir, server.getName()));
			GridData data = new GridData();
			data.widthHint = 300;
			label.setLayoutData(data);
			
			if (state == IServer.STATE_STARTED) {
				label = new Label(composite, SWT.WRAP);
				label.setText(Messages.cleanServerRunning);
				data = new GridData();
				data.widthHint = 300;
				label.setLayoutData(data);
			}
		}
		
		applyDialogFont(composite);
		return composite;
	}
	
	protected void createButtonsForButtonBar(Composite parent) {
		super.createButtonsForButtonBar(parent);

		if (state < 0 || state == IServer.STATE_UNKNOWN) 
			captureServerState();

		// If server is transitioning, only allow Cancel
		if (state == IServer.STATE_STARTING || state == IServer.STATE_STOPPING) {
			Button button = getButton(IDialogConstants.OK_ID);
			if (button != null)
				button.setEnabled(false);
		}
	}

	protected void okPressed() {
		String jobName = NLS.bind(Messages.cleanServerTask,
				module != null ? module.getName() : server.getName());
		// Create job to perform the cleaning, including stopping and starting the server if necessary
		CleanWorkDirJob job = new CleanWorkDirJob(jobName);
		// Note: Since stop and start, if needed, will set scheduling rules in their jobs,
		// don't set one here. Instead do the actual deletion in a child job too with the
		// scheduling rule on that job, like stop and start.
		job.schedule();
		
		super.okPressed();
	}
	
	/*
	 * Job to clean the appropriate Tomcat work directory.  It includes
	 * stopping and starting the server if the server is currently running.
	 * The stopping, deletion, and starting are all done with child jobs,
	 * each using the server scheduling rule.  Thus, this job should
	 * not use this rule or it will block these child jobs. 
	 */
	class CleanWorkDirJob extends Job {
		/**
		 * @param name name for job
		 */
		public CleanWorkDirJob(String jobName) {
			super(jobName);
		}

		/**
		 * @see Job#belongsTo(Object)
		 */
		public boolean belongsTo(Object family) {
			return ServerUtil.SERVER_JOB_FAMILY.equals(family);
		}

		protected IStatus run(IProgressMonitor monitor) {
			final Object mutex = new Object();

			IWebModule webModule = null;
			if (module != null) {
				webModule = (IWebModule)module.loadAdapter(IWebModule.class, null);
				if (webModule == null) {
					return newErrorStatus(NLS.bind(Messages.errorCantIdentifyWebApp, module.getName()), null);
				}
			}
			
			// If state has changed since dialog was open, abort
			if (server.getServerState() != state) {
				return newErrorStatus(
						NLS.bind(Messages.errorCouldNotCleanStateChange, server.getName()), null);
			}

			IOperationListener listener = new IOperationListener() {
				public void done(IStatus result) {
					synchronized (mutex) {
						completionStatus = result;
						mutex.notifyAll();
					}
				}
			};
			
			boolean restart = false;
			IStatus status = Status.OK_STATUS;
			// If server isn't stopped, try to stop, clean, and restart
			if (state != IServer.STATE_STOPPED) {
				status = server.canStop();
				if (!status.isOK()) {
					return wrapErrorStatus(status, 
							NLS.bind(Messages.errorCouldNotCleanCantStop, server.getName()));
				}

				boolean done = false;
				boolean force = false;
				while (!done) {
					// Stop the server and wait for completion
					synchronized (mutex) {
						server.stop(force, listener);

						while (completionStatus == null) {
							try {
								mutex.wait();
							} catch (InterruptedException e) {
								// Ignore
							}
						}
					}
					// If forced, or there was an error (doesn't include timeout), or we are stopped, time to exit
					if (force || !completionStatus.isOK() || server.getServerState() == IServer.STATE_STOPPED) {
						done = true;
					}
					else {
						force = TomcatUIPlugin.queryCleanTermination(server);
						completionStatus = null;
					}
				}
			
				if (!completionStatus.isOK()) {
					// If stop job failed, assume error was displayed for that job
					return Status.OK_STATUS;
				}
				if (server.getServerState() != IServer.STATE_STOPPED) {
					return newErrorStatus(
							NLS.bind(Messages.errorCouldNotCleanStopFailed, server.getName()), null);
				}
				restart = true;
				completionStatus = null;
			}
			
			DeleteWorkDirJob deleteJob = new DeleteWorkDirJob(getName(), webModule, restart);
			deleteJob.setRule(ServerUtil.getServerSchedulingRule(server));

			deleteJob.addJobChangeListener(new JobChangeAdapter() {
				public void done(IJobChangeEvent event) {
					synchronized (mutex) {
						completionStatus = event.getResult();
						mutex.notifyAll();
					}

				}
			});

			// Perform the work directory deletion job
			synchronized (mutex) {
				deleteJob.schedule();

				while (completionStatus == null) {
					try {
						mutex.wait();
					} catch (InterruptedException e) {
						// Ignore
					}
				}
			}
			if (!completionStatus.isOK()) {
				// If delete job failed, assume error was displayed for that job
				return Status.OK_STATUS;
			}
			completionStatus = null;

			if (restart) {
				status = server.canStart(mode);
				if (!status.isOK()) {
					return wrapErrorStatus(status, 
							NLS.bind(Messages.errorCleanCantRestart, server.getName()));
				}

				// Restart the server and wait for completion
				synchronized (mutex) {
					server.start(mode, listener);

					while (completionStatus == null) {
						try {
							mutex.wait();
						} catch (InterruptedException e) {
							// Ignore
						}
					}
				}
				
				if (!completionStatus.isOK()) {
					// If start job failed, assume error was displayed for that job
					return Status.OK_STATUS;
				}
			}
			return status;
		}
	}
	
	/*
	 * Job to actually delete the work directory.  This is done
	 * in a separate job so it can be a "sibling" of potential
	 * stop and start jobs. This allows it to have a server
	 * scheduling rule.
	 */
	class DeleteWorkDirJob extends Job {
		private IWebModule webModule;
		private boolean restart;
		
		/**
		 * @param name name for job
		 */
		public DeleteWorkDirJob(String jobName, IWebModule webModule, boolean restart) {
			super(jobName);
			this.webModule = webModule;
			this.restart = restart;
		}

		/**
		 * @see Job#belongsTo(Object)
		 */
		public boolean belongsTo(Object family) {
			return ServerUtil.SERVER_JOB_FAMILY.equals(family);
		}

		protected IStatus run(IProgressMonitor monitor) {
			
			IStatus status = Status.OK_STATUS;
			// If server isn't stopped, abort the attempt to delete the work directory
			if (server.getServerState() != IServer.STATE_STOPPED) {
				return newErrorStatus(
						NLS.bind(Messages.errorCantDeleteServerNotStopped, 
								webModule != null ? module.getName() : server.getName()), null);
			}				

			// Delete the work directory
			TomcatServerBehaviour tsb = (TomcatServerBehaviour)server.loadAdapter(
					TomcatServerBehaviour.class, monitor);
			try {
				if (webModule != null) {
					ITomcatWebModule tcWebModule = new WebModule(webModule.getContextRoot(), "", "", true);
					status = tsb.cleanContextWorkDir(tcWebModule, null);
				}
				else {
					status = tsb.cleanServerWorkDir(null);
				}
			} catch (CoreException ce) {
				status = ce.getStatus();
			}
			if (!status.isOK()) {
				String cleanName = module != null ? module.getName() : server.getName();
				return wrapErrorStatus(status,
						restart ?
								NLS.bind(Messages.errorErrorDuringCleanWasRunning, 
										cleanName , server.getName()) :
								NLS.bind(Messages.errorErrorDuringClean, cleanName));
			}
			return status;
		}
	}
	
	private void captureServerState() {
		state = server.getServerState();
		if (state != IServer.STATE_STOPPED) {
			mode = server.getMode();
		}
	}

	protected IStatus newErrorStatus(String message, Throwable throwable) {
		return new Status(IStatus.ERROR, TomcatUIPlugin.PLUGIN_ID, 0,
				message, throwable);
	}
	
	protected IStatus wrapErrorStatus(IStatus status, String message) {
		MultiStatus ms = new MultiStatus(TomcatUIPlugin.PLUGIN_ID, 0, message, null);
		ms.add(status);
		return ms;
	}
}