/*******************************************************************************
 * Copyright (c) 2005 BEA Systems, Inc. 
 * 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:
 *    rfrost@bea.com - initial API and implementation
 *    
 *    Based on GenericServerBehavior by Gorkem Ercan
 *******************************************************************************/
package org.eclipse.jst.server.generic.core.internal;

import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
import org.eclipse.debug.core.ILaunchManager;
import org.eclipse.debug.core.model.IProcess;
import org.eclipse.jdt.launching.IJavaLaunchConfigurationConstants;
import org.eclipse.jst.server.generic.internal.xml.Resolver;
import org.eclipse.jst.server.generic.servertype.definition.External;
import org.eclipse.jst.server.generic.servertype.definition.ServerRuntime;
import org.eclipse.osgi.util.NLS;
import org.eclipse.wst.server.core.IServer;
import org.eclipse.wst.server.core.ServerPort;
import org.eclipse.wst.server.core.internal.Server;
import org.eclipse.wst.server.core.util.SocketUtil;

/**
 * Subclass of <code>GenericServerBehavior</code> that supports 
 * servers which are started/stopped via external executables (e.g. scripts).
 */
public class ExternalServerBehaviour extends GenericServerBehaviour {
	
	// config for debugging session
	private ILaunchConfigurationWorkingCopy fLaunchConfigurationWC;
    private String fMode;
    private ILaunch fLaunch; 
    private IProgressMonitor fProgressMonitor;
    
    /**
     * Override to reset the status if the state was unknown
     * @param force 
     */
    public void stop(boolean force) {
    	resetStatus(getServer().getServerState());
    	super.stop(force);
    }

    /**
     * Override to set status to unknown if the port was in use and to reset the status if the state was 
     * unknown and an exception was not thrown. Will want to change logic once external generic server pings
     * server process to determine state instead of maintaining handle to process. 
     */
    protected void setupLaunch(ILaunch launch, String launchMode, IProgressMonitor monitor) throws CoreException {
    	int state = getServer().getServerState();
    	try {
    		super.setupLaunch(launch, launchMode, monitor);
    	} catch (CoreException ce) {
    		ServerPort portInUse = portInUse();
    		if (portInUse != null) {
    			Trace.trace(Trace.WARNING, "Port " + portInUse.getPort() + " is currently in use");  //$NON-NLS-1$//$NON-NLS-2$
				Status status = new Status(IStatus.WARNING, CorePlugin.PLUGIN_ID, IStatus.OK, 
							NLS.bind(GenericServerCoreMessages.errorPortInUse,Integer.toString(portInUse.getPort()),portInUse.getName()), null);
				setServerStatus(status);
				setServerState(IServer.STATE_UNKNOWN);
    		}
    		throw ce;
    	}
    	resetStatus(state);
    }
    
    private ServerPort portInUse() {
    	ServerPort[] ports = getServer().getServerPorts(null);
    	ServerPort sp;
    	for(int i=0;i<ports.length;i++){
    		sp = ports[i];
    		if (SocketUtil.isPortInUse(sp.getPort(), 5)) {
    			return sp;
    		}
    	}
    	return null;
	}
    
	/**
	 * Override to trigger the launch of the debugging session (if appropriate).
	 */
	protected synchronized void setServerStarted() {
		if (fLaunchConfigurationWC != null) {
			try {
				setupSourceLocator( fLaunch );
				ExternalLaunchConfigurationDelegate.startDebugging(fLaunchConfigurationWC, fMode, fLaunch, fProgressMonitor);
			} catch (CoreException ce) {
				// failed to start debugging, so set mode to run
				setMode(ILaunchManager.RUN_MODE);
				final Status status = new Status(IStatus.ERROR, CorePlugin.PLUGIN_ID, 1,
							GenericServerCoreMessages.errorStartingExternalDebugging, ce); 
				CorePlugin.getDefault().getLog().log(status);
				Trace.trace(Trace.SEVERE, GenericServerCoreMessages.errorStartingExternalDebugging, ce);
			} finally {
				clearDebuggingConfig();
			}
		}
		setServerState(IServer.STATE_STARTED);
 	}
	
	/**
	 * Subclasses may override this method to replace default source locator or add additional
	 * sourceLookupParticipant, if necessary 
	 * @param launch 	the ILaunch object of the debug session
	 */
	protected void setupSourceLocator(ILaunch launch) {
        //nothing to do
	}

	/*
	 * If the server state is unknown, reset the status to OK
	 */
	private void resetStatus(int state) {
		if (state == IServer.STATE_UNKNOWN) {
			setServerStatus(null);
		}
	}
	
	/**
	 * Since terminate() is called during restart, need to override to
	 * call shutdown instead of just killing the original process.
	 */
	protected void terminate() {
		int state = getServer().getServerState();
		if (state == IServer.STATE_STOPPED) 
    		return;
    
		// cache a ref to the current process
		IProcess currentProcess = process;
		// set the process var to null so that GenericServerBehavior.setProcess()
		// will grab the stop executable (and declare the server stopped when it exits)
		process = null;

		// execute the standard shutdown
		shutdown(state);
		
		// if the shutdown did not terminate the process, forcibly terminate it
		try {
    		if (currentProcess != null && !currentProcess.isTerminated()) {
    			Trace.trace(Trace.FINER, "About to kill process: " + currentProcess); //$NON-NLS-1$
    			currentProcess.terminate();
    			currentProcess = null;
    		}
    	} catch (Exception e) {
    		Trace.trace(Trace.SEVERE, "Error killing the process", e); //$NON-NLS-1$
    	}
	}
	
