/*
 [The "BSD license"]
 Copyright (c) 2005-2009 Terence Parr
 All rights reserved.

 Redistribution and use in source and binary forms, with or without
 modification, are permitted provided that the following conditions
 are met:
 1. Redistributions of source code must retain the above copyright
     notice, this list of conditions and the following disclaimer.
 2. Redistributions in binary form must reproduce the above copyright
     notice, this list of conditions and the following disclaimer in the
     documentation and/or other materials provided with the distribution.
 3. The name of the author may not be used to endorse or promote products
     derived from this software without specific prior written permission.

 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
package org.antlr.runtime.debug;

import org.antlr.runtime.RecognitionException;
import org.antlr.runtime.Token;
import org.antlr.runtime.BaseRecognizer;
import org.antlr.runtime.tree.TreeAdaptor;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;

/** A proxy debug event listener that forwards events over a socket to
 *  a debugger (or any other listener) using a simple text-based protocol;
 *  one event per line.  ANTLRWorks listens on server socket with a
 *  RemoteDebugEventSocketListener instance.  These two objects must therefore
 *  be kept in sync.  New events must be handled on both sides of socket.
 */
public class DebugEventSocketProxy extends BlankDebugEventListener {
	public static final int DEFAULT_DEBUGGER_PORT = 49100; // was 49153
	protected int port = DEFAULT_DEBUGGER_PORT;
	protected ServerSocket serverSocket;
	protected Socket socket;
	protected String grammarFileName;
	protected PrintWriter out;
	protected BufferedReader in;

	/** Who am i debugging? */
	protected BaseRecognizer recognizer;

	/** Almost certainly the recognizer will have adaptor set, but
	 *  we don't know how to cast it (Parser or TreeParser) to get
	 *  the adaptor field.  Must be set with a constructor. :(
	 */
	protected TreeAdaptor adaptor;

	public DebugEventSocketProxy(BaseRecognizer recognizer, TreeAdaptor adaptor) {
		this(recognizer, DEFAULT_DEBUGGER_PORT, adaptor);
	}

	public DebugEventSocketProxy(BaseRecognizer recognizer, int port, TreeAdaptor adaptor) {
		this.grammarFileName = recognizer.getGrammarFileName();
		this.adaptor = adaptor;
		this.port = port;
	}

	public void handshake() throws IOException {
		if ( serverSocket==null ) {
			serverSocket = new ServerSocket(port);
			socket = serverSocket.accept();
			socket.setTcpNoDelay(true);
			OutputStream os = socket.getOutputStream();
			OutputStreamWriter osw = new OutputStreamWriter(os, "UTF8");
			out = new PrintWriter(new BufferedWriter(osw));
			InputStream is = socket.getInputStream();
			InputStreamReader isr = new InputStreamReader(is, "UTF8");
			in = new BufferedReader(isr);
			out.println("ANTLR "+ DebugEventListener.PROTOCOL_VERSION);
			out.println("grammar \""+ grammarFileName);
			out.flush();
			ack();
		}
	}

	public void commence() {
		// don't bother sending event; listener will trigger upon connection
	}

	public void terminate() {
		transmit("terminate");
		out.close();
		try {
			socket.close();
		}
		catch (IOException ioe) {
			ioe.printStackTrace(System.err);
		}
	}

	protected void ack() {
		try {
			in.readLine();
		}
		catch (IOException ioe) {
			ioe.printStackTrace(System.err);
		}
	}

	protected void transmit(String event) {
		out.println(event);
		out.flush();
		ack();
	}

	public void enterRule(String grammarFileName, String ruleName) {
		transmit("enterRule\t"+grammarFileName+"\t"+ruleName);
	}

	public void enterAlt(int alt) {
		transmit("enterAlt\t"+alt);
	}

	public void exitRule(String grammarFileName, String ruleName) {
		transmit("exitRule\t"+grammarFileName+"\t"+ruleName);
	}

	public void enterSubRule(int decisionNumber) {
		transmit("enterSubRule\t"+decisionNumber);
	}

	public void exitSubRule(int decisionNumber) {
		transmit("exitSubRule\t"+decisionNumber);
	}

	public void enterDecision(int decisionNumber, boolean couldBacktrack) {
		transmit("enterDecision\t"+decisionNumber+"\t"+couldBacktrack);
	}

	public void exitDecision(int decisionNumber) {
		transmit("exitDecision\t"+decisionNumber);
	}

	public void consumeToken(Token t) {
		String buf = serializeToken(t);
		transmit("consumeToken\t"+buf);
	}

	public void consumeHiddenToken(Token t) {
		String buf = serializeToken(t);
		transmit("consumeHiddenToken\t"+buf);
	}

	public void LT(int i, Token t) {
        if(t != null)
            transmit("LT\t"+i+"\t"+serializeToken(t));
	}

	public void mark(int i) {
		transmit("mark\t"+i);
	}

	public void rewind(int i) {
		transmit("rewind\t"+i);
	}

	public void rewind() {
		transmit("rewind");
	}

	public void beginBacktrack(int level) {
		transmit("beginBacktrack\t"+level);
	}

	public void endBacktrack(int level, boolean successful) {
		transmit("endBacktrack\t"+level+"\t"+(successful?TRUE:FALSE));
	}

	public void location(int line, int pos) {
		transmit("location\t"+line+"\t"+pos);
	}

