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

import java.io.File;
import java.util.ArrayList;
import java.util.List;

import org.eclipse.core.runtime.*;
import org.eclipse.jst.server.core.PublishUtil;
import org.eclipse.wst.server.core.IModule;
import org.eclipse.wst.server.core.IServer;
import org.eclipse.wst.server.core.model.*;
/**
 * Tomcat publish helper.
 */
public class PublishOperation2 extends PublishOperation {
	protected TomcatServerBehaviour server;
	protected IModule[] module;
	protected int kind;
	protected int deltaKind;

	/**
	 * Construct the operation object to publish the specified module
	 * to the specified server.
	 * 
	 * @param server server to which the module will be published
	 * @param kind kind of publish
	 * @param module module to publish
	 * @param deltaKind kind of change
	 */
	public PublishOperation2(TomcatServerBehaviour server, int kind, IModule[] module, int deltaKind) {
		super("Publish to server", "Publish Web module to Tomcat server");
		this.server = server;
		this.module = module;
		this.kind = kind;
		this.deltaKind = deltaKind;
	}

	/**
	 * @see PublishOperation#getOrder()
	 */
	public int getOrder() {
		return 0;
	}

	/**
	 * @see PublishOperation#getKind()
	 */
	public int getKind() {
		return REQUIRED;
	}

	/**
	 * @see PublishOperation#execute(IProgressMonitor, IAdaptable)
	 */
	public void execute(IProgressMonitor monitor, IAdaptable info) throws CoreException {
		List status = new ArrayList();
		if (module.length == 1) { // web module
			publishDir(module[0], status, monitor);
		} else { // utility module
			publishJar(status, monitor);
		}
		throwException(status);
		server.setModulePublishState2(module, IServer.PUBLISH_STATE_NONE);
	}

	private void publishDir(IModule module2, List status, IProgressMonitor monitor) throws CoreException {
		IPath path = server.getModuleDeployDirectory(module2);
		
		// Remove if requested or if previously published and are now serving without publishing
		if (kind == IServer.PUBLISH_CLEAN || deltaKind == ServerBehaviourDelegate.REMOVED
				|| server.getTomcatServer().isServeModulesWithoutPublish()) {
			File f = path.toFile();
			if (f.exists()) {
				IStatus[] stat = PublishUtil.deleteDirectory(f, monitor);
				addArrayToList(status, stat);
			}
			
			if (deltaKind == ServerBehaviourDelegate.REMOVED
					|| server.getTomcatServer().isServeModulesWithoutPublish())
				return;
		}
		
		if (kind == IServer.PUBLISH_CLEAN || kind == IServer.PUBLISH_FULL) {
			IModuleResource[] mr = server.getResources(module);
			IStatus[] stat = PublishUtil.publishFull(mr, path, monitor);
			addArrayToList(status, stat);
			return;
		}
		
		IModuleResourceDelta[] delta = server.getPublishedResourceDelta(module);
		
		int size = delta.length;
		for (int i = 0; i < size; i++) {
			IStatus[] stat = PublishUtil.publishDelta(delta[i], path, monitor);
			addArrayToList(status, stat);
		}
	}

	private void publishJar(List status, IProgressMonitor monitor) throws CoreException {
		IPath path = server.getModuleDeployDirectory(module[0]);
		path = path.append("WEB-INF").append("lib");
		IPath jarPath = path.append(module[1].getName() + ".jar");
		
		// Remove if requested or if previously published and are now serving without publishing
		if (kind == IServer.PUBLISH_CLEAN || deltaKind == ServerBehaviourDelegate.REMOVED
				|| server.getTomcatServer().isServeModulesWithoutPublish()) {
			if (jarPath.toFile().exists())
				jarPath.toFile().delete();
			
			if (deltaKind == ServerBehaviourDelegate.REMOVED
					|| server.getTomcatServer().isServeModulesWithoutPublish())
				return;
		}
		if (kind != IServer.PUBLISH_CLEAN && kind != IServer.PUBLISH_FULL) {
			// avoid changes if no changes to module since last publish
			IModuleResourceDelta[] delta = server.getPublishedResourceDelta(module);
			if (delta == null || delta.length == 0)
				return;
		}
		
		// make directory if it doesn't exist
		if (!path.toFile().exists())
			path.toFile().mkdirs();
		
		IModuleResource[] mr = server.getResources(module);
		IStatus[] stat = PublishUtil.publishZip(mr, jarPath, monitor);
		addArrayToList(status, stat);
	}

	/**
	 * Utility method to throw a CoreException based on the contents of a list of
	 * error and warning status.
	 * 
	 * @param status a List containing error and warning IStatus
	 * @throws CoreException
	 */
	protected static void throwException(List status) throws CoreException {
		if (status == null)
			status = new ArrayList();
		
		if (status == null || status.size() == 0)
			return;
		if (status.size() == 1) {
			IStatus status2 = (IStatus) status.get(0);
			throw new CoreException(status2);
		}
		IStatus[] children = new IStatus[status.size()];
		status.toArray(children);
		String message = Messages.errorPublish;
		MultiStatus status2 = new MultiStatus(TomcatPlugin.PLUGIN_ID, 0, children, message, null);
		throw new CoreException(status2);
	}

	protected static void addArrayToList(List list, IStatus[] a) {
		if (list == null || a == null || a.length == 0)
			return;
		
		int size = a.length;
		for (int i = 0; i < size; i++)
			list.add(a[i]);
	}
}