﻿/*
 * 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 System.Diagnostics;
using System.Threading;
using Apache.NMS.Test;
using Apache.NMS.Util;
using NUnit.Framework;

namespace Apache.NMS.ActiveMQ.Test
{
	[TestFixture]
	public class MaxInactivityDurationTest : NMSTestSupport
	{
		protected static string DESTINATION_NAME = "TEST.MaxInactivityDuration";
		protected static string CORRELATION_ID = "MaxInactivityCorrelationID";

		[Test]
		public void TestMaxInactivityDuration()
		{
			string testuri = "activemq:tcp://${activemqhost}:61616" +
										"?wireFormat.maxInactivityDurationInitialDelay=5000" +
										"&wireFormat.maxInactivityDuration=10000" +
										"&connection.asyncClose=false";

			NMSConnectionFactory factory = new NMSConnectionFactory(NMSTestSupport.ReplaceEnvVar(testuri));
			using(IConnection connection = factory.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))
					{
						SendMessage(producer);

						IMessage receivedMsg = consumer.Receive(TimeSpan.FromSeconds(5));
						Assert.AreEqual(CORRELATION_ID, receivedMsg.NMSCorrelationID, "Invalid correlation ID.");

						// Go inactive...
						Thread.Sleep(TimeSpan.FromSeconds(30));

						// Send another message.
						SendMessage(producer);
						receivedMsg = consumer.Receive(TimeSpan.FromSeconds(5));
						Assert.AreEqual(CORRELATION_ID, receivedMsg.NMSCorrelationID, "Invalid correlation ID.");
					}
				}
			}
		}

		protected void SendMessage(IMessageProducer producer)
		{
			IMessage request = producer.CreateMessage();
			request.NMSCorrelationID = CORRELATION_ID;
			request.NMSType = "Test";
			producer.Send(request);
		}

		[Test, Sequential]
		public void TestInactivityMonitorThreadLeak(
			[Values(0, 1000)]
			int inactivityDuration)
		{
			Process currentProcess = Process.GetCurrentProcess();
			Tracer.InfoFormat("Beginning thread count: {0}, handle count: {1}", currentProcess.Threads.Count, currentProcess.HandleCount);

			string testuri = string.Format("activemq:tcp://${{activemqhost}}:61616?wireFormat.maxInactivityDuration={0}", inactivityDuration);
	
			NMSConnectionFactory factory = new NMSConnectionFactory(NMSTestSupport.ReplaceEnvVar(testuri));

			// We measure the initial resource counts, and then allow a certain fudge factor for the resources
			// to fluctuate at run-time.  We allow for a certain amount of fluctuation, but if the counts
			// grow outside the safe boundaries of delayed garbage collection, then we fail the test.
			currentProcess = Process.GetCurrentProcess();
			int beginThreadCount = currentProcess.Threads.Count;
			int beginHandleCount = currentProcess.HandleCount;
			int maxThreadGrowth = 10;
			int maxHandleGrowth = 500;

			for(int i = 0; i < 200; i++)
			{
				using(IConnection connection = factory.CreateConnection("ResourceLeakTest", "Password"))
				{
					using(ISession session = connection.CreateSession())
					{
						IDestination destination = SessionUtil.GetDestination(session, "topic://TEST.NMSResourceLeak");
						using(IMessageConsumer consumer = session.CreateConsumer(destination))
						{
							connection.Start();
						}
					}
				}

				currentProcess = Process.GetCurrentProcess();
				int endThreadCount = currentProcess.Threads.Count;
				int endHandleCount = currentProcess.HandleCount;

				Assert.Less(endThreadCount, beginThreadCount + maxThreadGrowth, string.Format("Thread count grew beyond maximum of {0} on iteration #{1}.", maxThreadGrowth, i));
				Assert.Less(endHandleCount, beginHandleCount + maxHandleGrowth, string.Format("Handle count grew beyond maximum of {0} on iteration #{1}.", maxHandleGrowth, i));
			}
		}
	}
}
