/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
using Apache.NMS.ActiveMQ.Commands;
using System;
using System.IO;
using System.Text;

namespace Apache.NMS.ActiveMQ.OpenWire

{
    /// <summary>
    /// A base class with useful implementation inheritence methods
    /// for creating marshallers of the OpenWire protocol
    /// </summary>
    public abstract class BaseDataStreamMarshaller
    {
        private static readonly String[] HEX_TABLE = new String[]{
            "00", "01", "02", "03", "04", "05", "06", "07", "08", "09", "0a", "0b", "0c", "0d", "0e", "0f",
            "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "1a", "1b", "1c", "1d", "1e", "1f",
            "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "2a", "2b", "2c", "2d", "2e", "2f",
            "30", "31", "32", "33", "34", "35", "36", "37", "38", "39", "3a", "3b", "3c", "3d", "3e", "3f",
            "40", "41", "42", "43", "44", "45", "46", "47", "48", "49", "4a", "4b", "4c", "4d", "4e", "4f",
            "50", "51", "52", "53", "54", "55", "56", "57", "58", "59", "5a", "5b", "5c", "5d", "5e", "5f",
            "60", "61", "62", "63", "64", "65", "66", "67", "68", "69", "6a", "6b", "6c", "6d", "6e", "6f",
            "70", "71", "72", "73", "74", "75", "76", "77", "78", "79", "7a", "7b", "7c", "7d", "7e", "7f",
            "80", "81", "82", "83", "84", "85", "86", "87", "88", "89", "8a", "8b", "8c", "8d", "8e", "8f",
            "90", "91", "92", "93", "94", "95", "96", "97", "98", "99", "9a", "9b", "9c", "9d", "9e", "9f",
            "a0", "a1", "a2", "a3", "a4", "a5", "a6", "a7", "a8", "a9", "aa", "ab", "ac", "ad", "ae", "af",
            "b0", "b1", "b2", "b3", "b4", "b5", "b6", "b7", "b8", "b9", "ba", "bb", "bc", "bd", "be", "bf",
            "c0", "c1", "c2", "c3", "c4", "c5", "c6", "c7", "c8", "c9", "ca", "cb", "cc", "cd", "ce", "cf",
            "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "d8", "d9", "da", "db", "dc", "dd", "de", "df",
            "e0", "e1", "e2", "e3", "e4", "e5", "e6", "e7", "e8", "e9", "ea", "eb", "ec", "ed", "ee", "ef",
            "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", "f8", "f9", "fa", "fb", "fc", "fd", "fe", "ff",
        };
        
        public abstract DataStructure CreateObject();
        public abstract byte GetDataStructureType();
        
        public virtual int TightMarshal1(OpenWireFormat wireFormat, Object o, BooleanStream bs)
        {
            return 0;
        }

        public virtual void TightMarshal2(
            OpenWireFormat wireFormat,
            Object o,
            BinaryWriter dataOut,
            BooleanStream bs)
        {
        }
        
        public virtual void TightUnmarshal(
            OpenWireFormat wireFormat,
            Object o,
            BinaryReader dataIn,
            BooleanStream bs)
        {
        }

        protected virtual DataStructure TightUnmarshalNestedObject(
            OpenWireFormat wireFormat,
            BinaryReader dataIn,
            BooleanStream bs)
        {
            return wireFormat.TightUnmarshalNestedObject(dataIn, bs);
        }
        
        protected virtual int TightMarshalNestedObject1(
            OpenWireFormat wireFormat,
            DataStructure o,
            BooleanStream bs)
        {
            return wireFormat.TightMarshalNestedObject1(o, bs);
        }
        
        protected virtual void TightMarshalNestedObject2(
            OpenWireFormat wireFormat,
            DataStructure o,
            BinaryWriter dataOut,
            BooleanStream bs)
        {
            wireFormat.TightMarshalNestedObject2(o, dataOut, bs);
        }
        
