/*
 * 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 Apache.NMS.Commands;
using NUnit.Framework;

namespace Apache.NMS.Test
{
    //[TestFixture]
    public class ForeignMessageTransformationTest : NMSTest
    {
        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;

		protected ForeignMessageTransformationTest(NMSTestSupport testSupport)
			: base(testSupport)
		{
		}

        //[Test]
        public virtual void TestSendReceiveForeignMessage(
            //[Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]
            MsgDeliveryMode deliveryMode, string testTopicRef)
        {
            using(IConnection connection = CreateConnection())
            {
                connection.Start();
                using(ISession session = connection.CreateSession(AcknowledgementMode.AutoAcknowledge))
                {
					IDestination destination = GetClearDestination(session, DestinationType.Topic, testTopicRef);
                    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 virtual void TestSendReceiveForeignTextMessage(
            //[Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]
            MsgDeliveryMode deliveryMode, string testTopicRef)
        {
            using(IConnection connection = CreateConnection())
            {
                connection.Start();
                using(ISession session = connection.CreateSession(AcknowledgementMode.AutoAcknowledge))
                {
					IDestination destination = GetClearDestination(session, DestinationType.Topic, testTopicRef);
                    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 virtual void TestSendReceiveForeignBytesMessage(
			//[Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]
			MsgDeliveryMode deliveryMode, string testTopicRef)
		{
			using(IConnection connection = CreateConnection())
			{
				connection.Start();
				using(ISession session = connection.CreateSession(AcknowledgementMode.AutoAcknowledge))
				{
					IDestination destination = GetClearDestination(session, DestinationType.Topic, testTopicRef);
					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 virtual void TestSendReceiveForeignMapMessage(
			//[Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]
			MsgDeliveryMode deliveryMode, string testTopicRef)
		{
			using(IConnection connection = CreateConnection())
			{
				connection.Start();
				using(ISession session = connection.CreateSession(AcknowledgementMode.AutoAcknowledge))
				{
					IDestination destination = GetClearDestination(session, DestinationType.Topic, testTopicRef);
					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 virtual void TestSendReceiveForeignStreamMessage(
			//[Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]
			MsgDeliveryMode deliveryMode, string testTopicRef)
		{
			using(IConnection connection = CreateConnection())
			{
				connection.Start();
				using(ISession session = connection.CreateSession(AcknowledgementMode.AutoAcknowledge))
				{
					IDestination destination = GetClearDestination(session, DestinationType.Topic, testTopicRef);
					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)
						{
						}
					}
				}
			}
		}
	}
}
