/*
 * 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 Apache.NMS.Util;
using NUnit.Framework;

namespace Apache.NMS.Test
{
	//[TestFixture]
	public class BytesMessageTest : NMSTest
	{
		protected byte[] msgContent = {1, 2, 3, 4, 5, 6, 7, 8};

		protected BytesMessageTest(NMSTestSupport testSupport)
			: base(testSupport)
		{
		}

		//[Test]
		public virtual void SendReceiveBytesMessage(
			//[Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]
			MsgDeliveryMode deliveryMode, string testQueueRef)
		{
			using(IConnection connection = CreateConnection(GetTestClientId()))
			{
				connection.Start();
				using(ISession session = connection.CreateSession(AcknowledgementMode.AutoAcknowledge))
				{
					IDestination destination = GetClearDestination(session, DestinationType.Queue, testQueueRef);
					using(IMessageConsumer consumer = session.CreateConsumer(destination))
					using(IMessageProducer producer = session.CreateProducer(destination))
					{
						producer.DeliveryMode = deliveryMode;
						IMessage request = session.CreateBytesMessage(msgContent);
						producer.Send(request);

						IMessage message = consumer.Receive(receiveTimeout);
                        AssertMessageIsReadOnly(message);
						AssertBytesMessageEqual(request, message);
						Assert.AreEqual(deliveryMode, message.NMSDeliveryMode, "NMSDeliveryMode does not match");

					}
				}
			}
		}

        //[Test]
        public virtual void SendReceiveBytesMessageContent(
			//[Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]
			MsgDeliveryMode deliveryMode, string testQueueRef)
        {
            using(IConnection connection = CreateConnection(GetTestClientId()))
            {
                connection.Start();
                using(ISession session = connection.CreateSession(AcknowledgementMode.AutoAcknowledge))
                {
					IDestination destination = GetClearDestination(session, DestinationType.Queue, testQueueRef);
                    using(IMessageConsumer consumer = session.CreateConsumer(destination))
                    using(IMessageProducer producer = session.CreateProducer(destination))
                    {
                        producer.DeliveryMode = deliveryMode;
                        IBytesMessage request = session.CreateBytesMessage();
                        
                        request.WriteBoolean(true);
                        request.WriteByte((byte) 1);
                        request.WriteBytes(new byte[1]);
                        request.WriteBytes(new byte[3], 0, 2);
                        request.WriteChar('a');
                        request.WriteDouble(1.5);
                        request.WriteSingle((float) 1.5);
                        request.WriteInt32(1);
                        request.WriteInt64(1);
                        request.WriteObject("stringobj");
                        request.WriteInt16((short) 1);
                        request.WriteString("utfstring");
                        
                        producer.Send(request);

                        IMessage message = consumer.Receive(receiveTimeout);
                        AssertMessageIsReadOnly(message);
                        AssertBytesMessageEqual(request, message);
                        Assert.AreEqual(deliveryMode, message.NMSDeliveryMode, "NMSDeliveryMode does not match");

                    }
                }
            }
        }
        
        protected void AssertMessageIsReadOnly(IMessage message)
        {
			Type writeableExceptionType = typeof(MessageNotWriteableException);
			IBytesMessage theMessage = message as IBytesMessage;
            Assert.IsNotNull(theMessage);
			Assert.Throws(writeableExceptionType, delegate () { theMessage.WriteBoolean(true); });
			Assert.Throws(writeableExceptionType, delegate () { theMessage.WriteByte((byte) 1); });
			Assert.Throws(writeableExceptionType, delegate () { theMessage.WriteBytes(new byte[1]); });
			Assert.Throws(writeableExceptionType, delegate () { theMessage.WriteBytes(new byte[3], 0, 2); });
			Assert.Throws(writeableExceptionType, delegate () { theMessage.WriteChar('a'); });
			Assert.Throws(writeableExceptionType, delegate () { theMessage.WriteDouble(1.5); });
			Assert.Throws(writeableExceptionType, delegate () { theMessage.WriteSingle((float) 1.5); });
			Assert.Throws(writeableExceptionType, delegate () { theMessage.WriteInt32(1); });
			Assert.Throws(writeableExceptionType, delegate () { theMessage.WriteInt64(1); });
			Assert.Throws(writeableExceptionType, delegate () { theMessage.WriteObject("stringobj"); });
			Assert.Throws(writeableExceptionType, delegate () { theMessage.WriteInt16((short) 1); });
			Assert.Throws(writeableExceptionType, delegate () { theMessage.WriteString("utfstring"); });
		}
        
		/// <summary>
		/// Assert that two messages are IBytesMessages and their contents are equal.
		/// </summary>
		/// <param name="expected"></param>
		/// <param name="actual"></param>
		protected void AssertBytesMessageEqual(IMessage expected, IMessage actual)
		{
			IBytesMessage expectedBytesMsg = expected as IBytesMessage;
			expectedBytesMsg.Reset();
			Assert.IsNotNull(expectedBytesMsg, "'expected' message not a bytes message");
			IBytesMessage actualBytesMsg = actual as IBytesMessage;
			Assert.IsNotNull(actualBytesMsg, "'actual' message not a bytes message");
			Assert.AreEqual(expectedBytesMsg.Content, actualBytesMsg.Content, "Bytes message contents do not match.");
		}
	}
}
