/***************************************************************************************************
 * Copyright (c) 2005 Eteration A.S. and Gorkem Ercan. 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: Gorkem Ercan - initial API and implementation
 *               
 **************************************************************************************************/
package org.eclipse.jst.server.generic.core.internal.publishers;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

import org.eclipse.ant.internal.ui.IAntUIConstants;
import org.eclipse.ant.internal.ui.launchConfigurations.IAntLaunchConfigurationConstants;
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.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.ILaunchConfigurationType;
import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
import org.eclipse.debug.core.ILaunchManager;
import org.eclipse.debug.ui.IDebugUIConstants;
import org.eclipse.jdt.launching.IJavaLaunchConfigurationConstants;
import org.eclipse.jst.server.core.IWebModule;
import org.eclipse.jst.server.generic.core.internal.CorePlugin;
import org.eclipse.jst.server.generic.core.internal.GenericPublisher;
import org.eclipse.jst.server.generic.core.internal.GenericServerCoreMessages;
import org.eclipse.jst.server.generic.internal.core.util.FileUtil;
import org.eclipse.jst.server.generic.servertype.definition.Module;
import org.eclipse.jst.server.generic.servertype.definition.PublisherData;
import org.eclipse.ui.externaltools.internal.model.IExternalToolConstants;
import org.eclipse.wst.server.core.IModule;
import org.eclipse.wst.server.core.IModuleArtifact;
import org.eclipse.wst.server.core.internal.ServerPlugin;
import org.osgi.framework.Bundle;

/**
 * Ant based publisher. All the properties defined in the server definition file
 * are passed into the ANT build file as properties. In addition to the
 * properties defined in the server definition <I>module.dir</I>,
 * <I>module.name,</I> and <I>server.publish.dir</I> are computed and passed
 * to the definition file.
 * <ul>
 * <li>module.dir: includes the root of the module project file</li>
 * <li>module.name: the name of the module</li>
 * <li>server.publish.dir: the directory to put the deployment units</li>
 * <li>project.working.dir: the working dir of the project that deployed module
 * is in</li>
 * </ul>
 * 
 * @author Gorkem Ercan
 */

public class AntPublisher extends GenericPublisher {
	private static final String JAR_PROTOCOL_PREFIX = "jar"; //$NON-NLS-1$

	/**
	 * publisher id for ANT publisher.
	 */
	public static final String PUBLISHER_ID = "org.eclipse.jst.server.generic.antpublisher"; //$NON-NLS-1$

	protected static final String PROP_SERVER_PUBLISH_DIR = "server.publish.dir";//$NON-NLS-1$

	protected static final String PROP_PROJECT_WORKING_DIR = "project.working.dir";//$NON-NLS-1$

	protected static final String PROP_MODULE_DIR = "module.dir";//$NON-NLS-1$

	protected static final String PROP_MODULE_NAME = "module.name";//$NON-NLS-1$

	protected static final String PROP_CONTEXT_ROOT = "contextRoot";//$NON-NLS-1$

	protected static final String PROP_PROJECT_NAME = "project.name";//$NON-NLS-1$

	protected static final String MODULE_PUBLISH_TARGET_PREFIX = "target.publish."; //$NON-NLS-1$

	protected static final String MODULE_UNPUBLISH_TARGET_PREFIX = "target.unpublish.";//$NON-NLS-1$

	protected static final String DATA_NAME_BUILD_FILE = "build.file";//$NON-NLS-1$