        protected virtual DataStructure TightUnmarshalCachedObject(
            OpenWireFormat wireFormat,
            BinaryReader dataIn,
            BooleanStream bs)
        {
            return wireFormat.TightUnmarshalNestedObject(dataIn, bs);
        }
        
        protected virtual int TightMarshalCachedObject1(
            OpenWireFormat wireFormat,
            DataStructure o,
            BooleanStream bs)
        {
            return wireFormat.TightMarshalNestedObject1(o, bs);
        }
        
        protected virtual void TightMarshalCachedObject2(
            OpenWireFormat wireFormat,
            DataStructure o,
            BinaryWriter dataOut,
            BooleanStream bs)
        {
            wireFormat.TightMarshalNestedObject2(o, dataOut, bs);
        }
        
        protected virtual String TightUnmarshalString(BinaryReader dataIn, BooleanStream bs)
        {
            if(bs.ReadBoolean())
            {
                if(bs.ReadBoolean())
                {
                    return ReadAsciiString(dataIn);
                }
                else
                {
                    return dataIn.ReadString();
                }
            }
            else
            {
                return null;
            }
        }
                
        protected virtual int TightMarshalString1(String value, BooleanStream bs)
        {
            bs.WriteBoolean(value != null);
            if (value != null)
            {
                int strlen = value.Length;
                
                int utflen = 0;
                int c = 0;
                bool isOnlyAscii = true;
                char[] charr = value.ToCharArray();
                for (int i = 0; i < strlen; i++)
                {
                    c = charr[i];
                    if ((c >= 0x0001) && (c <= 0x007F))
                    {
                        utflen++;
                    }
                    else if (c > 0x07FF)
                    {
                        utflen += 3;
                        isOnlyAscii = false;
                    }
                    else
                    {
                        isOnlyAscii = false;
                        utflen += 2;
                    }
                }
                
                if (utflen >= Int16.MaxValue)
                    throw new IOException("Encountered a String value that is too long to encode.");
                
                bs.WriteBoolean(isOnlyAscii);
                return utflen + 2;
            }
            else
            {
                return 0;
            }
        }
        
        public static void TightMarshalString2(String value, BinaryWriter dataOut, BooleanStream bs)
        {
            if (bs.ReadBoolean())
            {
                // If we verified it only holds ascii values
                if (bs.ReadBoolean())
                {
                    dataOut.Write((short) value.Length);
                    // now lets write the bytes
                    char[] chars = value.ToCharArray();
                    for (int i = 0; i < chars.Length; i++)
                    {
                        dataOut.Write((byte)(chars[i]&0xFF00>>8));
                    }
                }
                else
                {
                    dataOut.Write(value);
                }
            }
        }
                
        public virtual int TightMarshalLong1(OpenWireFormat wireFormat, long o, BooleanStream bs)
        {
            if (o == 0L)
            {
                bs.WriteBoolean(false);
                bs.WriteBoolean(false);
                return 0;
            }
            else
            {
                ulong ul = (ulong) o;
                if ((ul & 0xFFFFFFFFFFFF0000ul) == 0L)
                {
                    bs.WriteBoolean(false);
                    bs.WriteBoolean(true);
                    return 2;
                }
                else if ((ul & 0xFFFFFFFF00000000ul) == 0L)
                {
                    bs.WriteBoolean(true);
                    bs.WriteBoolean(false);
                    return 4;
                }
                else
                {
                    bs.WriteBoolean(true);
                    bs.WriteBoolean(true);
                    return 8;
                }
            }
        }
        
        public virtual void TightMarshalLong2(
            OpenWireFormat wireFormat,
            long o,
            BinaryWriter dataOut,
            BooleanStream bs)
        {
            if (bs.ReadBoolean())
            {
                if (bs.ReadBoolean())
                {
                    dataOut.Write(o);
                }
                else
                {
                    dataOut.Write((int)o);
                }
            }
            else
            {
                if (bs.ReadBoolean())
                {
                    dataOut.Write((short)o);
                }
            }
        }