	/**
	 * Override superclass method to correctly setup the launch configuration for starting an external
	 * server.
	 * @param workingCopy
	 * @param monitor
	 * @throws CoreException 
	 */
	public void setupLaunchConfiguration(ILaunchConfigurationWorkingCopy workingCopy,
										 IProgressMonitor monitor) throws CoreException {
		clearDebuggingConfig();
		ServerRuntime serverDef = getServerDefinition();
		Resolver resolver = serverDef.getResolver();
		workingCopy.setAttribute(IJavaLaunchConfigurationConstants.ATTR_WORKING_DIRECTORY,
					resolver.resolveProperties(serverDef.getStart().getWorkingDirectory()));
		String external = resolver.resolveProperties(getExternalForOS(serverDef.getStart().getExternal()));
		workingCopy.setAttribute(ExternalLaunchConfigurationDelegate.COMMANDLINE, external);
		workingCopy.setAttribute(ExternalLaunchConfigurationDelegate.DEBUG_PORT, 
					resolver.resolveProperties(serverDef.getStart().getDebugPort()));
		// just use the commandline for now
		workingCopy.setAttribute(ExternalLaunchConfigurationDelegate.EXECUTABLE_NAME, external);
        Map environVars = getEnvironmentVariables(getServerDefinition().getStart());
        if(!environVars.isEmpty()){
        	workingCopy.setAttribute(ILaunchManager.ATTR_ENVIRONMENT_VARIABLES,environVars);
        }
        String existingProgArgs  = workingCopy.getAttribute(IJavaLaunchConfigurationConstants.ATTR_PROGRAM_ARGUMENTS, (String)null);
        String serverProgArgs =  getProgramArguments();
        if(existingProgArgs==null || existingProgArgs.indexOf(serverProgArgs)<0) {
            workingCopy.setAttribute(IJavaLaunchConfigurationConstants.ATTR_PROGRAM_ARGUMENTS,serverProgArgs);
        }
	}

	/*
	 * Returns the first external whose "os" attribute matches (case insensitive) the beginning 
	 * of the name of the current OS (as determined by the System "os.name" property). If
	 * no such match is found, returns the first external that does not have an OS attribute.
	 */
	private String getExternalForOS(List externals) {
		String currentOS = System.getProperty("os.name").toLowerCase(); //$NON-NLS-1$
		External external;
		String matchingExternal = null;
		String externalOS;
		Iterator i = externals.iterator();
		while (i.hasNext()) {
			external= (External) i.next();
			externalOS = external.getOs();
			if (externalOS == null) {
				if (matchingExternal == null) {
					matchingExternal = external.getValue();
				}
			} else if (currentOS.startsWith(externalOS.toLowerCase())) {
				matchingExternal = external.getValue();
				break;
			}
		}
		return matchingExternal;
	}

	/**
     * Returns the String ID of the launch configuration type.
     * @return launchTypeID
     */
	protected String getConfigTypeID() {
		return ExternalLaunchConfigurationDelegate.ID_EXTERNAL_LAUNCH_TYPE;
	}

	/**
	 * Returns the String name of the stop launch configuration.
	 * @return launcherName
	 */
	protected String getStopLaunchName() {
		return GenericServerCoreMessages.externalStopLauncher;
	}
	
	/**
	 * Sets up the launch configuration for stopping the server.
	 * 
	 */
	protected void setupStopLaunchConfiguration(GenericServerRuntime runtime, ILaunchConfigurationWorkingCopy wc) {
		clearDebuggingConfig();
		ServerRuntime serverDef = getServerDefinition();
		Resolver resolver = serverDef.getResolver(); 
		wc.setAttribute(IJavaLaunchConfigurationConstants.ATTR_WORKING_DIRECTORY,
					resolver.resolveProperties(serverDef.getStop().getWorkingDirectory()));
		String external = resolver.resolveProperties(getExternalForOS(serverDef.getStop().getExternal()));
		wc.setAttribute(ExternalLaunchConfigurationDelegate.COMMANDLINE, external);
		// just use commandline for now
        Map environVars = getEnvironmentVariables(getServerDefinition().getStop());
        if(!environVars.isEmpty()){
        	wc.setAttribute(ILaunchManager.ATTR_ENVIRONMENT_VARIABLES,environVars);
        }
		wc.setAttribute(
				IJavaLaunchConfigurationConstants.ATTR_PROGRAM_ARGUMENTS,
				resolver.resolveProperties(serverDef.getStop().getProgramArgumentsAsString()));
		wc.setAttribute(ExternalLaunchConfigurationDelegate.EXECUTABLE_NAME, external); 	
		wc.setAttribute(Server.ATTR_SERVER_ID, getServer().getId());
	}
	
	/**
	 * Sets the configuration to use for launching a debugging session
	 */
	protected synchronized void setDebuggingConfig(ILaunchConfigurationWorkingCopy wc,
					 			      String mode,
					 			      ILaunch launch, 
					 			      IProgressMonitor monitor) {
		this.fLaunchConfigurationWC = wc;
		this.fMode = mode;
		this.fLaunch = launch;
		this.fProgressMonitor = monitor;
	}
	
	private synchronized void clearDebuggingConfig() {
		this.fLaunchConfigurationWC = null;
		this.fMode = null;
		this.fLaunch = null;
		this.fProgressMonitor = null;
	}
	
	
}
