﻿/*
 * 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.IO;
using Apache.NMS.Util;
using NUnit.Framework;

namespace Apache.NMS.Test
{
    [TestFixture]
    public class EndianBinaryReaderTest
    {
        public void readString16Helper(byte[] input, char[] expect)
        {
            MemoryStream stream = new MemoryStream(input);
            EndianBinaryReader reader = new EndianBinaryReader(stream);

            char[] result = reader.ReadString16().ToCharArray();

            for (int i = 0; i < expect.Length; ++i)
            {
                Assert.AreEqual(expect[i], result[i]);
            }
        }

        [Test]
        public void testReadString16_1byteUTF8encoding()
        {
            // Test data with 1-byte UTF8 encoding.
            char[] expect =
            {
                '\u0000', '\u000B', '\u0048', '\u0065', '\u006C', '\u006C', '\u006F', '\u0020', '\u0057', '\u006F',
                '\u0072', '\u006C', '\u0064'
            };
            byte[] input =
                {0x00, 0x0E, 0xC0, 0x80, 0x0B, 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x20, 0x57, 0x6F, 0x72, 0x6C, 0x64};

            readString16Helper(input, expect);
        }

        [Test]
        public void testReadString16_2byteUTF8encoding()
        {
            // Test data with 2-byte UT8 encoding.
            char[] expect = {'\u0000', '\u00C2', '\u00A9', '\u00C3', '\u00A6'};
            byte[] input = {0x00, 0x0A, 0xC0, 0x80, 0xC3, 0x82, 0xC2, 0xA9, 0xC3, 0x83, 0xC2, 0xA6};
            readString16Helper(input, expect);
        }

        [Test]
        public void testReadString16_1byteAnd2byteEmbeddedNULLs()
        {
            // Test data with 1-byte and 2-byte encoding with embedded NULL's.
            char[] expect = {'\u0000', '\u0004', '\u00C2', '\u00A9', '\u00C3', '\u0000', '\u00A6'};
            byte[] input = {0x00, 0x0D, 0xC0, 0x80, 0x04, 0xC3, 0x82, 0xC2, 0xA9, 0xC3, 0x83, 0xC0, 0x80, 0xC2, 0xA6};

            readString16Helper(input, expect);
        }

        [Test]
        public void testReadString16_UTF8Missing2ndByte()
        {
            Assert.Throws<IOException>(_testReadString16_UTF8Missing2ndByte);
        }

        private void _testReadString16_UTF8Missing2ndByte()
        {
            // Test with bad UTF-8 encoding, missing 2nd byte of two byte value
            byte[] input = {0x00, 0x0D, 0xC0, 0x80, 0x04, 0xC3, 0x82, 0xC2, 0xC2, 0xC3, 0x83, 0xC0, 0x80, 0xC2, 0xA6};

            MemoryStream stream = new MemoryStream(input);
            EndianBinaryReader reader = new EndianBinaryReader(stream);

            reader.ReadString16();
        }

        [Test]
        public void testReadString16_3byteEncodingMissingLastByte()
        {
            Assert.Throws<IOException>(_testReadString16_3byteEncodingMissingLastByte);
        }

        private void _testReadString16_3byteEncodingMissingLastByte()
        {
            // Test with three byte encode that's missing a last byte.
            byte[] input = {0x00, 0x02, 0xE8, 0xA8};

            MemoryStream stream = new MemoryStream(input);
            EndianBinaryReader reader = new EndianBinaryReader(stream);

            reader.ReadString16();
        }

        public void readString32Helper(byte[] input, char[] expect)
        {
            MemoryStream stream = new MemoryStream(input);
            EndianBinaryReader reader = new EndianBinaryReader(stream);

            char[] result = reader.ReadString32().ToCharArray();

            for (int i = 0; i < expect.Length; ++i)
            {
                Assert.AreEqual(expect[i], result[i]);
            }
        }

        [Test]
        public void testReadString32_1byteUTF8encoding()
        {
            // Test data with 1-byte UTF8 encoding.
            char[] expect =
            {
                '\u0000', '\u000B', '\u0048', '\u0065', '\u006C', '\u006C', '\u006F', '\u0020', '\u0057', '\u006F',
                '\u0072', '\u006C', '\u0064'
            };
            byte[] input =
            {
                0x00, 0x00, 0x00, 0x0E, 0xC0, 0x80, 0x0B, 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x20, 0x57, 0x6F, 0x72, 0x6C,
                0x64
            };

            readString32Helper(input, expect);
        }

        [Test]
        public void testReadString32_2byteUTF8encoding()
        {
            // Test data with 2-byte UT8 encoding.
            char[] expect = {'\u0000', '\u00C2', '\u00A9', '\u00C3', '\u00A6'};
            byte[] input = {0x00, 0x00, 0x00, 0x0A, 0xC0, 0x80, 0xC3, 0x82, 0xC2, 0xA9, 0xC3, 0x83, 0xC2, 0xA6};
            readString32Helper(input, expect);
        }

        [Test]
        public void testReadString32_1byteAnd2byteEmbeddedNULLs()
        {
            // Test data with 1-byte and 2-byte encoding with embedded NULL's.
            char[] expect = {'\u0000', '\u0004', '\u00C2', '\u00A9', '\u00C3', '\u0000', '\u00A6'};
            byte[] input =
                {0x00, 0x00, 0x00, 0x0D, 0xC0, 0x80, 0x04, 0xC3, 0x82, 0xC2, 0xA9, 0xC3, 0x83, 0xC0, 0x80, 0xC2, 0xA6};

            readString32Helper(input, expect);
        }

        [Test]
        public void testReadString32_UTF8Missing2ndByte()
        {
            Assert.Throws<IOException>(_testReadString32_UTF8Missing2ndByte);
        }

        private void _testReadString32_UTF8Missing2ndByte()
        {
            // Test with bad UTF-8 encoding, missing 2nd byte of two byte value
            byte[] input =
                {0x00, 0x00, 0x00, 0x0D, 0xC0, 0x80, 0x04, 0xC3, 0x82, 0xC2, 0xC2, 0xC3, 0x83, 0xC0, 0x80, 0xC2, 0xA6};

            MemoryStream stream = new MemoryStream(input);
            EndianBinaryReader reader = new EndianBinaryReader(stream);

            reader.ReadString32();
        }

        [Test]
        public void testReadString32_3byteEncodingMissingLastByte()
        {
            Assert.Throws<IOException>(_testReadString32_3byteEncodingMissingLastByte);
        }

        private void _testReadString32_3byteEncodingMissingLastByte()
        {
            // Test with three byte encode that's missing a last byte.
            byte[] input = {0x00, 0x00, 0x00, 0x02, 0xE8, 0xA8};

            MemoryStream stream = new MemoryStream(input);
            EndianBinaryReader reader = new EndianBinaryReader(stream);

            reader.ReadString32();
        }
    }
}