	protected static final String PROP_MODULE_ARCHIVE_NAME = "module.archive.name"; //$NON-NLS-1$

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.wtp.server.core.model.IPublisher#publish(org.eclipse.wtp.server.core.resources.IModuleResource[],
	 *      org.eclipse.core.runtime.IProgressMonitor)
	 */
	public IStatus[] publish(IModuleArtifact[] resource, IProgressMonitor monitor) {
		if (getModule().length > 1)// only respond to root module calls.
			return null;
		try {
			if (monitor.isCanceled())
				return null;
			assembleModule(monitor);
			File file = computeBuildFile();
			if (monitor.isCanceled())
				return null;
			runAnt(file.toString(), getPublishTargetsForModule(), getPublishProperties(), monitor);
		} catch (CoreException e) {
			IStatus s = new Status(IStatus.ERROR, CorePlugin.PLUGIN_ID, 0, GenericServerCoreMessages.errorPublishAntpublisher, e);
			CorePlugin.getDefault().getLog().log(s);
			return new IStatus[] { s };
		}
		return null;
	}

	protected void assembleModule(IProgressMonitor monitor) throws CoreException {
		AbstractModuleAssembler assembler = AbstractModuleAssembler.Factory.getModuleAssembler(getModule()[0], getServer());
		assembler.assemble(monitor);
	}

	/**
	 * 
	 * @return file
	 * @throws CoreException
	 */
	private File computeBuildFile() throws CoreException {
		Bundle bundle = Platform.getBundle(getServerRuntime().getServerTypeDefinition().getConfigurationElementNamespace());
		URL bundleUrl = bundle.getEntry(getBuildFile());
		URL fileURL = FileUtil.resolveURL(bundleUrl);
		if (fileURL.getProtocol().equals(JAR_PROTOCOL_PREFIX)) {
			OutputStream os = null;
			InputStream is = null;
			try {
				String filename = fileURL.getPath();
				String jarname = fileURL.getFile().substring(0, filename.indexOf('!'));

				File jarFile = new File(new URL(jarname).getFile());
				JarFile jar = new JarFile(jarFile);
				File tmpFile = FileUtil.createTempFile(getBuildFile(), CorePlugin.getDefault().getStateLocation().toOSString());
				os = new FileOutputStream(tmpFile);
				String entryname = getBuildFile();
				if (entryname.startsWith("/"))//$NON-NLS-1$
					entryname = entryname.substring(1);
				JarEntry entry = jar.getJarEntry(entryname);
				is = jar.getInputStream(entry);
				FileUtil.copy(is, os);
				return tmpFile;
			} catch (IOException e) {
				IStatus s = new Status(IStatus.ERROR, CorePlugin.PLUGIN_ID, 0, "error creating temporary build file", e);//$NON-NLS-1$
				CorePlugin.getDefault().getLog().log(s);
				throw new CoreException(s);
			} finally {
				try {
					if (is != null)
						is.close();
					if (os != null)
						os.close();
				} catch (IOException e) {
					// ignore
				}
			}
		} else {
			return FileUtil.resolveFile(fileURL);
		}
	}

	private String getPublishTargetsForModule() {
		return doGetTargets(MODULE_PUBLISH_TARGET_PREFIX + getModuleTypeId());
	}

	private String getUnpublishTargetsForModule() {
		return doGetTargets(MODULE_UNPUBLISH_TARGET_PREFIX + getModuleTypeId());
	}

	private String doGetTargets(String dataname) {
		StringBuffer buffer = new StringBuffer();
		Iterator iterator = getServerRuntime().getServerTypeDefinition().getPublisher(PUBLISHER_ID).getPublisherdata().iterator();
		while (iterator.hasNext()) {
			PublisherData data = (PublisherData) iterator.next();
			if (dataname.equals(data.getDataname())) {
				if (buffer.length() > 0)
					buffer.append(",");//$NON-NLS-1$
				buffer.append(data.getDatavalue());
			}
		}
		return buffer.toString();
	}

	private String getModuleTypeId() {
		return getModule()[0].getModuleType().getId();
	}

	private String getBuildFile() {
		Iterator iterator = getServerRuntime().getServerTypeDefinition().getPublisher(PUBLISHER_ID).getPublisherdata().iterator();
		while (iterator.hasNext()) {
			PublisherData data = (PublisherData) iterator.next();
			if (DATA_NAME_BUILD_FILE.equals(data.getDataname()))
				return getServerRuntime().getServerTypeDefinition().getResolver().resolveProperties(data.getDatavalue());
		}
		return null;
	}

	private Map getPublishProperties() {
		Map props = new HashMap();
		// pass all properties to build file.
		Map serverProperties = getServer().getServerInstanceProperties();
		Map properties = getServerRuntime().getServerInstanceProperties();
		properties.putAll(serverProperties);
		Iterator propertyIterator = properties.keySet().iterator();
		while (propertyIterator.hasNext()) {
			String property = (String) propertyIterator.next();
			String value = (String) properties.get(property);
			if (value != null && value.trim().length() > 0)
				props.put(property, properties.get(property));
		}
		Module module = getServerRuntime().getServerTypeDefinition().getModule(getModuleTypeId());
		String modDir = module.getPublishDir();
		modDir = getServerRuntime().getServerTypeDefinition().getResolver().resolveProperties(modDir);
		IModule webModule = getModule()[0];

		String moduleName = guessModuleName(webModule);
		String contextRoot = guessContextRoot(webModule);
		props.put(PROP_PROJECT_WORKING_DIR, getProjectWorkingLocation().toString());
		props.put(PROP_MODULE_NAME, moduleName);
		props.put(PROP_CONTEXT_ROOT, contextRoot);
		if (isModuleType(webModule, "jst.ear")) {//$NON-NLS-1$
			props.put(PROP_MODULE_ARCHIVE_NAME, moduleName + ".ear"); //$NON-NLS-1$
		} else if (isModuleType(webModule, "jst.web")) { //$NON-NLS-1$
			props.put(PROP_MODULE_ARCHIVE_NAME, moduleName + ".war"); //$NON-NLS-1$
		} else if (isModuleType(webModule, "jst.ejb")) { //$NON-NLS-1$
			props.put(PROP_MODULE_ARCHIVE_NAME, moduleName + ".jar"); //$NON-NLS-1$
		}
		if (webModule.getProject() != null) {
			props.put(PROP_MODULE_DIR, getModuleWorkingDir().toString());
			props.put(PROP_PROJECT_NAME, webModule.getProject().getName());
		}
		props.put(PROP_SERVER_PUBLISH_DIR, modDir);
		return props;
	}

	private IPath getModuleWorkingDir() {
		return getProjectWorkingLocation().append(getModule()[0].getProject().getName());
	}

	private IPath getProjectWorkingLocation() {
		return ServerPlugin.getInstance().getTempDirectory(getServer().getServer().getId());
	}

	private String guessModuleName(IModule module) {
		String moduleName = module.getName();
		if ("jst.web".equals(getModuleTypeId())) { //$NON-NLS-1$
			IWebModule webModule = (IWebModule) getModule()[0].loadAdapter(IWebModule.class, null);
			if (webModule == null) {
				return module.getName();
			}
			String contextRoot = webModule.getURI(module);
			moduleName = contextRoot.substring(0, contextRoot.lastIndexOf('.'));
		}
		return moduleName;
	}

	private String guessContextRoot(IModule module) {
		String moduleName = guessModuleName(module);
		String contextRoot = moduleName;
		if ("jst.web".equals(getModuleTypeId())) { //$NON-NLS-1$
			IWebModule webModule = (IWebModule) getModule()[0].loadAdapter(IWebModule.class, null);
			if (webModule != null) {
				contextRoot = webModule.getContextRoot();
				if (contextRoot == null || contextRoot.length() == 0) {
					contextRoot = moduleName;
				}
			}
		}
		return contextRoot;
	}

	private void runAnt(String buildFile, String targets, Map properties, IProgressMonitor monitor) throws CoreException {
		ILaunchManager launchManager = DebugPlugin.getDefault().getLaunchManager();
		ILaunchConfigurationType type = launchManager
				.getLaunchConfigurationType(IAntLaunchConfigurationConstants.ID_ANT_LAUNCH_CONFIGURATION_TYPE);
		if (type == null) {
			IStatus s = new Status(IStatus.ERROR, CorePlugin.PLUGIN_ID, 0, GenericServerCoreMessages.antLauncherMissing, null);
			throw new CoreException(s);
		}
		ILaunchConfigurationWorkingCopy wc = type.newInstance(null, properties.get(PROP_MODULE_NAME) + " module publisher"); //$NON-NLS-1$
		wc.setContainer(null);
		wc.setAttribute(IExternalToolConstants.ATTR_LOCATION, buildFile);
		wc.setAttribute(IJavaLaunchConfigurationConstants.ATTR_CLASSPATH_PROVIDER, "org.eclipse.ant.ui.AntClasspathProvider"); //$NON-NLS-1$
		wc.setAttribute(IAntLaunchConfigurationConstants.ATTR_ANT_TARGETS, targets);
		wc.setAttribute(IAntLaunchConfigurationConstants.ATTR_ANT_PROPERTIES, properties);
		wc.setAttribute(IDebugUIConstants.ATTR_LAUNCH_IN_BACKGROUND, false);
		wc.setAttribute(IDebugUIConstants.ATTR_CAPTURE_IN_CONSOLE, true);
		wc.setAttribute(IDebugUIConstants.ATTR_PRIVATE, true);

		wc.setAttribute(IJavaLaunchConfigurationConstants.ATTR_SOURCE_PATH_PROVIDER, "org.eclipse.ant.ui.AntClasspathProvider"); //$NON-NLS-1$
		wc.setAttribute(IJavaLaunchConfigurationConstants.ATTR_VM_INSTALL_NAME, getServerRuntime().getVMInstall().getName());
		wc.setAttribute(IJavaLaunchConfigurationConstants.ATTR_VM_INSTALL_TYPE, getServerRuntime().getVMInstall().getVMInstallType()
				.getId());
		wc.setAttribute(IJavaLaunchConfigurationConstants.ATTR_MAIN_TYPE_NAME,
				"org.eclipse.ant.internal.ui.antsupport.InternalAntRunner"); //$NON-NLS-1$
		wc.setAttribute(DebugPlugin.ATTR_PROCESS_FACTORY_ID, IAntUIConstants.REMOTE_ANT_PROCESS_FACTORY_ID);

		setupAntLaunchConfiguration(wc);

		ILaunchConfiguration launchConfig = wc.doSave();
		launchConfig.launch("run", monitor); //$NON-NLS-1$
	}

	/**
	 * Hook method for subclasses.
	 * 
	 * @param wc
	 */
	protected void setupAntLaunchConfiguration(ILaunchConfigurationWorkingCopy wc) {
		// nothing to do
	}

	private static boolean isModuleType(IModule module, String moduleTypeId) {
		if (module.getModuleType() != null && moduleTypeId.equals(module.getModuleType().getId()))
			return true;
		return false;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jst.server.generic.internal.core.GenericPublisher#unpublish(org.eclipse.wst.server.core.IModule,
	 *      org.eclipse.core.runtime.IProgressMonitor)
	 */
	public IStatus[] unpublish(IProgressMonitor monitor) {

		if (getModule().length > 1)// only respond to root module calls.
			return null;
		try {
			File file = computeBuildFile();
			runAnt(file.toString(), getUnpublishTargetsForModule(), getPublishProperties(), monitor);
		} catch (CoreException e) {
			IStatus s = new Status(IStatus.ERROR, CorePlugin.PLUGIN_ID, 0, GenericServerCoreMessages.errorRemoveModuleAntpublisher, e);
			return new IStatus[] { s };
		}
		return null;
	}
}
