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

using Apache.NMS.Util;
using Apache.NMS.Commands;

namespace Apache.NMS.Test
{
    [TestFixture]
    public class ForeignMessageTransformationTest : NMSTestSupport
    {
        protected static string DESTINATION_NAME = "topic://MessageTransformationDestination";

        private string propertyName = "Test-Property";
        private string propertyValue = "Test-Property-Value";
        private string mapElementName = "Test-Map-Property";
        private string mapElementValue = "Test-Map-Property-Value";
        private string textBody = "This is a TextMessage from a Foreign Provider";
        private byte[] bytesContent = {1, 2, 3, 4, 5, 6, 7, 8};

        private bool a = true;
        private byte b = 123;
        private char c = 'c';
        private short d = 0x1234;
        private int e = 0x12345678;
        private long f = 0x1234567812345678;
        private string g = "Hello World!";
        private bool h = false;
        private byte i = 0xFF;
        private short j = -0x1234;
        private int k = -0x12345678;
        private long l = -0x1234567812345678;
        private float m = 2.1F;
        private double n = 2.3;

        [Test]
        public void SendReceiveForeignMessageTest(
            [Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]
            MsgDeliveryMode deliveryMode)
        {
            using(IConnection connection = CreateConnection())
            {
                connection.Start();
                using(ISession session = connection.CreateSession(AcknowledgementMode.AutoAcknowledge))
                {
                    IDestination destination = SessionUtil.GetDestination(session, DESTINATION_NAME);
                    using(IMessageConsumer consumer = session.CreateConsumer(destination))
                    using(IMessageProducer producer = session.CreateProducer(destination))
                    {
                        try
                        {
                            producer.DeliveryMode = deliveryMode;
                            Message request = new Message();
                            request.Properties[propertyName] = propertyValue;

                            producer.Send(request);

                            IMessage message = consumer.Receive(receiveTimeout);
                            Assert.IsNotNull(message, "No message returned!");
                            Assert.AreEqual(request.Properties.Count, message.Properties.Count, "Invalid number of properties.");
                            Assert.AreEqual(deliveryMode, message.NMSDeliveryMode, "NMSDeliveryMode does not match");

                            // use generic API to access entries
                            Assert.AreEqual(propertyValue, message.Properties[propertyName], "generic map entry: " + propertyName);

                            // use type safe APIs
                            Assert.AreEqual(propertyValue, message.Properties.GetString(propertyName),   "map entry: " + propertyName);
                        }
                        catch(NotSupportedException)
                        {
                        }
                    }
                }
            }
        }

        [Test]
        public void SendReceiveForeignTextMessageTest(
            [Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]
            MsgDeliveryMode deliveryMode)
        {
            using(IConnection connection = CreateConnection())
            {
                connection.Start();
                using(ISession session = connection.CreateSession(AcknowledgementMode.AutoAcknowledge))
                {
                    IDestination destination = SessionUtil.GetDestination(session, DESTINATION_NAME);
                    using(IMessageConsumer consumer = session.CreateConsumer(destination))
                    using(IMessageProducer producer = session.CreateProducer(destination))
                    {
                        try
                        {
                            producer.DeliveryMode = deliveryMode;
                            TextMessage request = new TextMessage();
                            request.Properties[propertyName] = propertyValue;
                            request.Text = textBody;

                            producer.Send(request);

                            ITextMessage message = consumer.Receive(receiveTimeout) as ITextMessage;
                            Assert.IsNotNull(message, "No message returned!");
                            Assert.AreEqual(request.Properties.Count, message.Properties.Count, "Invalid number of properties.");
                            Assert.AreEqual(deliveryMode, message.NMSDeliveryMode, "NMSDeliveryMode does not match");

                            // Check the body
                            Assert.AreEqual(textBody, message.Text, "TextMessage body was wrong.");

                            // use generic API to access entries
                            Assert.AreEqual(propertyValue, message.Properties[propertyName], "generic map entry: " + propertyName);

                            // use type safe APIs
                            Assert.AreEqual(propertyValue, message.Properties.GetString(propertyName),   "map entry: " + propertyName);
                        }
                        catch(NotSupportedException)
                        {
                        }
                    }
                }
            }
        }

        [Test]
        public void SendReceiveForeignBytesMessageTest(
            [Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]
            MsgDeliveryMode deliveryMode)
        {
            using(IConnection connection = CreateConnection())
            {
                connection.Start();
                using(ISession session = connection.CreateSession(AcknowledgementMode.AutoAcknowledge))
                {
                    IDestination destination = SessionUtil.GetDestination(session, DESTINATION_NAME);
                    using(IMessageConsumer consumer = session.CreateConsumer(destination))
                    using(IMessageProducer producer = session.CreateProducer(destination))
                    {
                        try
                        {
                            producer.DeliveryMode = deliveryMode;
                            BytesMessage request = new BytesMessage();
                            request.Properties[propertyName] = propertyValue;
                            request.WriteBytes(bytesContent);

                            producer.Send(request);

                            IBytesMessage message = consumer.Receive(receiveTimeout) as IBytesMessage;
                            Assert.IsNotNull(message, "No message returned!");
                            Assert.AreEqual(request.Properties.Count, message.Properties.Count, "Invalid number of properties.");
                            Assert.AreEqual(deliveryMode, message.NMSDeliveryMode, "NMSDeliveryMode does not match");

                            // Check the body
                            byte[] content = new byte[bytesContent.Length];
                            Assert.AreEqual(bytesContent.Length, message.ReadBytes(content));
                            Assert.AreEqual(bytesContent, content, "BytesMessage body was wrong.");

                            // use generic API to access entries
                            Assert.AreEqual(propertyValue, message.Properties[propertyName], "generic map entry: " + propertyName);

                            // use type safe APIs
                            Assert.AreEqual(propertyValue, message.Properties.GetString(propertyName),   "map entry: " + propertyName);
                        }
                        catch(NotSupportedException)
                        {
                        }
                    }
                }
            }
        }

