/*
 * Note to JL: Removed extension call syntax
 * 
 * [The "BSD licence"]
 * Copyright (c) 2005-2008 Terence Parr
 * All rights reserved.
 *
 * Conversion to C#:
 * Copyright (c) 2008-2009 Sam Harwell, Pixel Mine, Inc.
 * 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.
 */

namespace Antlr.Runtime.Debug {
    using System;
    using Antlr.Runtime.JavaExtensions;

    using IOException = System.IO.IOException;
    using ITreeAdaptor = Antlr.Runtime.Tree.ITreeAdaptor;
    using Socket = System.Net.Sockets.Socket;
    using StringBuilder = System.Text.StringBuilder;
    using TcpListener = System.Net.Sockets.TcpListener;

    /** <summary>
     *  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.
     *  </summary>
     */
    public class DebugEventSocketProxy : BlankDebugEventListener {
        public const int DefaultDebuggerPort = 49100;
        protected int port = DefaultDebuggerPort;
        protected TcpListener serverSocket;
        protected Socket socket;
        protected string grammarFileName;
        //protected PrintWriter @out;
        //protected BufferedReader @in;

        /** <summary>Who am i debugging?</summary> */
        protected BaseRecognizer recognizer;

        /** <summary>
         *  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. :(
         *  </summary>
         */
        protected ITreeAdaptor adaptor;

        public DebugEventSocketProxy(BaseRecognizer recognizer, ITreeAdaptor adaptor) :
            this(recognizer, DefaultDebuggerPort, adaptor) {
        }

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

        #region Properties
        public virtual ITreeAdaptor TreeAdaptor {
            get {
                return adaptor;
            }
            set {
                adaptor = value;
            }
        }
        #endregion

        public virtual void Handshake() {
            if (serverSocket == null) {
                System.Net.IPHostEntry hostInfo = System.Net.Dns.GetHostEntry("localhost");
                System.Net.IPAddress ipAddress = hostInfo.AddressList[0];
                serverSocket = new TcpListener(ipAddress, port);
                socket = serverSocket.AcceptSocket();
                socket.NoDelay = true;

                System.Text.UTF8Encoding encoding = new System.Text.UTF8Encoding();
                socket.Send(encoding.GetBytes("ANTLR " + DebugEventListenerConstants.ProtocolVersion + "\n"));
                socket.Send(encoding.GetBytes("grammar \"" + grammarFileName + "\n"));
                Ack();

                //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 " + DebugEventListenerConstants.PROTOCOL_VERSION );
                //@out.println( "grammar \"" + grammarFileName );
                //@out.flush();
                //ack();
            }
        }

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

        public override void Terminate() {
            Transmit("terminate");
            //@out.close();
            try {
                socket.Close();
            } catch (IOException ioe) {
                ExceptionExtensions.PrintStackTrace(ioe, Console.Error);
            }
        }

        protected virtual void Ack() {
            try {
                throw new NotImplementedException();
                //@in.readLine();
            } catch (IOException ioe) {
                ExceptionExtensions.PrintStackTrace(ioe, Console.Error);
            }
        }

        protected virtual void Transmit(string @event) {
            socket.Send(new System.Text.UTF8Encoding().GetBytes(@event + "\n"));
            //@out.println( @event );
            //@out.flush();
            Ack();
        }

        public override void EnterRule(string grammarFileName, string ruleName) {
            Transmit("enterRule\t" + grammarFileName + "\t" + ruleName);
        }

        public override void EnterAlt(int alt) {
            Transmit("enterAlt\t" + alt);
        }

        public override void ExitRule(string grammarFileName, string ruleName) {
            Transmit("exitRule\t" + grammarFileName + "\t" + ruleName);
        }

        public override void EnterSubRule(int decisionNumber) {
            Transmit("enterSubRule\t" + decisionNumber);
        }

        public override void ExitSubRule(int decisionNumber) {
            Transmit("exitSubRule\t" + decisionNumber);
        }

        public override void EnterDecision(int decisionNumber, bool couldBacktrack) {
            Transmit("enterDecision\t" + decisionNumber);
        }

        public override void ExitDecision(int decisionNumber) {
            Transmit("exitDecision\t" + decisionNumber);
        }

        public override void ConsumeToken(IToken t) {
            string buf = SerializeToken(t);
            Transmit("consumeToken\t" + buf);
        }

        public override void ConsumeHiddenToken(IToken t) {
            string buf = SerializeToken(t);
            Transmit("consumeHiddenToken\t" + buf);
        }

        public override void LT(int i, IToken t) {
            if (t != null)
                Transmit("LT\t" + i + "\t" + SerializeToken(t));
        }

        public override void Mark(int i) {
            Transmit("mark\t" + i);
        }

        public override void Rewind(int i) {
            Transmit("rewind\t" + i);
        }

