/*******************************************************************************
 * Copyright (c) 2007 Chase Technology Ltd - http://www.chasetechnology.co.uk
 * 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:
 *     Doug Satchwell (Chase Technology Ltd) - initial API and implementation
 *******************************************************************************/
package org.eclipse.wst.xsl.jaxp.launching.internal;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.FileLocator;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.IBreakpointManager;
import org.eclipse.debug.core.IDebugEventSetListener;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.ILaunchManager;
import org.eclipse.debug.core.model.IBreakpoint;
import org.eclipse.debug.core.model.IDebugTarget;
import org.eclipse.debug.core.model.ISourceLocator;
import org.eclipse.debug.core.model.IStackFrame;
import org.eclipse.jdt.launching.IVMRunner;
import org.eclipse.jdt.launching.JavaLaunchDelegate;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PlatformUI;
import org.eclipse.wst.xsl.jaxp.launching.IDebugger;
import org.eclipse.wst.xsl.jaxp.launching.IProcessorInstall;
import org.eclipse.wst.xsl.jaxp.launching.IProcessorInvoker;
import org.eclipse.wst.xsl.jaxp.launching.IProcessorJar;
import org.eclipse.wst.xsl.jaxp.launching.ITransformerFactory;
import org.eclipse.wst.xsl.jaxp.launching.JAXPLaunchConfigurationConstants;
import org.eclipse.wst.xsl.jaxp.launching.JAXPRuntime;
import org.eclipse.wst.xsl.jaxp.launching.model.JAXPDebugTarget;
import org.eclipse.wst.xsl.launching.model.IXSLConstants;

public class JAXPJavaLaunchConfigurationDelegate extends JavaLaunchDelegate implements IDebugEventSetListener
{
	private String mode;
	LaunchHelper launchHelper;
	
	@Override
	public synchronized void launch(ILaunchConfiguration configuration, final String mode, final ILaunch launch, IProgressMonitor monitor) throws CoreException
	{
		this.mode = mode;
		launchHelper.save(getLaunchConfigFile());
		
		// set the launch name
		IProcessorInstall install = getProcessorInstall(configuration, mode);
		String tfactory = getTransformerFactory(install);
		String name = install.getName();
		if (tfactory != null)
			name += "[" + tfactory + "]";
		launch.setAttribute("launchName", name);

		// the super.launch will add a Java source director if we set it to null here
		final ISourceLocator configuredLocator = launch.getSourceLocator();
		launch.setSourceLocator(null);

		super.launch(configuration, mode, launch, monitor);
		
		// now get the java source locator
		final ISourceLocator javaSourceLookupDirector = (ISourceLocator)launch.getSourceLocator();
		// now add our own participant to the java director
		launch.setSourceLocator(new ISourceLocator(){

			public Object getSourceElement(IStackFrame stackFrame) 
			{
				// simply look at one and then the other
				Object sourceElement = javaSourceLookupDirector.getSourceElement(stackFrame);
				if (sourceElement == null)
					sourceElement = configuredLocator.getSourceElement(stackFrame);
				return sourceElement;
			}});
		
//		IJavaDebugTarget javaTarget = (IJavaDebugTarget)launch.getDebugTarget();
//		launch.removeDebugTarget(javaTarget);
		
		IDebugTarget javaTarget = launch.getDebugTarget();
		IDebugTarget xslTarget = new JAXPDebugTarget(launch, launch.getProcesses()[0], launchHelper);
		
		// remove java as the primary target and make xsl the primary target
		launch.removeDebugTarget(javaTarget);
		launch.addDebugTarget(xslTarget);
		// add this here to make java the non-primary target
	//	launch.addDebugTarget(javaTarget);
		
	//	launch.addDebugTarget(new JavaXSLDebugTarget(launch, launch.getProcesses()[0], launchHelper, javaTarget));
		

	}

	/**
	 * Get the Java breakpoint and the XSL breakpoints
	 */
	@Override
	protected IBreakpoint[] getBreakpoints(ILaunchConfiguration configuration)
	{
		IBreakpointManager breakpointManager = DebugPlugin.getDefault().getBreakpointManager();
		if (!breakpointManager.isEnabled())
			return null;
		
		IBreakpoint[] javaBreakpoints = super.getBreakpoints(configuration);
		IBreakpoint[] xslBreakpoints = breakpointManager.getBreakpoints(IXSLConstants.ID_XSL_DEBUG_MODEL);
		IBreakpoint[] breakpoints = new IBreakpoint[javaBreakpoints.length+xslBreakpoints.length];
		System.arraycopy(javaBreakpoints, 0, breakpoints, 0, javaBreakpoints.length);
		System.arraycopy(xslBreakpoints, 0, breakpoints, javaBreakpoints.length, xslBreakpoints.length);
		
		return breakpoints;
	}