        [Test]
        public void SendReceiveForeignMapMessageTest(
            [Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]
            MsgDeliveryMode deliveryMode)
        {
            using(IConnection connection = CreateConnection())
            {
                connection.Start();
                using(ISession session = connection.CreateSession(AcknowledgementMode.AutoAcknowledge))
                {
                    IDestination destination = SessionUtil.GetDestination(session, DESTINATION_NAME);
                    using(IMessageConsumer consumer = session.CreateConsumer(destination))
                    using(IMessageProducer producer = session.CreateProducer(destination))
                    {
                        try
                        {
                            producer.DeliveryMode = deliveryMode;
                            MapMessage request = new MapMessage();
                            request.Properties[propertyName] = propertyValue;
                            request.Body[mapElementName] = mapElementValue;

                            producer.Send(request);

                            IMapMessage message = consumer.Receive(receiveTimeout) as IMapMessage;
                            Assert.IsNotNull(message, "No message returned!");
                            Assert.AreEqual(request.Properties.Count, message.Properties.Count, "Invalid number of properties.");
                            Assert.AreEqual(deliveryMode, message.NMSDeliveryMode, "NMSDeliveryMode does not match");

                            // Check the body
                            Assert.AreEqual(request.Body.Count, message.Body.Count);
                            Assert.AreEqual(mapElementValue, message.Body[mapElementName], "MapMessage body was wrong.");

                            // use generic API to access entries
                            Assert.AreEqual(propertyValue, message.Properties[propertyName], "generic map entry: " + propertyName);

                            // use type safe APIs
                            Assert.AreEqual(propertyValue, message.Properties.GetString(propertyName),   "map entry: " + propertyName);
                        }
                        catch(NotSupportedException)
                        {
                        }
                    }
                }
            }
        }

        [Test]
        public void SendReceiveForeignStreamMessageTest(
            [Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]
            MsgDeliveryMode deliveryMode)
        {
            using(IConnection connection = CreateConnection())
            {
                connection.Start();
                using(ISession session = connection.CreateSession(AcknowledgementMode.AutoAcknowledge))
                {
                    IDestination destination = SessionUtil.GetDestination(session, DESTINATION_NAME);
                    using(IMessageConsumer consumer = session.CreateConsumer(destination))
                    using(IMessageProducer producer = session.CreateProducer(destination))
                    {
                        try
                        {
                            producer.DeliveryMode = deliveryMode;
                            StreamMessage request = new StreamMessage();
                            request.Properties[propertyName] = propertyValue;

                            request.WriteBoolean(a);
                            request.WriteByte(b);
                            request.WriteChar(c);
                            request.WriteInt16(d);
                            request.WriteInt32(e);
                            request.WriteInt64(f);
                            request.WriteString(g);
                            request.WriteBoolean(h);
                            request.WriteByte(i);
                            request.WriteInt16(j);
                            request.WriteInt32(k);
                            request.WriteInt64(l);
                            request.WriteSingle(m);
                            request.WriteDouble(n);

                            producer.Send(request);

                            IStreamMessage message = consumer.Receive(receiveTimeout) as IStreamMessage;
                            Assert.IsNotNull(message, "No message returned!");
                            Assert.AreEqual(request.Properties.Count, message.Properties.Count, "Invalid number of properties.");
                            Assert.AreEqual(deliveryMode, message.NMSDeliveryMode, "NMSDeliveryMode does not match");

                            // Check the body
                            Assert.AreEqual(a, message.ReadBoolean(), "Stream Boolean Value: a");
                            Assert.AreEqual(b, message.ReadByte(), "Stream Byte Value: b");
                            Assert.AreEqual(c, message.ReadChar(), "Stream Char Value: c");
                            Assert.AreEqual(d, message.ReadInt16(), "Stream Int16 Value: d");
                            Assert.AreEqual(e, message.ReadInt32(), "Stream Int32 Value: e");
                            Assert.AreEqual(f, message.ReadInt64(), "Stream Int64 Value: f");
                            Assert.AreEqual(g, message.ReadString(), "Stream String Value: g");
                            Assert.AreEqual(h, message.ReadBoolean(), "Stream Boolean Value: h");
                            Assert.AreEqual(i, message.ReadByte(), "Stream Byte Value: i");
                            Assert.AreEqual(j, message.ReadInt16(), "Stream Int16 Value: j");
                            Assert.AreEqual(k, message.ReadInt32(), "Stream Int32 Value: k");
                            Assert.AreEqual(l, message.ReadInt64(), "Stream Int64 Value: l");
                            Assert.AreEqual(m, message.ReadSingle(), "Stream Single Value: m");
                            Assert.AreEqual(n, message.ReadDouble(), "Stream Double Value: n");

                            // use generic API to access entries
                            Assert.AreEqual(propertyValue, message.Properties[propertyName], "generic map entry: " + propertyName);

                            // use type safe APIs
                            Assert.AreEqual(propertyValue, message.Properties.GetString(propertyName),   "map entry: " + propertyName);
                        }
                        catch(NotSupportedException)
                        {
                        }
                    }
                }
            }
        }

    }
}

