/*
 * 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;

namespace Apache.NMS.Util
{
    /// <summary>
    /// A BinaryWriter that switches the endian orientation of the read operations so that they
    /// are compatible across platforms.
    /// </summary>
    [CLSCompliant(false)]
    public class EndianBinaryReader : BinaryReader
    {
        public EndianBinaryReader(Stream input)
            : base(input)
        {
        }

        /// <summary>
        /// Method Read
        /// </summary>
        /// <returns>An int</returns>
        /// <param name="buffer">A  char[]</param>
        /// <param name="index">An int</param>
        /// <param name="count">An int</param>
        public override int Read(char[] buffer, int index, int count)
        {
            int size = base.Read(buffer, index, count);
            for (int i = 0; i < size; i++)
            {
                buffer[index + i] = EndianSupport.SwitchEndian(buffer[index + i]);
            }

            return size;
        }

        /// <summary>
        /// Method ReadChars
        /// </summary>
        /// <returns>A char[]</returns>
        /// <param name="count">An int</param>
        public override char[] ReadChars(int count)
        {
            char[] rc = base.ReadChars(count);
            if (rc != null)
            {
                for (int i = 0; i < rc.Length; i++)
                {
                    rc[i] = EndianSupport.SwitchEndian(rc[i]);
                }
            }

            return rc;
        }

        /// <summary>
        /// Method ReadInt16
        /// </summary>
        /// <returns>A short</returns>
        public override short ReadInt16()
        {
            return EndianSupport.SwitchEndian(base.ReadInt16());
        }

        /// <summary>
        /// Method ReadChar
        /// </summary>
        /// <returns>A char</returns>
        public override char ReadChar()
        {
            return (char) (
                (((char) ((byte) (base.ReadByte()))) << 8) |
                (((char) ((byte) (base.ReadByte()))))
            );

            //			return EndianSupport.SwitchEndian(base.ReadChar());
        }

        /// <summary>
        /// Method ReadInt64
        /// </summary>
        /// <returns>A long</returns>
        public override long ReadInt64()
        {
            return EndianSupport.SwitchEndian(base.ReadInt64());
        }

        /// <summary>
        /// Method ReadUInt64
        /// </summary>
        /// <returns>An ulong</returns>
        public override ulong ReadUInt64()
        {
            return EndianSupport.SwitchEndian(base.ReadUInt64());
        }

        /// <summary>
        /// Method ReadUInt32
        /// </summary>
        /// <returns>An uint</returns>
        public override uint ReadUInt32()
        {
            return EndianSupport.SwitchEndian(base.ReadUInt32());
        }

        /// <summary>
        /// Method ReadUInt16
        /// </summary>
        /// <returns>An ushort</returns>
        public override ushort ReadUInt16()
        {
            return EndianSupport.SwitchEndian(base.ReadUInt16());
        }

        /// <summary>
        /// Method ReadInt32
        /// </summary>
        /// <returns>An int</returns>
        public override int ReadInt32()
        {
            int x = base.ReadInt32();
            int y = EndianSupport.SwitchEndian(x);
            return y;
        }

        /// <summary>
        /// Method ReadString
        /// </summary>
        /// <returns>A string</returns>
        public override String ReadString()
        {
            return ReadString16();
        }

        /// <summary>
        /// Method ReadString16, reads a String value encoded in the Java modified
        /// UTF-8 format with a length index encoded as a 16bit unsigned short.
        /// </summary>
        /// <returns>A string</returns>
        public String ReadString16()
        {
            int utfLength = ReadUInt16();

            if (utfLength < 0)
            {
                return null;
            }
            else if (utfLength == 0)
            {
                return "";
            }

            return doReadString(utfLength);
        }

        /// <summary>
        /// Method ReadString32, reads a String value encoded in the Java modified 
        /// UTF-8 format with a length index encoded as a singed integer value.
        /// </summary>
        /// <returns>A string</returns>
        public String ReadString32()
        {
            int utfLength = ReadInt32();

            if (utfLength < 0)
            {
                return null;
            }
            else if (utfLength == 0)
            {
                return "";
            }

            return doReadString(utfLength);
        }

        private string doReadString(int utfLength)
        {
            char[] result = new char[utfLength];
            byte[] buffer = new byte[utfLength];

            int bytesRead = 0;
            while (bytesRead < utfLength)
            {
                int rc = Read(buffer, bytesRead, utfLength - bytesRead);
                if (rc == 0)
                {
                    throw new IOException("premature end of stream");
                }

                bytesRead += rc;
            }

            int count = 0;
            int index = 0;
            byte a = 0;

            while (count < utfLength)
            {
                if ((result[index] = (char) buffer[count++]) < 0x80)
                {
                    index++;
                }
                else if (((a = (byte) result[index]) & 0xE0) == 0xC0)
                {
                    if (count >= utfLength)
                    {
                        throw new IOException("Invalid UTF-8 encoding found, start of two byte char found at end.");
                    }

                    byte b = buffer[count++];
                    if ((b & 0xC0) != 0x80)
                    {
                        throw new IOException("Invalid UTF-8 encoding found, byte two does not start with 0x80.");
                    }

                    result[index++] = (char) (((a & 0x1F) << 6) | (b & 0x3F));
                }
                else if ((a & 0xF0) == 0xE0)
                {
                    if (count + 1 >= utfLength)
                    {
                        throw new IOException("Invalid UTF-8 encoding found, start of three byte char found at end.");
                    }

                    byte b = buffer[count++];
                    byte c = buffer[count++];
                    if (((b & 0xC0) != 0x80) || ((c & 0xC0) != 0x80))
                    {
                        throw new IOException("Invalid UTF-8 encoding found, byte two does not start with 0x80.");
                    }

                    result[index++] = (char) (((a & 0x0F) << 12) |
                                              ((b & 0x3F) << 6) | (c & 0x3F));
                }
                else
                {
                    throw new IOException("Invalid UTF-8 encoding found, aborting.");
                }
            }

            return new String(result, 0, index);
        }

        public override float ReadSingle()
        {
            return EndianSupport.SwitchEndian(base.ReadSingle());
        }

        public override double ReadDouble()
        {
            return EndianSupport.SwitchEndian(base.ReadDouble());
        }

        protected static Exception CreateDataFormatException()
        {
            // TODO: implement a better exception
            return new IOException("Data format error!");
        }
    }
}