        public virtual long TightUnmarshalLong(OpenWireFormat wireFormat, BinaryReader dataIn, BooleanStream bs)
        {
            if (bs.ReadBoolean())
            {
                if (bs.ReadBoolean())
                {
                    return dataIn.ReadInt64(); // dataIn.ReadInt64();
                }
                else
                {
                    return dataIn.ReadUInt32();
                }
            }
            else
            {
                if (bs.ReadBoolean())
                {
                    return dataIn.ReadUInt16();
                }
                else
                {
                    return 0;
                }
            }
        }

        protected virtual int TightMarshalObjectArray1(
            OpenWireFormat wireFormat,
            DataStructure[] objects,
            BooleanStream bs)
        {
            if (objects != null)
            {
                int rc = 0;
                bs.WriteBoolean(true);
                rc += 2;
                for (int i = 0; i < objects.Length; i++)
                {
                    rc += TightMarshalNestedObject1(wireFormat, objects[i], bs);
                }
                return rc;
            }
            else
            {
                bs.WriteBoolean(false);
                return 0;
            }
        }
        
        protected virtual void TightMarshalObjectArray2(
            OpenWireFormat wireFormat,
            DataStructure[] objects,
            BinaryWriter dataOut,
            BooleanStream bs)
        {
            if (bs.ReadBoolean())
            {
                dataOut.Write((short) objects.Length);
                for (int i = 0; i < objects.Length; i++)
                {
                    TightMarshalNestedObject2(wireFormat, objects[i], dataOut, bs);
                }
            }
        }
        
        protected virtual BrokerError TightUnmarshalBrokerError(
            OpenWireFormat wireFormat,
            BinaryReader dataIn,
            BooleanStream bs)
        {
            if (bs.ReadBoolean())
            {
                BrokerError answer = new BrokerError();
                
                answer.ExceptionClass = TightUnmarshalString(dataIn, bs);
                answer.Message = TightUnmarshalString(dataIn, bs);
                if (wireFormat.StackTraceEnabled)
                {
                    short length = dataIn.ReadInt16();
                    StackTraceElement[] stackTrace = new StackTraceElement[length];
                    for (int i = 0; i < stackTrace.Length; i++)
                    {
                        StackTraceElement element = new StackTraceElement();
                        element.ClassName = TightUnmarshalString(dataIn, bs);
                        element.MethodName = TightUnmarshalString(dataIn, bs);
                        element.FileName = TightUnmarshalString(dataIn, bs);
                        element.LineNumber = dataIn.ReadInt32();
                        stackTrace[i] = element;
                    }
                    answer.StackTraceElements = stackTrace;
                    answer.Cause = TightUnmarshalBrokerError(wireFormat, dataIn, bs);
                }
                return answer;
            }
            else
            {
                return null;
            }
        }
        
        protected int TightMarshalBrokerError1(OpenWireFormat wireFormat, BrokerError o, BooleanStream bs)
        {
            if (o == null)
            {
                bs.WriteBoolean(false);
                return 0;
            }
            else
            {
                int rc = 0;
                bs.WriteBoolean(true);
                rc += TightMarshalString1(o.ExceptionClass, bs);
                rc += TightMarshalString1(o.Message, bs);
                if (wireFormat.StackTraceEnabled)
                {
                    rc += 2;
                    StackTraceElement[] stackTrace = o.StackTraceElements;
                    for (int i = 0; i < stackTrace.Length; i++)
                    {
                        StackTraceElement element = stackTrace[i];
                        rc += TightMarshalString1(element.ClassName, bs);
                        rc += TightMarshalString1(element.MethodName, bs);
                        rc += TightMarshalString1(element.FileName, bs);
                        rc += 4;
                    }
                    rc += TightMarshalBrokerError1(wireFormat, o.Cause, bs);
                }
                
                return rc;
            }
        }
        