	public void recognitionException(RecognitionException e) {
		StringBuffer buf = new StringBuffer(50);
		buf.append("exception\t");
		buf.append(e.getClass().getName());
		// dump only the data common to all exceptions for now
		buf.append("\t");
		buf.append(e.index);
		buf.append("\t");
		buf.append(e.line);
		buf.append("\t");
		buf.append(e.charPositionInLine);
		transmit(buf.toString());
	}

	public void beginResync() {
		transmit("beginResync");
	}

	public void endResync() {
		transmit("endResync");
	}

	public void semanticPredicate(boolean result, String predicate) {
		StringBuffer buf = new StringBuffer(50);
		buf.append("semanticPredicate\t");
		buf.append(result);
		serializeText(buf, predicate);
		transmit(buf.toString());
	}

	// A S T  P a r s i n g  E v e n t s

	public void consumeNode(Object t) {
		StringBuffer buf = new StringBuffer(50);
		buf.append("consumeNode");
		serializeNode(buf, t);
		transmit(buf.toString());
	}

	public void LT(int i, Object t) {
		int ID = adaptor.getUniqueID(t);
		String text = adaptor.getText(t);
		int type = adaptor.getType(t);
		StringBuffer buf = new StringBuffer(50);
		buf.append("LN\t"); // lookahead node; distinguish from LT in protocol
		buf.append(i);
		serializeNode(buf, t);
		transmit(buf.toString());
	}

	protected void serializeNode(StringBuffer buf, Object t) {
		int ID = adaptor.getUniqueID(t);
		String text = adaptor.getText(t);
		int type = adaptor.getType(t);
		buf.append("\t");
		buf.append(ID);
		buf.append("\t");
		buf.append(type);
		Token token = adaptor.getToken(t);
		int line = -1;
		int pos = -1;
		if ( token!=null ) {
			line = token.getLine();
			pos = token.getCharPositionInLine();
		}
		buf.append("\t");
		buf.append(line);
		buf.append("\t");
		buf.append(pos);
		int tokenIndex = adaptor.getTokenStartIndex(t);
		buf.append("\t");
		buf.append(tokenIndex);
		serializeText(buf, text);
	}


	// A S T  E v e n t s

	public void nilNode(Object t) {
		int ID = adaptor.getUniqueID(t);
		transmit("nilNode\t"+ID);
	}

	public void errorNode(Object t) {
		int ID = adaptor.getUniqueID(t);
		String text = t.toString();
		StringBuffer buf = new StringBuffer(50);
		buf.append("errorNode\t");
		buf.append(ID);
		buf.append("\t");
		buf.append(Token.INVALID_TOKEN_TYPE);
		serializeText(buf, text);
		transmit(buf.toString());
	}

	public void createNode(Object t) {
		int ID = adaptor.getUniqueID(t);
		String text = adaptor.getText(t);
		int type = adaptor.getType(t);
		StringBuffer buf = new StringBuffer(50);
		buf.append("createNodeFromTokenElements\t");
		buf.append(ID);
		buf.append("\t");
		buf.append(type);
		serializeText(buf, text);
		transmit(buf.toString());
	}

	public void createNode(Object node, Token token) {
		int ID = adaptor.getUniqueID(node);
		int tokenIndex = token.getTokenIndex();
		transmit("createNode\t"+ID+"\t"+tokenIndex);
	}

	public void becomeRoot(Object newRoot, Object oldRoot) {
		int newRootID = adaptor.getUniqueID(newRoot);
		int oldRootID = adaptor.getUniqueID(oldRoot);
		transmit("becomeRoot\t"+newRootID+"\t"+oldRootID);
	}

	public void addChild(Object root, Object child) {
		int rootID = adaptor.getUniqueID(root);
		int childID = adaptor.getUniqueID(child);
		transmit("addChild\t"+rootID+"\t"+childID);
	}

	public void setTokenBoundaries(Object t, int tokenStartIndex, int tokenStopIndex) {
		int ID = adaptor.getUniqueID(t);
		transmit("setTokenBoundaries\t"+ID+"\t"+tokenStartIndex+"\t"+tokenStopIndex);
	}


    // support

    public void setTreeAdaptor(TreeAdaptor adaptor) { this.adaptor = adaptor; }
    public TreeAdaptor getTreeAdaptor() { return adaptor; }

    protected String serializeToken(Token t) {
        StringBuffer buf = new StringBuffer(50);
        buf.append(t.getTokenIndex()); buf.append('\t');
        buf.append(t.getType()); buf.append('\t');
        buf.append(t.getChannel()); buf.append('\t');
        buf.append(t.getLine()); buf.append('\t');
		buf.append(t.getCharPositionInLine());
		serializeText(buf, t.getText());
		return buf.toString();
	}

	protected void serializeText(StringBuffer buf, String text) {
		buf.append("\t\"");
		if ( text==null ) {
			text = "";
		}
		// escape \n and \r all text for token appears to exist on one line
		// this escape is slow but easy to understand
		text = escapeNewlines(text);
		buf.append(text);
	}

	protected String escapeNewlines(String txt) {
		txt = txt.replaceAll("%","%25");   // escape all escape char ;)
		txt = txt.replaceAll("\n","%0A");  // escape \n
		txt = txt.replaceAll("\r","%0D");  // escape \r
		return txt;
	}
}