	@Override
	public boolean preLaunchCheck(ILaunchConfiguration configuration, String mode, IProgressMonitor monitor) throws CoreException
	{
		this.launchHelper = new LaunchHelper(configuration);
		if (mode.equals(ILaunchManager.DEBUG_MODE))
		{
			// TODO don't like having UI code in the launching plugin...where else can it go?
			final IProcessorInstall install = getProcessorInstall(configuration, ILaunchManager.RUN_MODE);
			if (install.getDebugger() == null)
			{
				final boolean[] result = new boolean[]
				{ false };
				// open a dialog for choosing a different install that does have
				// an associated debugger
				PlatformUI.getWorkbench().getDisplay().syncExec(new Runnable()
				{
					public void run()
					{
						String debuggingInstallId = JAXPLaunchingPlugin.getDefault().getPluginPreferences().getString(JAXPLaunchConfigurationConstants.ATTR_DEFAULT_DEBUGGING_INSTALL_ID);
						IProcessorInstall processor = JAXPRuntime.getProcessor(debuggingInstallId);

						IWorkbenchWindow dw = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
						
						String title = Messages.getString("XSLTLaunchConfigurationDelegate.0"); //$NON-NLS-1$
						String message = Messages.getString("XSLTLaunchConfigurationDelegate.1") + install.getName() + Messages.getString("XSLTLaunchConfigurationDelegate.2") //$NON-NLS-1$ //$NON-NLS-2$
								+ Messages.getString("XSLTLaunchConfigurationDelegate.3") + processor.getName() + Messages.getString("XSLTLaunchConfigurationDelegate.4");//$NON-NLS-1$ //$NON-NLS-2$
						
						MessageDialog dialog = new MessageDialog(dw.getShell(), title, null, message, MessageDialog.QUESTION,
								new String[] { IDialogConstants.OK_LABEL, IDialogConstants.CANCEL_LABEL }, 0); // yes is the default
						
				        result[0] = dialog.open() == 0;
					}
				});
				return result[0];
			}
			else
			{
				String debuggerTF = install.getDebugger().getTransformerFactory();
				String installTF = launchHelper.getTransformerFactory() == null ? null : launchHelper.getTransformerFactory().getFactoryClass();
				if (!debuggerTF.equals(installTF))
				{
					PlatformUI.getWorkbench().getDisplay().syncExec(new Runnable()
					{
						public void run()
						{
							IWorkbenchWindow dw = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
							
							String title = Messages.getString("Change Transformer Factory");
							String message = install.getName() + " must use the " + launchHelper.getTransformerFactory().getName() + " transformer factory when debugging.\n"
									+ "Be aware that this may give different results to the " + launchHelper.getTransformerFactory().getName() + " transformer factory configured for this launch configuration.";
							
							MessageDialog dialog = new MessageDialog(dw.getShell(), title, null, message, MessageDialog.WARNING,
									new String[] { IDialogConstants.OK_LABEL, IDialogConstants.CANCEL_LABEL }, 0); // yes is the default
							dialog.open();
						}
					});
				}
			}
		}
		return super.preLaunchCheck(configuration, mode, monitor);
	}

	@Override
	public IVMRunner getVMRunner(ILaunchConfiguration configuration, String mode) throws CoreException
	{
		// comment this out in order to get java debugging as well as XSL debugging
//		if (ILaunchManager.DEBUG_MODE.equals(mode))
//			return super.getVMRunner(configuration, ILaunchManager.RUN_MODE);
		return super.getVMRunner(configuration, mode);
	}

	private File getLaunchConfigFile()
	{
		IPath launchPath = Platform.getStateLocation(JAXPLaunchingPlugin.getDefault().getBundle()).append("launch"); //$NON-NLS-1$
		File launchDir = launchPath.toFile();
		if (!launchDir.exists())
			launchDir.mkdir();
		File file = new File(launchDir, "launch.xml"); //$NON-NLS-1$
		return file;
	}