        protected void TightMarshalBrokerError2(
            OpenWireFormat wireFormat,
            BrokerError o,
            BinaryWriter dataOut,
            BooleanStream bs)
        {
            if (bs.ReadBoolean())
            {
                TightMarshalString2(o.ExceptionClass, dataOut, bs);
                TightMarshalString2(o.Message, dataOut, bs);
                if (wireFormat.StackTraceEnabled)
                {
                    StackTraceElement[] stackTrace = o.StackTraceElements;
                    dataOut.Write((short) stackTrace.Length);
                    
                    for (int i = 0; i < stackTrace.Length; i++)
                    {
                        StackTraceElement element = stackTrace[i];
                        TightMarshalString2(element.ClassName, dataOut, bs);
                        TightMarshalString2(element.MethodName, dataOut, bs);
                        TightMarshalString2(element.FileName, dataOut, bs);
                        dataOut.Write(element.LineNumber);
                    }
                    TightMarshalBrokerError2(wireFormat, o.Cause, dataOut, bs);
                }
            }
        }

        public virtual void LooseMarshal(
            OpenWireFormat wireFormat,
            Object o,
            BinaryWriter dataOut)
        {
        }
        
        public virtual void LooseUnmarshal(
            OpenWireFormat wireFormat,
            Object o,
            BinaryReader dataIn)
        {
        }
        
        protected virtual DataStructure LooseUnmarshalNestedObject(
            OpenWireFormat wireFormat,
            BinaryReader dataIn)
        {
            return wireFormat.LooseUnmarshalNestedObject(dataIn);
        }
        
        protected virtual void LooseMarshalNestedObject(
            OpenWireFormat wireFormat,
            DataStructure o,
            BinaryWriter dataOut)
        {
            wireFormat.LooseMarshalNestedObject(o, dataOut);
        }
        
        protected virtual DataStructure LooseUnmarshalCachedObject(
            OpenWireFormat wireFormat,
            BinaryReader dataIn)
        {
            return wireFormat.LooseUnmarshalNestedObject(dataIn);
        }

        protected virtual void LooseMarshalCachedObject(
            OpenWireFormat wireFormat,
            DataStructure o,
            BinaryWriter dataOut)
        {
            wireFormat.LooseMarshalNestedObject(o, dataOut);
        }

        protected virtual String LooseUnmarshalString(BinaryReader dataIn)
        {
            if (dataIn.ReadBoolean())
            {
                return dataIn.ReadString();
            }
            else
            {
                return null;
            }
        }

        public static void LooseMarshalString(String value, BinaryWriter dataOut)
        {
            dataOut.Write(value != null);
            if (value != null)
            {
                dataOut.Write(value);
            }
        }
                
        public virtual void LooseMarshalLong(
            OpenWireFormat wireFormat,
            long o,
            BinaryWriter dataOut)
        {
            dataOut.Write(o);
        }
        
        public virtual long LooseUnmarshalLong(OpenWireFormat wireFormat, BinaryReader dataIn)
        {
            return dataIn.ReadInt64();
        }
                
        protected virtual void LooseMarshalObjectArray(
            OpenWireFormat wireFormat,
            DataStructure[] objects,
            BinaryWriter dataOut)
        {
            dataOut.Write(objects!=null);
            if (objects!=null)
            {
                dataOut.Write((short) objects.Length);
                for (int i = 0; i < objects.Length; i++)
                {
                    LooseMarshalNestedObject(wireFormat, objects[i], dataOut);
                }
            }
        }
                
        protected virtual BrokerError LooseUnmarshalBrokerError(
            OpenWireFormat wireFormat,
            BinaryReader dataIn)
        {
            if (dataIn.ReadBoolean())
            {
                BrokerError answer = new BrokerError();
                
                answer.ExceptionClass = LooseUnmarshalString(dataIn);
                answer.Message = LooseUnmarshalString(dataIn);
                if (wireFormat.StackTraceEnabled)
                {
                    short length = dataIn.ReadInt16();
                    StackTraceElement[] stackTrace = new StackTraceElement[length];
                    for (int i = 0; i < stackTrace.Length; i++)
                    {
                        StackTraceElement element = new StackTraceElement();
                        element.ClassName = LooseUnmarshalString(dataIn);
                        element.MethodName = LooseUnmarshalString(dataIn);
                        element.FileName = LooseUnmarshalString(dataIn);
                        element.LineNumber = dataIn.ReadInt32();
                        stackTrace[i] = element;
                    }
                    answer.StackTraceElements = stackTrace;
                    answer.Cause = LooseUnmarshalBrokerError(wireFormat, dataIn);
                }
                return answer;
            }
            else
            {
                return null;
            }
        }
                
