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

using Apache.NMS;
using Apache.NMS.Util;

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

        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 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;
            }
        }

    }
}

