/***************************************************************************************************
 * 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$
    
	private static final String PROP_SERVER_PUBLISH_DIR = "server.publish.dir";//$NON-NLS-1$
	private static final String PROP_PROJECT_WORKING_DIR= "project.working.dir";//$NON-NLS-1$
	private static final String PROP_MODULE_DIR = "module.dir";//$NON-NLS-1$
	private static final String PROP_MODULE_NAME = "module.name";//$NON-NLS-1$
	private static final String PROP_PROJECT_NAME = "project.name";//$NON-NLS-1$
	private static final String MODULE_PUBLISH_TARGET_PREFIX = "target.publish."; //$NON-NLS-1$
	private static final String MODULE_UNPUBLISH_TARGET_PREFIX = "target.unpublish.";//$NON-NLS-1$
	private static final String DATA_NAME_BUILD_FILE="build.file";//$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;
	}

	private 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);
        props.put(PROP_PROJECT_WORKING_DIR,getProjectWorkingLocation().toString());
		props.put(PROP_MODULE_NAME,moduleName);
		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);
			//TODO we should really pass the full uri including the file extension in the future
			moduleName = contextRoot.substring(0,contextRoot.lastIndexOf('.'));
			}
		return moduleName;
		}



	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
	}

	/* (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;
    }
}
