/*
 * 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 System;
using System.IO;

using Apache.NMS.Util;

namespace Apache.NMS.Stomp.Commands
{
    public class StreamMessage : Message, IStreamMessage
    {
        private EndianBinaryReader dataIn;
        private EndianBinaryWriter dataOut;
        private MemoryStream byteBuffer;
        private int bytesRemaining = -1;

        public override byte GetDataStructureType()
        {
            return DataStructureTypes.StreamMessageType;
        }

        public bool ReadBoolean()
        {
            InitializeReading();

            try
            {
                long startingPos = this.byteBuffer.Position;
                try
                {
                    int type = this.dataIn.ReadByte();

                    if(type == PrimitiveMap.BOOLEAN_TYPE)
                    {
                        return this.dataIn.ReadBoolean();
                    }
                    else if(type == PrimitiveMap.STRING_TYPE)
                    {
                        return Boolean.Parse(this.dataIn.ReadString16());
                    }
                    else if(type == PrimitiveMap.NULL)
                    {
                        this.byteBuffer.Seek(startingPos, SeekOrigin.Begin);
                        throw new NMSException("Cannot convert Null type to a bool");
                    }
                    else
                    {
                        this.byteBuffer.Seek(startingPos, SeekOrigin.Begin);
                        throw new MessageFormatException("Value is not a Boolean type.");
                    }
                }
                catch(FormatException e)
                {
                    this.byteBuffer.Seek(startingPos, SeekOrigin.Begin);
                    throw NMSExceptionSupport.CreateMessageFormatException(e);
                }
            }
            catch(EndOfStreamException e)
            {
                throw NMSExceptionSupport.CreateMessageEOFException(e);
            }
            catch(IOException e)
            {
                throw NMSExceptionSupport.CreateMessageFormatException(e);
            }
        }

        public byte ReadByte()
        {
            InitializeReading();

            try
            {
                long startingPos = this.byteBuffer.Position;
                try
                {
                    int type = this.dataIn.ReadByte();

                    if(type == PrimitiveMap.BYTE_TYPE)
                    {
                        return this.dataIn.ReadByte();
                    }
                    else if(type == PrimitiveMap.STRING_TYPE)
                    {
                        return Byte.Parse(this.dataIn.ReadString16());
                    }
                    else if(type == PrimitiveMap.NULL)
                    {
                        this.byteBuffer.Seek(startingPos, SeekOrigin.Begin);
                        throw new NMSException("Cannot convert Null type to a byte");
                    }
                    else
                    {
                        this.byteBuffer.Seek(startingPos, SeekOrigin.Begin);
                        throw new MessageFormatException("Value is not a Byte type.");
                    }
                }
                catch(FormatException e)
                {
                    this.byteBuffer.Seek(startingPos, SeekOrigin.Begin);
                    throw NMSExceptionSupport.CreateMessageFormatException(e);
                }
            }
            catch(EndOfStreamException e)
            {
                throw NMSExceptionSupport.CreateMessageEOFException(e);
            }
            catch(IOException e)
            {
                throw NMSExceptionSupport.CreateMessageFormatException(e);
            }
        }

        public char ReadChar()
        {
            InitializeReading();

            try
            {
                long startingPos = this.byteBuffer.Position;
                try
                {
                    int type = this.dataIn.ReadByte();

                    if(type == PrimitiveMap.CHAR_TYPE)
                    {
                        return this.dataIn.ReadChar();
                    }
                    else if(type == PrimitiveMap.NULL)
                    {
                        this.byteBuffer.Seek(startingPos, SeekOrigin.Begin);
                        throw new NMSException("Cannot convert Null type to a char");
                    }
                    else
                    {
                        this.byteBuffer.Seek(startingPos, SeekOrigin.Begin);
                        throw new MessageFormatException("Value is not a Char type.");
                    }
                }
                catch(FormatException e)
                {
                    this.byteBuffer.Seek(startingPos, SeekOrigin.Begin);
                    throw NMSExceptionSupport.CreateMessageFormatException(e);
                }
            }
            catch(EndOfStreamException e)
            {
                throw NMSExceptionSupport.CreateMessageEOFException(e);
            }
            catch(IOException e)
            {
                throw NMSExceptionSupport.CreateMessageFormatException(e);
            }
        }

        public short ReadInt16()
        {
            InitializeReading();

            try
            {
                long startingPos = this.byteBuffer.Position;
                try
                {
                    int type = this.dataIn.ReadByte();

                    if(type == PrimitiveMap.SHORT_TYPE)
                    {
                        return this.dataIn.ReadInt16();
                    }
                    else if(type == PrimitiveMap.BYTE_TYPE)
                    {
                        return this.dataIn.ReadByte();
                    }
                    else if(type == PrimitiveMap.STRING_TYPE)
                    {
                        return Int16.Parse(this.dataIn.ReadString16());
                    }
                    else if(type == PrimitiveMap.NULL)
                    {
                        this.byteBuffer.Seek(startingPos, SeekOrigin.Begin);
                        throw new NMSException("Cannot convert Null type to a short");
                    }
                    else
                    {
                        this.byteBuffer.Seek(startingPos, SeekOrigin.Begin);
                        throw new MessageFormatException("Value is not a Int16 type.");
                    }
                }
                catch(FormatException e)
                {
                    this.byteBuffer.Seek(startingPos, SeekOrigin.Begin);
                    throw NMSExceptionSupport.CreateMessageFormatException(e);
                }
            }
            catch(EndOfStreamException e)
            {
                throw NMSExceptionSupport.CreateMessageEOFException(e);
            }
            catch(IOException e)
            {
                throw NMSExceptionSupport.CreateMessageFormatException(e);
            }
        }

        public int ReadInt32()
        {
            InitializeReading();

            try
            {
                long startingPos = this.byteBuffer.Position;
                try
                {
                    int type = this.dataIn.ReadByte();

                    if(type == PrimitiveMap.INTEGER_TYPE)
                    {
                        return this.dataIn.ReadInt32();
                    }
                    else if(type == PrimitiveMap.SHORT_TYPE)
                    {
                        return this.dataIn.ReadInt16();
                    }
                    else if(type == PrimitiveMap.BYTE_TYPE)
                    {
                        return this.dataIn.ReadByte();
                    }
                    else if(type == PrimitiveMap.STRING_TYPE)
                    {
                        return Int32.Parse(this.dataIn.ReadString16());
                    }
                    else if(type == PrimitiveMap.NULL)
                    {
                        this.byteBuffer.Seek(startingPos, SeekOrigin.Begin);
                        throw new NMSException("Cannot convert Null type to a int");
                    }
                    else
                    {
                        this.byteBuffer.Seek(startingPos, SeekOrigin.Begin);
                        throw new MessageFormatException("Value is not a Int32 type.");
                    }
                }
                catch(FormatException e)
                {
                    this.byteBuffer.Seek(startingPos, SeekOrigin.Begin);
                    throw NMSExceptionSupport.CreateMessageFormatException(e);
                }
            }
            catch(EndOfStreamException e)
            {
                throw NMSExceptionSupport.CreateMessageEOFException(e);
            }
            catch(IOException e)
            {
                throw NMSExceptionSupport.CreateMessageFormatException(e);
            }
        }

        public long ReadInt64()
        {
            InitializeReading();

            try
            {
                long startingPos = this.byteBuffer.Position;
                try
                {
                    int type = this.dataIn.ReadByte();

                    if(type == PrimitiveMap.LONG_TYPE)
                    {
                        return this.dataIn.ReadInt64();
                    }
                    else if(type == PrimitiveMap.INTEGER_TYPE)
                    {
                        return this.dataIn.ReadInt32();
                    }
                    else if(type == PrimitiveMap.SHORT_TYPE)
                    {
                        return this.dataIn.ReadInt16();
                    }
                    else if(type == PrimitiveMap.BYTE_TYPE)
                    {
                        return this.dataIn.ReadByte();
                    }
                    else if(type == PrimitiveMap.STRING_TYPE)
                    {
                        return Int64.Parse(this.dataIn.ReadString16());
                    }
                    else if(type == PrimitiveMap.NULL)
                    {
                        this.byteBuffer.Seek(startingPos, SeekOrigin.Begin);
                        throw new NMSException("Cannot convert Null type to a long");
                    }
                    else
                    {
                        this.byteBuffer.Seek(startingPos, SeekOrigin.Begin);
                        throw new MessageFormatException("Value is not a Int64 type.");
                    }
                }
                catch(FormatException e)
                {
                    this.byteBuffer.Seek(startingPos, SeekOrigin.Begin);
                    throw NMSExceptionSupport.CreateMessageFormatException(e);
                }
            }
            catch(EndOfStreamException e)
            {
                throw NMSExceptionSupport.CreateMessageEOFException(e);
            }
            catch(IOException e)
            {
                throw NMSExceptionSupport.CreateMessageFormatException(e);
            }
        }

        public float ReadSingle()
        {
            InitializeReading();

            try
            {
                long startingPos = this.byteBuffer.Position;
                try
                {
                    int type = this.dataIn.ReadByte();

                    if(type == PrimitiveMap.FLOAT_TYPE)
                    {
                        return this.dataIn.ReadSingle();
                    }
                    else if(type == PrimitiveMap.STRING_TYPE)
                    {
                        return Single.Parse(this.dataIn.ReadString16());
                    }
                    else if(type == PrimitiveMap.NULL)
                    {
                        this.byteBuffer.Seek(startingPos, SeekOrigin.Begin);
                        throw new NMSException("Cannot convert Null type to a float");
                    }
                    else
                    {
                        this.byteBuffer.Seek(startingPos, SeekOrigin.Begin);
                        throw new MessageFormatException("Value is not a Single type.");
                    }
                }
                catch(FormatException e)
                {
                    this.byteBuffer.Seek(startingPos, SeekOrigin.Begin);
                    throw NMSExceptionSupport.CreateMessageFormatException(e);
                }
            }
            catch(EndOfStreamException e)
            {
                throw NMSExceptionSupport.CreateMessageEOFException(e);
            }
            catch(IOException e)
            {
                throw NMSExceptionSupport.CreateMessageFormatException(e);
            }
        }

        public double ReadDouble()
        {
            InitializeReading();

            try
            {
                long startingPos = this.byteBuffer.Position;
                try
                {
                    int type = this.dataIn.ReadByte();

                    if(type == PrimitiveMap.DOUBLE_TYPE)
                    {
                        return this.dataIn.ReadDouble();
                    }
                    else if(type == PrimitiveMap.FLOAT_TYPE)
                    {
                        return this.dataIn.ReadSingle();
                    }
                    else if(type == PrimitiveMap.STRING_TYPE)
                    {
                        return Single.Parse(this.dataIn.ReadString16());
                    }
                    else if(type == PrimitiveMap.NULL)
                    {
                        this.byteBuffer.Seek(startingPos, SeekOrigin.Begin);
                        throw new NMSException("Cannot convert Null type to a double");
                    }
                    else
                    {
                        this.byteBuffer.Seek(startingPos, SeekOrigin.Begin);
                        throw new MessageFormatException("Value is not a Double type.");
                    }
                }
                catch(FormatException e)
                {
                    this.byteBuffer.Seek(startingPos, SeekOrigin.Begin);
                    throw NMSExceptionSupport.CreateMessageFormatException(e);
                }
            }
            catch(EndOfStreamException e)
            {
                throw NMSExceptionSupport.CreateMessageEOFException(e);
            }
            catch(IOException e)
            {
                throw NMSExceptionSupport.CreateMessageFormatException(e);
            }
        }

        public string ReadString()
        {
            InitializeReading();

            long startingPos = this.byteBuffer.Position;

            try
            {
                int type = this.dataIn.ReadByte();

                if(type == PrimitiveMap.BIG_STRING_TYPE)
                {
                    return this.dataIn.ReadString32();
                }
                else if(type == PrimitiveMap.STRING_TYPE)
                {
                    return this.dataIn.ReadString16();
                }
                else if(type == PrimitiveMap.LONG_TYPE)
                {
                    return this.dataIn.ReadInt64().ToString();
                }
                else if(type == PrimitiveMap.INTEGER_TYPE)
                {
                    return this.dataIn.ReadInt32().ToString();
                }
                else if(type == PrimitiveMap.SHORT_TYPE)
                {
                    return this.dataIn.ReadInt16().ToString();
                }
                else if(type == PrimitiveMap.FLOAT_TYPE)
                {
                    return this.dataIn.ReadSingle().ToString();
                }
                else if(type == PrimitiveMap.DOUBLE_TYPE)
                {
                    return this.dataIn.ReadDouble().ToString();
                }
                else if(type == PrimitiveMap.CHAR_TYPE)
                {
                    return this.dataIn.ReadChar().ToString();
                }
                else if(type == PrimitiveMap.BYTE_TYPE)
                {
                    return this.dataIn.ReadByte().ToString();
                }
                else if(type == PrimitiveMap.BOOLEAN_TYPE)
                {
                    return this.dataIn.ReadBoolean().ToString();
                }
                else if(type == PrimitiveMap.NULL)
                {
                    return null;
                }
                else
                {
                    this.byteBuffer.Seek(startingPos, SeekOrigin.Begin);
                    throw new MessageFormatException("Value is not a known type.");
                }
            }
            catch(FormatException e)
            {
                this.byteBuffer.Seek(startingPos, SeekOrigin.Begin);
                throw NMSExceptionSupport.CreateMessageFormatException(e);
            }
            catch(EndOfStreamException e)
            {
                throw NMSExceptionSupport.CreateMessageEOFException(e);
            }
            catch(IOException e)
            {
                throw NMSExceptionSupport.CreateMessageFormatException(e);
            }
        }

        public int ReadBytes(byte[] value)
        {
            InitializeReading();

            if(value == null)
            {
                throw new NullReferenceException("Passed Byte Array is null");
            }

            try
            {
                if(this.bytesRemaining == -1)
                {
                    long startingPos = this.byteBuffer.Position;
                    byte type = this.dataIn.ReadByte();

                    if(type != PrimitiveMap.BYTE_ARRAY_TYPE)
                    {
                        this.byteBuffer.Seek(startingPos, SeekOrigin.Begin);
                        throw new MessageFormatException("Not a byte array");
                    }

                    this.bytesRemaining = this.dataIn.ReadInt32();
                }
                else if(this.bytesRemaining == 0)
                {
                    this.bytesRemaining = -1;
                    return -1;
                }

                if(value.Length <= this.bytesRemaining)
                {
                    // small buffer
                    this.bytesRemaining -= value.Length;
                    this.dataIn.Read(value, 0, value.Length);
                    return value.Length;
                }
                else
                {
                    // big buffer
                    int rc = this.dataIn.Read(value, 0, this.bytesRemaining);
                    this.bytesRemaining = 0;
                    return rc;
                }
            }
            catch(EndOfStreamException ex)
            {
                throw NMSExceptionSupport.CreateMessageEOFException(ex);
            }
            catch(IOException ex)
            {
                throw NMSExceptionSupport.CreateMessageFormatException(ex);
            }
        }

        public Object ReadObject()
        {
            InitializeReading();

            long startingPos = this.byteBuffer.Position;

            try
            {
                int type = this.dataIn.ReadByte();

                if(type == PrimitiveMap.BIG_STRING_TYPE)
                {
                    return this.dataIn.ReadString32();
                }
                else if(type == PrimitiveMap.STRING_TYPE)
                {
                    return this.dataIn.ReadString16();
                }
                else if(type == PrimitiveMap.LONG_TYPE)
                {
                    return this.dataIn.ReadInt64();
                }
                else if(type == PrimitiveMap.INTEGER_TYPE)
                {
                    return this.dataIn.ReadInt32();
                }
                else if(type == PrimitiveMap.SHORT_TYPE)
                {
                    return this.dataIn.ReadInt16();
                }
                else if(type == PrimitiveMap.FLOAT_TYPE)
                {
                    return this.dataIn.ReadSingle();
                }
                else if(type == PrimitiveMap.DOUBLE_TYPE)
                {
                    return this.dataIn.ReadDouble();
                }
                else if(type == PrimitiveMap.CHAR_TYPE)
                {
                    return this.dataIn.ReadChar();
                }
                else if(type == PrimitiveMap.BYTE_TYPE)
                {
                    return this.dataIn.ReadByte();
                }
                else if(type == PrimitiveMap.BOOLEAN_TYPE)
                {
                    return this.dataIn.ReadBoolean();
                }
                else if(type == PrimitiveMap.BYTE_ARRAY_TYPE)
                {
                    int length = this.dataIn.ReadInt32();
                    byte[] data = new byte[length];
                    this.dataIn.Read(data, 0, length);
                    return data;
                }
                else if(type == PrimitiveMap.NULL)
                {
                    return null;
                }
                else
                {
                    this.byteBuffer.Seek(startingPos, SeekOrigin.Begin);
                    throw new MessageFormatException("Value is not a known type.");
                }
            }
            catch(FormatException e)
            {
                this.byteBuffer.Seek(startingPos, SeekOrigin.Begin);
                throw NMSExceptionSupport.CreateMessageFormatException(e);
            }
            catch(EndOfStreamException e)
            {
                throw NMSExceptionSupport.CreateMessageEOFException(e);
            }
            catch(IOException e)
            {
                throw NMSExceptionSupport.CreateMessageFormatException(e);
            }
        }

        public void WriteBoolean(bool value)
        {
            InitializeWriting();
            try
            {
                this.dataOut.Write(PrimitiveMap.BOOLEAN_TYPE);
                this.dataOut.Write(value);
            }
            catch(IOException e)
            {
                NMSExceptionSupport.Create(e);
            }
        }

        public void WriteByte(byte value)
        {
            InitializeWriting();
            try
            {
                this.dataOut.Write(PrimitiveMap.BYTE_TYPE);
                this.dataOut.Write(value);
            }
            catch(IOException e)
            {
                NMSExceptionSupport.Create(e);
            }
        }

        public void WriteBytes(byte[] value)
        {
            InitializeWriting();
            this.WriteBytes(value, 0, value.Length);
        }

        public void WriteBytes(byte[] value, int offset, int length)
        {
            InitializeWriting();
            try
            {
                this.dataOut.Write(PrimitiveMap.BYTE_ARRAY_TYPE);
                this.dataOut.Write((int) length);
                this.dataOut.Write(value, offset, length);
            }
            catch(IOException e)
            {
                NMSExceptionSupport.Create(e);
            }
        }

        public void WriteChar(char value)
        {
            InitializeWriting();
            try
            {
                this.dataOut.Write(PrimitiveMap.CHAR_TYPE);
                this.dataOut.Write(value);
            }
            catch(IOException e)
            {
                NMSExceptionSupport.Create(e);
            }
        }

        public void WriteInt16(short value)
        {
            InitializeWriting();
            try
            {
                this.dataOut.Write(PrimitiveMap.SHORT_TYPE);
                this.dataOut.Write(value);
            }
            catch(IOException e)
            {
                NMSExceptionSupport.Create(e);
            }
        }

        public void WriteInt32(int value)
        {
            InitializeWriting();
            try
            {
                this.dataOut.Write(PrimitiveMap.INTEGER_TYPE);
                this.dataOut.Write(value);
            }
            catch(IOException e)
            {
                NMSExceptionSupport.Create(e);
            }
        }

        public void WriteInt64(long value)
        {
            InitializeWriting();
            try
            {
                this.dataOut.Write(PrimitiveMap.LONG_TYPE);
                this.dataOut.Write(value);
            }
            catch(IOException e)
            {
                NMSExceptionSupport.Create(e);
            }
        }

        public void WriteSingle(float value)
        {
            InitializeWriting();
            try
            {
                this.dataOut.Write(PrimitiveMap.FLOAT_TYPE);
                this.dataOut.Write(value);
            }
            catch(IOException e)
            {
                NMSExceptionSupport.Create(e);
            }
        }

        public void WriteDouble(double value)
        {
            InitializeWriting();
            try
            {
                this.dataOut.Write(PrimitiveMap.DOUBLE_TYPE);
                this.dataOut.Write(value);
            }
            catch(IOException e)
            {
                NMSExceptionSupport.Create(e);
            }
        }

        public void WriteString(string value)
        {
            InitializeWriting();
            try
            {
                if( value.Length > 8192 )
                {
                    this.dataOut.Write(PrimitiveMap.BIG_STRING_TYPE);
                    this.dataOut.WriteString32(value);
                }
                else
                {
                    this.dataOut.Write(PrimitiveMap.STRING_TYPE);
                    this.dataOut.WriteString16(value);
                }
            }
            catch(IOException e)
            {
                NMSExceptionSupport.Create(e);
            }
        }

        public void WriteObject(Object value)
        {
            InitializeWriting();
            if( value is System.Byte )
            {
                this.WriteByte( (byte) value );
            }
            else if( value is Char )
            {
                this.WriteChar( (char) value );
            }
            else if( value is Boolean )
            {
                this.WriteBoolean( (bool) value );
            }
            else if( value is Int16 )
            {
                this.WriteInt16( (short) value );
            }
            else if( value is Int32 )
            {
                this.WriteInt32( (int) value );
            }
            else if( value is Int64 )
            {
                this.WriteInt64( (long) value );
            }
            else if( value is Single )
            {
                this.WriteSingle( (float) value );
            }
            else if( value is Double )
            {
                this.WriteDouble( (double) value );
            }
            else if( value is byte[] )
            {
                this.WriteBytes( (byte[]) value );
            }
            else if( value is String )
            {
                this.WriteString( (string) value );
            }
            else
            {
                throw new MessageFormatException("Cannot write non-primitive type:" + value.GetType());
            }
        }

        public override Object Clone()
        {
            StoreContent();
            return base.Clone();
        }

        public override void OnSend()
        {
            base.OnSend();
            StoreContent();
        }

        public override void ClearBody()
        {
            base.ClearBody();
            this.byteBuffer = null;
            this.dataIn = null;
            this.dataOut = null;
            this.bytesRemaining = -1;
        }

        public void Reset()
        {
            StoreContent();
            this.dataIn = null;
            this.dataOut = null;
            this.byteBuffer = null;
            this.bytesRemaining = -1;
            this.ReadOnlyBody = true;
        }

        private void InitializeReading()
        {
            FailIfWriteOnlyBody();
            if(this.dataIn == null)
            {
                this.byteBuffer = new MemoryStream(this.Content, false);
                this.dataIn = new EndianBinaryReader(this.byteBuffer);
            }
        }

        private void InitializeWriting()
        {
            FailIfReadOnlyBody();
            if(this.dataOut == null)
            {
                this.byteBuffer = new MemoryStream();
                this.dataOut = new EndianBinaryWriter(this.byteBuffer);
            }
        }

        private void StoreContent()
        {
            if( dataOut != null)
            {
                dataOut.Close();

                this.Content = byteBuffer.ToArray();
                this.dataOut = null;
                this.byteBuffer = null;
            }
        }

    }
}

