/*
 * 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;
using NUnit.Framework;

namespace Apache.NMS.Test
{
	[TestFixture]
	public class EndianBinaryWriterTest
	{
		void writeString16TestHelper(char[] input, byte[] expect)
		{
			MemoryStream stream = new MemoryStream();
			EndianBinaryWriter writer = new EndianBinaryWriter(stream);

			String str = new String(input);

			writer.WriteString16(str);

			byte[] result = stream.GetBuffer();

			Assert.AreEqual(result[0], 0x00);
			Assert.AreEqual(result[1], expect.Length);

			for(int i = 4; i < expect.Length; ++i)
			{
				Assert.AreEqual(result[i], expect[i - 2]);
			}
		}

		[Test]
		public void testWriteString16_1byteUTF8encoding()
		{
			// Test data with 1-byte UTF8 encoding.
			char[] input = { '\u0000', '\u000B', '\u0048', '\u0065', '\u006C', '\u006C', '\u006F', '\u0020', '\u0057', '\u006F', '\u0072', '\u006C', '\u0064' };
			byte[] expect = { 0xC0, 0x80, 0x0B, 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x20, 0x57, 0x6F, 0x72, 0x6C, 0x64 };

			writeString16TestHelper(input, expect);
		}

		[Test]
		public void testWriteString16_2byteUTF8encoding()
		{
			// Test data with 2-byte UT8 encoding.
			char[] input = { '\u0000', '\u00C2', '\u00A9', '\u00C3', '\u00A6' };
			byte[] expect = { 0xC0, 0x80, 0xC3, 0x82, 0xC2, 0xA9, 0xC3, 0x83, 0xC2, 0xA6 };

			writeString16TestHelper(input, expect);
		}

		[Test]
		public void testWriteString16_1byteAnd2byteEmbeddedNULLs()
		{
			// Test data with 1-byte and 2-byte encoding with embedded NULL's.
			char[] input = { '\u0000', '\u0004', '\u00C2', '\u00A9', '\u00C3', '\u0000', '\u00A6' };
			byte[] expect = { 0xC0, 0x80, 0x04, 0xC3, 0x82, 0xC2, 0xA9, 0xC3, 0x83, 0xC0, 0x80, 0xC2, 0xA6 };

			writeString16TestHelper(input, expect);
		}

		[Test]
		public void testWriteString16_nullstring()
		{
			// test that a null string writes no output.
			MemoryStream stream = new MemoryStream();
			EndianBinaryWriter writer = new EndianBinaryWriter(stream);
			writer.WriteString16(null);
			Assert.AreEqual(0, stream.Length);
		}

		[Test]
		public void testWriteString16_emptystring()
		{
			// test that a null string writes no output.
			MemoryStream stream = new MemoryStream();
			EndianBinaryWriter writer = new EndianBinaryWriter(stream);
			writer.WriteString16("");

			stream.Seek(0, SeekOrigin.Begin);
			EndianBinaryReader reader = new EndianBinaryReader(stream);
			Assert.AreEqual(0, reader.ReadInt16());
		}

		[Test]
		[ExpectedException(typeof(IOException))]
		public void testWriteString16_stringTooLong()
		{
			// String of length 65536 of Null Characters.
			MemoryStream stream = new MemoryStream();
			EndianBinaryWriter writer = new EndianBinaryWriter(stream);
			String testStr = new String('a', 65536);
			writer.Write(testStr);
		}

		[Test]
		public void testWriteString16_maxStringLength()
		{
			// String of length 65535 of non Null Characters since Null encodes as UTF-8.
			MemoryStream stream = new MemoryStream();
			EndianBinaryWriter writer = new EndianBinaryWriter(stream);
			String testStr = new String('a', 65535);
			writer.Write(testStr);
		}

		[Test]
		[ExpectedException(typeof(IOException))]
		public void testWriteString16_invalidEncodingHeader()
		{
			// Set one of the 65535 bytes to a value that will result in a 2 byte UTF8 encoded sequence.
			// This will cause the string of length 65535 to have a utf length of 65536.
			MemoryStream stream = new MemoryStream();
			EndianBinaryWriter writer = new EndianBinaryWriter(stream);
			String testStr = new String('a', 65535);
			char[] array = testStr.ToCharArray();
			array[0] = '\u0000';
			testStr = new String(array);
			writer.Write(testStr);
		}

		void writeString32TestHelper(char[] input, byte[] expect)
		{
			MemoryStream stream = new MemoryStream();
			EndianBinaryWriter writer = new EndianBinaryWriter(stream);

			String str = new String(input);

			writer.WriteString32(str);

			byte[] result = stream.GetBuffer();

			Assert.AreEqual(result[0], 0x00);
			Assert.AreEqual(result[1], 0x00);
			Assert.AreEqual(result[2], 0x00);
			Assert.AreEqual(result[3], expect.Length);

			for(int i = 4; i < expect.Length; ++i)
			{
				Assert.AreEqual(result[i], expect[i - 4]);
			}
		}

		[Test]
		public void testWriteString32_1byteUTF8encoding()
		{
			// Test data with 1-byte UTF8 encoding.
			char[] input = { '\u0000', '\u000B', '\u0048', '\u0065', '\u006C', '\u006C', '\u006F', '\u0020', '\u0057', '\u006F', '\u0072', '\u006C', '\u0064' };
			byte[] expect = { 0xC0, 0x80, 0x0B, 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x20, 0x57, 0x6F, 0x72, 0x6C, 0x64 };

			writeString32TestHelper(input, expect);
		}

		[Test]
		public void testWriteString32_2byteUTF8encoding()
		{
			// Test data with 2-byte UT8 encoding.
			char[] input = { '\u0000', '\u00C2', '\u00A9', '\u00C3', '\u00A6' };
			byte[] expect = { 0xC0, 0x80, 0xC3, 0x82, 0xC2, 0xA9, 0xC3, 0x83, 0xC2, 0xA6 };

			writeString32TestHelper(input, expect);
		}

		[Test]
		public void testWriteString32_1byteAnd2byteEmbeddedNULLs()
		{
			// Test data with 1-byte and 2-byte encoding with embedded NULL's.
			char[] input = { '\u0000', '\u0004', '\u00C2', '\u00A9', '\u00C3', '\u0000', '\u00A6' };
			byte[] expect = { 0xC0, 0x80, 0x04, 0xC3, 0x82, 0xC2, 0xA9, 0xC3, 0x83, 0xC0, 0x80, 0xC2, 0xA6 };

			writeString32TestHelper(input, expect);
		}

		[Test]
		public void testWriteString32_nullstring()
		{
			// test that a null strings writes a -1
			MemoryStream stream = new MemoryStream();
			EndianBinaryWriter writer = new EndianBinaryWriter(stream);
			writer.WriteString32(null);

			stream.Seek(0, SeekOrigin.Begin);
			EndianBinaryReader reader = new EndianBinaryReader(stream);
			Assert.AreEqual(-1, reader.ReadInt32());
		}
	}
}
