/*
 * 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 NMSPropertyTest : NMSTest
	{
		// standard NMS properties
		protected string expectedText = "Hey this works!";
		protected string correlationID = "FooBar";
		protected MsgPriority priority = MsgPriority.Normal;
		protected String type = "FooType";
		protected String groupID = "BarGroup";
		protected int groupSeq = 1;

		protected NMSPropertyTest(NMSTestSupport testSupport)
			: base (testSupport)
		{
		}

		//[Test]
		public void TestSendReceiveNMSProperties(
			//[Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]
			MsgDeliveryMode deliveryMode, string testDestRef)
		{
			using(IConnection connection = CreateConnection(GetTestClientId()))
			{
				connection.Start();
				using(ISession session = connection.CreateSession(AcknowledgementMode.AutoAcknowledge))
				{
					IDestination destination = GetClearDestinationByNodeReference(session, testDestRef);
					using(IMessageConsumer consumer = session.CreateConsumer(destination))
					using(IMessageProducer producer = session.CreateProducer(destination))
					{
						producer.Priority = priority;
						producer.DeliveryMode = deliveryMode;
						ITextMessage request = session.CreateTextMessage(expectedText);

						// Set the headers
						request.NMSCorrelationID = correlationID;
						request.NMSType = type;
						request.Properties["NMSXGroupID"] = groupID;
						request.Properties["NMSXGroupSeq"] = groupSeq;

						producer.Send(request);

						ITextMessage message = consumer.Receive(receiveTimeout) as ITextMessage;

						Assert.IsNotNull(message, "Did not receive an ITextMessage!");
						Assert.AreEqual(expectedText, message.Text, "Message text does not match.");

						// compare standard NMS headers
						Assert.AreEqual(correlationID, message.NMSCorrelationID, "NMSCorrelationID does not match");
						Assert.AreEqual(deliveryMode, message.NMSDeliveryMode, "NMSDeliveryMode does not match");
						Assert.AreEqual(priority, message.NMSPriority, "NMSPriority does not match");
						Assert.AreEqual(type, message.NMSType, "NMSType does not match");
						Assert.AreEqual(groupID, message.Properties["NMSXGroupID"], "NMSXGroupID does not match");
						Assert.AreEqual(groupSeq, message.Properties["NMSXGroupSeq"], "NMSXGroupSeq does not match");
					}
				}
			}
		}
	}
}