        public override void Rewind() {
            Transmit("rewind");
        }

        public override void BeginBacktrack(int level) {
            Transmit("beginBacktrack\t" + level);
        }

        public override void EndBacktrack(int level, bool successful) {
            Transmit("endBacktrack\t" + level + "\t" + (successful ? DebugEventListenerConstants.True : DebugEventListenerConstants.False));
        }

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

        public override void RecognitionException(RecognitionException e) {
            StringBuilder buf = new StringBuilder(50);
            buf.Append("exception\t");
            buf.Append(e.GetType().Name);
            // 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 override void BeginResync() {
            Transmit("beginResync");
        }

        public override void EndResync() {
            Transmit("endResync");
        }

        public override void SemanticPredicate(bool result, string predicate) {
            StringBuilder buf = new StringBuilder(50);
            buf.Append("semanticPredicate\t");
            buf.Append(result);
            SerializeText(buf, predicate);
            Transmit(buf.ToString());
        }

        #region AST Parsing Events

        public override void ConsumeNode(object t) {
            StringBuilder buf = new StringBuilder(50);
            buf.Append("consumeNode");
            SerializeNode(buf, t);
            Transmit(buf.ToString());
        }

        public override void LT(int i, object t) {
            int ID = adaptor.GetUniqueID(t);
            string text = adaptor.GetText(t);
            int type = adaptor.GetType(t);
            StringBuilder buf = new StringBuilder(50);
            buf.Append("LN\t"); // lookahead node; distinguish from LT in protocol
            buf.Append(i);
            SerializeNode(buf, t);
            Transmit(buf.ToString());
        }

        protected virtual void SerializeNode(StringBuilder 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);
            IToken token = adaptor.GetToken(t);
            int line = -1;
            int pos = -1;
            if (token != null) {
                line = token.Line;
                pos = token.CharPositionInLine;
            }
            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);
        }

        #endregion


        #region AST Events

        public override void NilNode(object t) {
            int ID = adaptor.GetUniqueID(t);
            Transmit("nilNode\t" + ID);
        }

        public override void ErrorNode(object t) {
            int ID = adaptor.GetUniqueID(t);
            string text = t.ToString();
            StringBuilder buf = new StringBuilder(50);
            buf.Append("errorNode\t");
            buf.Append(ID);
            buf.Append("\t");
            buf.Append(TokenTypes.Invalid);
            SerializeText(buf, text);
            Transmit(buf.ToString());
        }

        public override void CreateNode(object t) {
            int ID = adaptor.GetUniqueID(t);
            string text = adaptor.GetText(t);
            int type = adaptor.GetType(t);
            StringBuilder buf = new StringBuilder(50);
            buf.Append("createNodeFromTokenElements\t");
            buf.Append(ID);
            buf.Append("\t");
            buf.Append(type);
            SerializeText(buf, text);
            Transmit(buf.ToString());
        }

        public override void CreateNode(object node, IToken token) {
            int ID = adaptor.GetUniqueID(node);
            int tokenIndex = token.TokenIndex;
            Transmit("createNode\t" + ID + "\t" + tokenIndex);
        }

        public override void BecomeRoot(object newRoot, object oldRoot) {
            int newRootID = adaptor.GetUniqueID(newRoot);
            int oldRootID = adaptor.GetUniqueID(oldRoot);
            Transmit("becomeRoot\t" + newRootID + "\t" + oldRootID);
        }

        public override void AddChild(object root, object child) {
            int rootID = adaptor.GetUniqueID(root);
            int childID = adaptor.GetUniqueID(child);
            Transmit("addChild\t" + rootID + "\t" + childID);
        }

        public override void SetTokenBoundaries(object t, int tokenStartIndex, int tokenStopIndex) {
            int ID = adaptor.GetUniqueID(t);
            Transmit("setTokenBoundaries\t" + ID + "\t" + tokenStartIndex + "\t" + tokenStopIndex);
        }

        #endregion


        #region Support

        protected virtual string SerializeToken(IToken t) {
            StringBuilder buf = new StringBuilder(50);
            buf.Append(t.TokenIndex);
            buf.Append('\t');
            buf.Append(t.Type);
            buf.Append('\t');
            buf.Append(t.Channel);
            buf.Append('\t');
            buf.Append(t.Line);
            buf.Append('\t');
            buf.Append(t.CharPositionInLine);
            SerializeText(buf, t.Text);
            return buf.ToString();
        }

        protected virtual void SerializeText(StringBuilder 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 virtual string EscapeNewlines(string txt) {
            txt = StringExtensions.replaceAll(txt, "%", "%25");   // escape all escape char ;)
            txt = StringExtensions.replaceAll(txt, "\n", "%0A");  // escape \n
            txt = StringExtensions.replaceAll(txt, "\r", "%0D");  // escape \r
            return txt;
        }

        #endregion
    }
}
