/*
 * 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.Test;
using Apache.NMS.Util;
using NUnit.Framework;
using NUnit.Framework.Extensions;

namespace Apache.NMS.Stomp.Test
{
    [TestFixture]
    public class BytesMessageTest : NMSTestSupport
    {
        protected static string TEST_CLIENT_ID = "BytesMessageClientId";
        protected byte[] msgContent = {1, 2, 3, 4, 5, 6, 7, 8};

        [SetUp]
        public override void SetUp()
        {
        }

        [TearDown]
        public override void TearDown()
        {
        }
        
        [RowTest]
        [Row(MsgDeliveryMode.Persistent)]
        [Row(MsgDeliveryMode.NonPersistent)]
        public void SendReceiveBytesMessage(MsgDeliveryMode deliveryMode)
        {
            using(IConnection connection = CreateConnection(TEST_CLIENT_ID + ":" + new Random().Next()))
            {
                connection.Start();
                using(ISession session = connection.CreateSession(AcknowledgementMode.AutoAcknowledge))
                {
                    IDestination destination = session.CreateTemporaryTopic();
                    using(IMessageConsumer consumer = session.CreateConsumer(destination))
                    using(IMessageProducer producer = session.CreateProducer(destination))
                    {
                        producer.DeliveryMode = deliveryMode;
                        producer.RequestTimeout = receiveTimeout;
                        IMessage request = session.CreateBytesMessage(msgContent);
                        producer.Send(request);

                        IMessage message = consumer.Receive(receiveTimeout);
                        AssertBytesMessageEqual(request, message);
                        AssertMessageIsReadOnly(message);
                        Assert.AreEqual(deliveryMode, message.NMSDeliveryMode, "NMSDeliveryMode does not match");

                    }
                }
            }
        }

        [RowTest]
        [Row(MsgDeliveryMode.Persistent)]
        [Row(MsgDeliveryMode.NonPersistent)]
        public void SendReceiveBytesMessageContentTest(MsgDeliveryMode deliveryMode)
        {
            using(IConnection connection = CreateConnection(TEST_CLIENT_ID + ":" + new Random().Next()))
            {
                connection.Start();
                using(ISession session = connection.CreateSession(AcknowledgementMode.AutoAcknowledge))
                {
                    IDestination destination = session.CreateTemporaryTopic();
                    using(IMessageConsumer consumer = session.CreateConsumer(destination))
                    using(IMessageProducer producer = session.CreateProducer(destination))
                    {
                        producer.DeliveryMode = deliveryMode;
                        producer.RequestTimeout = receiveTimeout;
                        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);
                        AssertBytesMessageEqual(request, message);
                        AssertMessageIsReadOnly(message);
                        Assert.AreEqual(deliveryMode, message.NMSDeliveryMode, "NMSDeliveryMode does not match");

                    }
                }
            }
        }

        protected void AssertMessageIsReadOnly(IMessage message)
        {
            IBytesMessage theMessage = message as IBytesMessage;
            Assert.IsNotNull(theMessage);
            try
            {
                theMessage.WriteBoolean(true);
                theMessage.WriteByte((byte) 1);
                theMessage.WriteBytes(new byte[1]);
                theMessage.WriteBytes(new byte[3], 0, 2);
                theMessage.WriteChar('a');
                theMessage.WriteDouble(1.5);
                theMessage.WriteSingle((float) 1.5);
                theMessage.WriteInt32(1);
                theMessage.WriteInt64(1);
                theMessage.WriteObject("stringobj");
                theMessage.WriteInt16((short) 1);
                theMessage.WriteString("utfstring");
                Assert.Fail("Message should not have been Writable");
            }
            catch(MessageNotWriteableException)
            {
            }
        }

        /// <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.");
        }
    }
}
