/*
 * 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.ReadInt32();
                }
            }
            else
            {
                if (bs.ReadBoolean())
                {
                    return dataIn.ReadInt16();
                }
                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)
        {
            /*
             if (wireFormat.isCacheEnabled()) {
             if (bs.ReadBoolean()) {
             short index = dataIndataIn.ReadInt16()Int16();
             DataStructure value = wireFormat.UnmarshalNestedObject(dataIn, bs);
             wireFormat.setInUnmarshallCache(index, value);
             return value;
             } else {
             short index = dataIn.ReadInt16();
             return wireFormat.getFromUnmarshallCache(index);
             }
             } else {
             return wireFormat.UnmarshalNestedObject(dataIn, bs);
             }
             */
            return wireFormat.LooseUnmarshalNestedObject(dataIn);
        }
        
        
        protected virtual void LooseMarshalCachedObject(
            OpenWireFormat wireFormat,
            DataStructure o,
            BinaryWriter dataOut)
        {
            /*
             if (wireFormat.isCacheEnabled()) {
             Short index = wireFormat.getMarshallCacheIndex(o);
             if (bs.ReadBoolean()) {
             dataOut.Write(index.shortValue(), dataOut);
             wireFormat.Marshal2NestedObject(o, dataOut, bs);
             } else {
             dataOut.Write(index.shortValue(), dataOut);
             }
             } else {
             wireFormat.Marshal2NestedObject(o, dataOut, bs);
             }
             */
            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();
        }
        
    }
}