	@Override
	public IPath getWorkingDirectoryPath(ILaunchConfiguration configuration) throws CoreException
	{
		// TODO changes are afoot so that working directory can be gotten from the Common launch tab
		
//		String path = configuration.getAttribute(JAXPLaunchConfigurationConstants.ATTR_PROCESSOR_WORKING_DIR, (String) null);
//		if (path != null)
//		{
//			path = VariablesPlugin.getDefault().getStringVariableManager().performStringSubstitution(path);
//			return new Path(path);
//		}
		return null;
	}

	private IProcessorInvoker getProcessorInvokerDescriptor(ILaunchConfiguration configuration) throws CoreException
	{
		String invokerId = configuration.getAttribute(JAXPLaunchConfigurationConstants.INVOKER_DESCRIPTOR, "org.eclipse.wst.xsl.launching.jaxp.invoke");
		return JAXPRuntime.getProcessorInvoker(invokerId);
	}

	public static IProcessorInstall getProcessorInstall(ILaunchConfiguration configuration, String mode) throws CoreException
	{
		IProcessorInstall install = LaunchHelper.getProcessorInstall(configuration);
		if (mode.equals(ILaunchManager.DEBUG_MODE) && install.getDebugger() == null)
		{
			String debuggingInstallId = JAXPLaunchingPlugin.getDefault().getPluginPreferences().getString(JAXPLaunchConfigurationConstants.ATTR_DEFAULT_DEBUGGING_INSTALL_ID);
			install = JAXPRuntime.getProcessor(debuggingInstallId);
		}
		return install;
	}

	@Override
	public String getMainTypeName(ILaunchConfiguration configuration) throws CoreException
	{
		if (ILaunchManager.DEBUG_MODE.equals(mode))
			return "org.eclipse.wst.xsl.jaxp.debug.debugger.DebugRunner"; //$NON-NLS-1$
		return "org.eclipse.wst.xsl.jaxp.debug.invoker.internal.Main"; //$NON-NLS-1$
	}

	@Override
	public String getProgramArguments(ILaunchConfiguration configuration) throws CoreException
	{
		// classname, sourceurl, output file
		IProcessorInvoker invoker = getProcessorInvokerDescriptor(configuration);
		String clazz = invoker.getInvokerClassName();

		StringBuffer sb = new StringBuffer();
		sb.append(clazz);
		sb.append(" "); //$NON-NLS-1$
		sb.append("\"" + getLaunchConfigFile().getAbsolutePath() + "\""); //$NON-NLS-1$ //$NON-NLS-2$
		sb.append(" "); //$NON-NLS-1$
		sb.append("\"" + launchHelper.getSource() + "\""); //$NON-NLS-1$ //$NON-NLS-2$
		sb.append(" "); //$NON-NLS-1$
		sb.append("\"" + launchHelper.getTarget().getAbsolutePath() + "\""); //$NON-NLS-1$ //$NON-NLS-2$
		if (ILaunchManager.DEBUG_MODE.equals(mode))
		{
			IProcessorInstall install = getProcessorInstall(configuration, mode);
			if (install.getDebugger() != null)
			{
				IDebugger debugger = install.getDebugger();
				String className = debugger.getClassName();
				sb.append(" -debug ").append(className).append(" "); //$NON-NLS-1$ //$NON-NLS-2$
				sb.append(launchHelper.getRequestPort());
				sb.append(" ").append(launchHelper.getEventPort()); //$NON-NLS-1$
				sb.append(" ").append(launchHelper.getGeneratePort()); //$NON-NLS-1$
			}
		}

		return sb.toString();
	}

	@Override
	public String[] getClasspath(ILaunchConfiguration configuration) throws CoreException
	{
		// get the classpath defined by the user
		String[] userClasspath = super.getClasspath(configuration);

		// get the classpath required for the transformation
		IProcessorInvoker invoker = getProcessorInvokerDescriptor(configuration);
		List<String> invokerCP = new ArrayList<String>();
		for (String entry : invoker.getClasspathEntries())
		{
			invokerCP.add(entry);
		}

		// add the debugger...
		IProcessorInstall install = getProcessorInstall(configuration, mode);
		if (ILaunchManager.DEBUG_MODE.equals(mode) && install.getDebugger() != null)
		{
			String[] jars = install.getDebugger().getClassPath();
			for (String jar : jars)
			{
				invokerCP.add(jar);
			}
		}

		String[] invokerClasspath = (String[]) invokerCP.toArray(new String[0]);

		// add them together
		String[] classpath = new String[userClasspath.length + invokerClasspath.length];
		System.arraycopy(invokerClasspath, 0, classpath, 0, invokerClasspath.length);
		System.arraycopy(userClasspath, 0, classpath, invokerClasspath.length, userClasspath.length);

		return classpath;
	}