        protected void LooseMarshalBrokerError(
            OpenWireFormat wireFormat,
            BrokerError o,
            BinaryWriter dataOut)
        {
            dataOut.Write(o!=null);
            if (o!=null)
            {
                LooseMarshalString(o.ExceptionClass, dataOut);
                LooseMarshalString(o.Message, dataOut);
                if (wireFormat.StackTraceEnabled)
                {
                    StackTraceElement[] stackTrace = o.StackTraceElements;
                    dataOut.Write((short) stackTrace.Length);
                    
                    for (int i = 0; i < stackTrace.Length; i++)
                    {
                        StackTraceElement element = stackTrace[i];
                        LooseMarshalString(element.ClassName, dataOut);
                        LooseMarshalString(element.MethodName, dataOut);
                        LooseMarshalString(element.FileName, dataOut);
                        dataOut.Write(element.LineNumber);
                    }
                    LooseMarshalBrokerError(wireFormat, o.Cause, dataOut);
                }
            }
        }
        
        protected virtual byte[] ReadBytes(BinaryReader dataIn, bool flag)
        {
            if (flag)
            {
                int size = dataIn.ReadInt32();
                return dataIn.ReadBytes(size);
            }
            else
            {
                return null;
            }
        }
        
        protected virtual byte[] ReadBytes(BinaryReader dataIn)
        {
            int size = dataIn.ReadInt32();
            return dataIn.ReadBytes(size);
        }
        
        protected virtual byte[] ReadBytes(BinaryReader dataIn, int size)
        {
            return dataIn.ReadBytes(size);
        }
        
        protected virtual void WriteBytes(byte[] command, BinaryWriter dataOut)
        {
            dataOut.Write(command.Length);
            dataOut.Write(command);
        }
        
        protected virtual String ReadAsciiString(BinaryReader dataIn)
        {
            int size = dataIn.ReadInt16();
            byte[] data = new byte[size];
            dataIn.Read(data, 0, size);
            char[] text = new char[size];
            for (int i = 0; i < size; i++)
            {
                text[i] = (char) data[i];
            }
            return new String(text);
        }
        
        /// <summary>
        /// Converts the object to a String
        /// </summary>
        public static string ToString(MessageId id)
        {
            return ToString(id.ProducerId) + ":" + id.ProducerSequenceId;
        }

        /// <summary>
        /// Converts the object to a String
        /// </summary>
        public static string ToString(ProducerId id)
        {
            return id.ConnectionId + ":" + id.SessionId + ":" + id.Value;
        }
        
        /// <summary>
        /// Converts the given transaction ID into a String
        /// </summary>
        public static String ToString(TransactionId txnId)
        {
            if (txnId is LocalTransactionId)
            {
                LocalTransactionId ltxnId = (LocalTransactionId) txnId;
                return "" + ltxnId.Value;
            }
            else if (txnId is XATransactionId)
            {
                XATransactionId xaTxnId = (XATransactionId) txnId;
                return "XID:" + xaTxnId.FormatId + ":" + ToHexFromBytes(xaTxnId.GlobalTransactionId) + ":" + ToHexFromBytes(xaTxnId.BranchQualifier);
            }
            return null;
        }
        
        /// <summary>
        /// Creates the byte array into hexidecimal
        /// </summary>
        public static String ToHexFromBytes(byte[] data)
        {
            StringBuilder buffer = new StringBuilder(data.Length * 2);
            for (int i = 0; i < data.Length; i++)
            {
                buffer.Append(HEX_TABLE[0xFF & data[i]]);
            }
            return buffer.ToString();
        }
    }
}

