/*******************************************************************************
 * 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.debug.debugger;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.Writer;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.URL;
import java.util.Map;
import java.util.Properties;

import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.URIResolver;
import javax.xml.transform.sax.SAXSource;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.eclipse.wst.xsl.jaxp.debug.invoker.IProcessorInvoker;
import org.eclipse.wst.xsl.jaxp.debug.invoker.PipelineDefinition;
import org.eclipse.wst.xsl.jaxp.debug.invoker.TransformationException;
import org.eclipse.wst.xsl.jaxp.debug.invoker.internal.JAXPSAXProcessorInvoker;
import org.xml.sax.InputSource;

/**
 * The entry point to the debug process which is responsible for configuring a debugger 
 * and then communicating with the Eclipse process via sockets using a common set of commands.
 * 
 * <ul>
 * <li>instantiates an implementation of <code>IXSLDebugger</code>
 * <li>configures the debugger with the transformation pipeline
 * <li>starts the debugger in a separate thread
 * <li>the main thread is then used to listen to incoming requests and call the appropriate debugger methods
 * </ul>
 * 
 * @author Doug Satchwell
 */
public class DebugRunner
{
	private static final Log log = LogFactory.getLog(DebugRunner.class);

	private final BufferedReader requestIn;
	private final Writer requestOut;
	private final Writer eventOut;
	private final Writer generatedStream;
	private Socket eventSocket;
	private Socket requestSocket;
	private Socket generateSocket;

	/**
	 * Create a new instance of this using the supplied readers and writers.
	 * 
	 * @param requestIn the reader for reading incoming requests
	 * @param requestOut the writer for acknowledging requests
	 * @param eventOut the writer for publishing debug events
	 */
	public DebugRunner(BufferedReader requestIn, PrintWriter requestOut, PrintWriter eventOut, PrintWriter generatedStream)
	{
		this.requestOut = requestOut;
		this.requestIn = requestIn;
		this.eventOut = eventOut;
		this.generatedStream = generatedStream;
	}

	/**
	 * Create a new instance of this given a request port and an event port.
	 * 
	 * @param requestPort the port to listen to requests and send acknowledgements
	 * @param eventPort the port for publishing debug events
	 * @throws IOException if there was a problem opening a socket
	 */
	public DebugRunner(int requestPort, int eventPort, int generatePort) throws IOException
	{
		requestSocket = getSocket(requestPort);
		eventSocket = getSocket(eventPort);
		generateSocket = getSocket(generatePort);
		requestIn = new BufferedReader(new InputStreamReader(requestSocket.getInputStream()));
		requestOut = new PrintWriter(requestSocket.getOutputStream(), true);
		eventOut = new PrintWriter(eventSocket.getOutputStream(), true);
		generatedStream = new BufferedWriter(new PrintWriter(generateSocket.getOutputStream(), true));
	}