	@Override
	public String getVMArguments(ILaunchConfiguration configuration) throws CoreException
	{
		String vmargs = super.getVMArguments(configuration);

		IProcessorInstall install = getProcessorInstall(configuration, mode);
		if (install != null && !install.getProcessorType().isJREDefault())
		{
			// clear the endorsed dir
			File tempDir = getEndorsedDir();
			if (tempDir.exists())
			{
				File[] children = tempDir.listFiles();
				for (File child : children)
				{
					child.delete();
				}
				tempDir.delete();
			}
			tempDir.mkdir();

			// move the required jars to the endorsed dir
			IProcessorJar[] jars = install.getProcessorJars();
			for (int i = 0; i < jars.length; i++)
			{
				URL entry = jars[i].asURL();
				if (entry == null)
					throw new CoreException(new Status(IStatus.ERROR, JAXPLaunchingPlugin.PLUGIN_ID, IStatus.ERROR, Messages.getString("XSLTLaunchConfigurationDelegate.23") + jars[i], null)); //$NON-NLS-1$
				File file = new File(tempDir, "END_" + i + ".jar"); //$NON-NLS-1$ //$NON-NLS-2$
				moveFile(entry, file);
			}
			// add the endorsed dir
			vmargs += " -Djava.endorsed.dirs=\"" + tempDir.getAbsolutePath() + "\""; //$NON-NLS-1$ //$NON-NLS-2$
			
			String tfactory = getTransformerFactory(install);
			if (tfactory != null)
				vmargs += " -Djavax.xml.transform.TransformerFactory=" + tfactory; //$NON-NLS-1$
			
//			if (ILaunchManager.DEBUG_MODE.equals(mode))
//			{
//				// in debug mode, set the logging to ERROR. This prevents the console from popping up on top of the result view!
//				try
//				{
//					URL url = FileLocator.resolve(FileLocator.find(Platform.getBundle(JAXPLaunchingPlugin.PLUGIN_ID), new Path("/log4j.debug.properties"), null));
//					vmargs += " -Dlog4j.configuration=\""+url.toExternalForm()+"\""; //$NON-NLS-1$
//				}
//				catch (IOException e)
//				{
//					JAXPLaunchingPlugin.log(e);
//				}
//			}
		}
		return vmargs;
	}
	
	private String getTransformerFactory(IProcessorInstall install)
	{
		String tfactory = null;
		if (ILaunchManager.DEBUG_MODE.equals(mode))
			tfactory = install.getDebugger().getTransformerFactory();
		else
		{
			ITransformerFactory t = launchHelper.getTransformerFactory();
			if (t != null)
				tfactory = t.getFactoryClass();
		}
		return tfactory;
	}

	private File getEndorsedDir()
	{
		IPath tempLocation = Platform.getStateLocation(JAXPLaunchingPlugin.getDefault().getBundle()).append("endorsed"); //$NON-NLS-1$
		return tempLocation.toFile();
	}

	private static void moveFile(URL src, File target) throws CoreException
	{
		BufferedOutputStream bos = null;
		BufferedInputStream bis = null;
		try
		{
			bos = new BufferedOutputStream(new FileOutputStream(target));
			bis = new BufferedInputStream(src.openStream());
			while (bis.available() > 0)
			{
				int size = bis.available();
				if (size > 1024)
					size = 1024;
				byte[] b = new byte[size];
				bis.read(b, 0, b.length);
				bos.write(b);
			}
		}
		catch (IOException e)
		{
			throw new CoreException(new Status(IStatus.ERROR, JAXPLaunchingPlugin.PLUGIN_ID, IStatus.ERROR, Messages.getString("XSLTLaunchConfigurationDelegate.7") + src + Messages.getString("XSLTLaunchConfigurationDelegate.31") + target, e)); //$NON-NLS-1$ //$NON-NLS-2$
		}
		finally
		{
			if (bis != null)
			{
				try
				{
					bis.close();
				}
				catch (IOException e)
				{
					JAXPLaunchingPlugin.log(e);
				}
			}
			if (bos != null)
			{
				try
				{
					bos.close();
				}
				catch (IOException e)
				{
					JAXPLaunchingPlugin.log(e);
				}
			}
		}
	}
}