	/**
	 * This method starts the given debugger in its own thread, and blocks while waiting 
	 * for incoming requests from the request port, until there are no more requests.
	 * 
	 * @param debugger the debugger to start in a thread
	 * @throws TransformationException if a problem occurred while transforming
	 * @throws IOException 
	 */
	public void loop(IXSLDebugger debugger) throws TransformationException, IOException
	{
		debugger.setEventWriter(eventOut);
		debugger.setGeneratedWriter(generatedStream);
		String inputLine, response;
		// signal we are ready to receive requests
		eventOut.write("ready\n"); //$NON-NLS-1$
		eventOut.flush();
		log.debug("entering loop"); //$NON-NLS-1$
		try
		{
			while ((inputLine = requestIn.readLine()) != null)
			{
				response = inputLine;
				log.debug("REQUEST:" + inputLine); //$NON-NLS-1$
				Thread debuggerThread = null;
				if (DebugConstants.REQUEST_START.equals(inputLine))
				{
					debuggerThread = new Thread(debugger, "debugger"); //$NON-NLS-1$
					debuggerThread.start();
				}
				/*
				 * else if (REQUEST_QUIT.equals(inputLine)) { }
				 */
				else if (DebugConstants.REQUEST_STEP_INTO.equals(inputLine))
				{
					debugger.stepInto();
				}
				else if (DebugConstants.REQUEST_STEP_OVER.equals(inputLine))
				{
					debugger.stepOver();
				}
				else if (DebugConstants.REQUEST_STEP_RETURN.equals(inputLine))
				{
					debugger.stepReturn();
				}
				else if (DebugConstants.REQUEST_SUSPEND.equals(inputLine))
				{
					debugger.suspend();
				}
				else if (DebugConstants.REQUEST_RESUME.equals(inputLine))
				{
					debugger.resume();
				}
				else if (DebugConstants.REQUEST_STACK.equals(inputLine))
				{
					response = debugger.stack();
				}
				else if (inputLine.startsWith(DebugConstants.REQUEST_VARIABLE))
				{
					String data = inputLine.substring(DebugConstants.REQUEST_VARIABLE.length() + 1);
					int id = Integer.parseInt(data);
					Variable var = debugger.getVariable(id);
					log.debug("var "+id+" = "+var); //$NON-NLS-1$ //$NON-NLS-2$
					response = var.getScope() + "&" + var.getName(); //$NON-NLS-1$
				}
				else if (inputLine.startsWith(DebugConstants.REQUEST_VALUE))
				{
					String data = inputLine.substring(DebugConstants.REQUEST_VALUE.length() + 1);
					int id = Integer.parseInt(data);
					Variable var = debugger.getVariable(id);
					response =  var.getType() + "&" + var.getValueFirstLine(); //$NON-NLS-1$
				}
				else if (inputLine.startsWith(DebugConstants.REQUEST_ADD_BREAKPOINT))
				{
					int index = inputLine.lastIndexOf(' ');
					String file = inputLine.substring(DebugConstants.REQUEST_ADD_BREAKPOINT.length() + 1, index);
					String line = inputLine.substring(index + 1);
					BreakPoint breakpoint = new BreakPoint(file, Integer.parseInt(line));
					debugger.addBreakpoint(breakpoint);
				}
				else if (inputLine.startsWith(DebugConstants.REQUEST_REMOVE_BREAKPOINT))
				{
					int index = inputLine.lastIndexOf(' ');
					String file = inputLine.substring(DebugConstants.REQUEST_REMOVE_BREAKPOINT.length() + 1, index);
					String line = inputLine.substring(index + 1);
					BreakPoint breakpoint = new BreakPoint(file, Integer.parseInt(line));
					debugger.removeBreakpoint(breakpoint);
				}
				else
				{
					response = "What?"; //$NON-NLS-1$
				}
				// confirm request
				log.debug("RESPONSE:" + response); //$NON-NLS-1$
				requestOut.write(response + "\n"); //$NON-NLS-1$
				requestOut.flush();

				/*
				 * if (REQUEST_QUIT.equals(inputLine)) { waitForFinish(debuggerThread); break; }
				 */
			}
		}
		catch (Exception e)
		{
			throw new TransformationException(e.getMessage(), e);
		}
		log.debug("exited loop"); //$NON-NLS-1$
		eventOut.write("terminated\n"); //$NON-NLS-1$
		eventOut.flush();
	}

	/**
	 * Dispose of this - close all open sockets.
	 * @throws IOException 
	 */
	public void dispose() throws IOException
	{
		if (requestIn != null)
		{
			try
			{
				requestIn.close();
			}
			catch (IOException e)
			{
				log.error("Could not close request input stream", e); //$NON-NLS-1$
			}
		}
		if (requestOut != null)
		{
			requestOut.close();
		}
		if (eventOut != null)
		{
			eventOut.close();
		}
		if (requestSocket != null)
		{
			try
			{
				requestSocket.close();
			}
			catch (IOException e)
			{
				log.error("Could not close request socket", e); //$NON-NLS-1$
			}
		}
		if (eventSocket != null)
		{
			try
			{
				eventSocket.close();
			}
			catch (IOException e)
			{
				log.error("Could not close event socket", e); //$NON-NLS-1$
			}
		}
	}

	private static Socket getSocket(int port) throws IOException
	{
		InetAddress localhost = InetAddress.getByName("localhost"); //$NON-NLS-1$
		ServerSocket serverSocket = new ServerSocket(port, 5, localhost);
		Socket clientSocket = serverSocket.accept();
		serverSocket.close();
		return clientSocket;
	}

	/**
	 * Expected arguments:
	 * 
	 * <ol>
	 * <li>the class name of the invoker
	 * <li>the file name of the XML launch configuration file
	 * <li>the URL of the source document
	 * <li>the file of the output document
	 * <li>not used (anything)
	 * <li>the class name of the <code>IXSLDebugger</code> instance
	 * <li>the port used for requests
	 * <li>the port used for debug events
	 * <li>the port used for generate events
	 * </ol>
	 * 
	 * @param args
	 */
	public static void main(String[] args)
	{
		log.info("javax.xml.transform.TransformerFactory=" + System.getProperty("javax.xml.transform.TransformerFactory"));  //$NON-NLS-1$//$NON-NLS-2$
		log.info("java.endorsed.dirs=" + System.getProperty("java.endorsed.dirs"));  //$NON-NLS-1$//$NON-NLS-2$

		String invokerClassName = args[0];
		File launchFile = new File(args[1]);
		String src = args[2];
		String target = args[3];
		String debuggerClassName = args[5];

		log.info("src: " + src); //$NON-NLS-1$
		log.info("target: " + target); //$NON-NLS-1$
		log.info("launchFile: " + launchFile); //$NON-NLS-1$
		log.info("debugger: " + debuggerClassName); //$NON-NLS-1$

		DebugRunner debugRunner = null;
		try
		{
			final IXSLDebugger debugger = createDebugger(debuggerClassName);
			// create the invoker
			IProcessorInvoker invoker = new JAXPSAXProcessorInvoker()
			{

				protected TransformerFactory createTransformerFactory()
				{
					TransformerFactory tFactory = super.createTransformerFactory();
					debugger.setTransformerFactory(tFactory);
					return tFactory;
				}

				public void addStylesheet(URL stylesheet, Map parameters, Properties outputProperties, URIResolver resolver) throws TransformerConfigurationException
				{
					InputSource inputsource = new InputSource(stylesheet.toString());
					// if required in future, parse the document with line numbers (to get the end line numbers)
//					XMLReaderWrapper reader = new XMLReaderWrapper(createReader());
//					SAXSource source = new SAXSource(reader,inputsource);
					addStylesheet(new SAXSource(inputsource), resolver, parameters, outputProperties);
				}
				
				protected Transformer addStylesheet(Source source, URIResolver resolver, Map parameters, Properties outputProperties) throws TransformerConfigurationException
				{
					Transformer transformer = super.addStylesheet(source, resolver, parameters, outputProperties);
					debugger.addTransformer(transformer);
					return transformer;
				}
			};

			if (args.length == 9)
			{
				int requestPort = Integer.parseInt(args[6]);
				int eventPort = Integer.parseInt(args[7]);
				int generatePort = Integer.parseInt(args[8]);

				log.debug("requestPort: " + requestPort); //$NON-NLS-1$
				log.debug("eventPort: " + eventPort); //$NON-NLS-1$
				log.debug("generatePort: " + generatePort); //$NON-NLS-1$

				try
				{
					debugRunner = new DebugRunner(requestPort, eventPort, generatePort);
				}
				catch (Exception e)
				{
					handleFatalError("Could not instantiate invoker: " + invokerClassName, e); //$NON-NLS-1$
				}
			}
			else
			{
				BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
				debugRunner = new DebugRunner(br, new PrintWriter(System.out), new PrintWriter(System.err), null);
				System.out.println("xsl>"); //$NON-NLS-1$
			}

			PipelineDefinition pipeline = new PipelineDefinition(launchFile);
			pipeline.configure(invoker);

			debugger.setInvoker(invoker);
			debugger.setSource(new URL(src));
			debugger.setTarget(new FileWriter(new File(target)));

			debugRunner.loop(debugger);
		}
		catch (Exception e)
		{
			handleFatalError(e.getMessage(), e);
		}
		finally
		{
			if (debugRunner != null)
			{
				try
				{
					debugRunner.dispose();
				}
				catch (IOException e)
				{
					handleFatalError(e.getMessage(), e);
				}
			}
		}
	}

	private static IXSLDebugger createDebugger(String classname) throws ClassNotFoundException, InstantiationException, IllegalAccessException
	{
		Class clazz = Class.forName(classname);
		return (IXSLDebugger) clazz.newInstance();
	}

	private static void handleFatalError(String msg, Throwable t)
	{
		log.fatal(msg, t);
		System.exit(1);
	}
}
