/*
 * 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.Collections;
using System.IO;
using System.Reflection;
using System.Text.RegularExpressions;
using System.Xml;
using Apache.NMS.Util;
using NUnit.Framework;

namespace Apache.NMS.Test
{
	/// <summary>
	/// useful base class for test cases
	/// </summary>
	public abstract class NMSTestSupport
	{
		private NMSConnectionFactory NMSFactory;
		protected TimeSpan receiveTimeout = TimeSpan.FromMilliseconds(15000);
		protected string clientId;
		protected string passWord;
		protected string userName;
		protected int testRun;
		protected int idCounter;

		static NMSTestSupport()
		{
			Apache.NMS.Tracer.Trace = new NmsTracer();
		}

		public NMSTestSupport()
		{
		}

		[SetUp]
		public virtual void SetUp()
		{
			this.testRun++;
		}

		[TearDown]
		public virtual void TearDown()
		{
		}

		// Properties

		/// <summary>
		/// The connection factory interface property.
		/// </summary>
		public IConnectionFactory Factory
		{
			get
			{
				if(null == NMSFactory)
				{
					Assert.IsTrue(CreateNMSFactory(), "Error creating factory.");
				}

				return NMSFactory.ConnectionFactory;
			}
		}

		/// <summary>
		/// Name of the connection configuration filename.
		/// </summary>
		/// <returns></returns>
		protected virtual string GetConnectionConfigFileName() { return "nmsprovider-test.config"; }

		/// <summary>
		/// The name of the connection configuration that CreateNMSFactory() will load.
		/// </summary>
		/// <returns></returns>
		protected virtual string GetNameTestURI() { return "defaultURI"; }

		/// <summary>
		/// Create the NMS Factory that can create NMS Connections.
		/// </summary>
		/// <returns></returns>
		protected bool CreateNMSFactory()
		{
			return CreateNMSFactory(GetNameTestURI());
		}

		/// <summary>
		/// Return the configured URI String.  This function loads the connection
		/// settings from the configuration file.
		/// </summary>
		/// <returns></returns>
		protected string GetConfiguredConnectionURI()
		{
			Uri brokerUri = null;
			string[] paths = GetConfigSearchPaths();
			string connectionConfigFileName = GetConnectionConfigFileName();
			bool configFound = false;

			foreach(string path in paths)
			{
				string fullpath = Path.Combine(path, connectionConfigFileName);
				Tracer.Debug("\tScanning folder: " + path);

				if(File.Exists(fullpath))
				{
					Tracer.Debug("\tAssembly found!");
					connectionConfigFileName = fullpath;
					configFound = true;
					break;
				}
			}

			Assert.IsTrue(configFound, "Connection configuration file does not exist.");
			XmlDocument configDoc = new XmlDocument();

			configDoc.Load(connectionConfigFileName);
			XmlElement uriNode = (XmlElement) configDoc.SelectSingleNode(String.Format("/configuration/{0}", GetNameTestURI()));

			if(null != uriNode)
			{
				// Replace any environment variables embedded inside the string.
				brokerUri = new Uri(ReplaceEnvVar(uriNode.GetAttribute("value")));
			}

			return brokerUri.ToString();
		}

		/// <summary>
		/// Create the NMS Factory that can create NMS Connections.  This function loads the
		/// connection settings from the configuration file.
		/// </summary>
		/// <param name="nameTestURI">The named connection configuration.</param>
		/// <returns></returns>
		protected bool CreateNMSFactory(string nameTestURI)
		{
			Uri brokerUri = null;
			string[] paths = GetConfigSearchPaths();
			object[] factoryParams = null;
			string connectionConfigFileName = GetConnectionConfigFileName();
			bool configFound = false;

			foreach(string path in paths)
			{
				string fullpath = Path.Combine(path, connectionConfigFileName);
				Tracer.Debug("\tScanning folder: " + path);

				if(File.Exists(fullpath))
				{
					Tracer.Debug("\tAssembly found!");
					connectionConfigFileName = fullpath;
					configFound = true;
					break;
				}
			}

			Assert.IsTrue(configFound, "Connection configuration file does not exist.");
			XmlDocument configDoc = new XmlDocument();

			configDoc.Load(connectionConfigFileName);
			XmlElement uriNode = (XmlElement) configDoc.SelectSingleNode(String.Format("/configuration/{0}", nameTestURI));

			if(null != uriNode)
			{
				// Replace any environment variables embedded inside the string.
				brokerUri = new Uri(ReplaceEnvVar(uriNode.GetAttribute("value")));
				factoryParams = GetFactoryParams(uriNode);
				clientId = ReplaceEnvVar(GetNodeValueAttribute(uriNode, "clientId", "NMSTestClientId"));
				userName = ReplaceEnvVar(GetNodeValueAttribute(uriNode, "userName", "guest"));
				passWord = ReplaceEnvVar(GetNodeValueAttribute(uriNode, "passWord", "guest"));
			}

			if(null == factoryParams)
			{
				NMSFactory = new Apache.NMS.NMSConnectionFactory(brokerUri);
			}
			else
			{
				NMSFactory = new Apache.NMS.NMSConnectionFactory(brokerUri, factoryParams);
			}

			return (null != NMSFactory);
		}

		private static string[] GetConfigSearchPaths()
		{
			ArrayList pathList = new ArrayList();

			// Check the current folder first.
			pathList.Add("");
#if !NETCF
			AppDomain currentDomain = AppDomain.CurrentDomain;

			// Check the folder the assembly is located in.
			pathList.Add(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location));
			if(null != currentDomain.BaseDirectory)
			{
				pathList.Add(currentDomain.BaseDirectory);
			}

			if(null != currentDomain.RelativeSearchPath)
			{
				pathList.Add(currentDomain.RelativeSearchPath);
			}
#endif

			return (string[]) pathList.ToArray(typeof(string));
		}

		/// <summary>
		/// Get the parameters for the ConnectionFactory from the configuration file.
		/// </summary>
		/// <param name="uriNode">Parent node of the factoryParams node.</param>
		/// <returns>Object array of parameter objects to be passsed to provider factory object.  Null if no parameters are specified in configuration file.</returns>
		protected object[] GetFactoryParams(XmlElement uriNode)
		{
			ArrayList factoryParams = new ArrayList();
			XmlElement factoryParamsNode = (XmlElement) uriNode.SelectSingleNode("factoryParams");

			if(null != factoryParamsNode)
			{
				XmlNodeList nodeList = factoryParamsNode.SelectNodes("param");

				if(null != nodeList)
				{
					foreach(XmlElement paramNode in nodeList)
					{
						string paramType = paramNode.GetAttribute("type");
						string paramValue = ReplaceEnvVar(paramNode.GetAttribute("value"));

						switch(paramType)
						{
							case "string":
								factoryParams.Add(paramValue);
								break;

							case "int":
								factoryParams.Add(int.Parse(paramValue));
								break;

							// TODO: Add more parameter types
						}
					}
				}
			}

			if(factoryParams.Count > 0)
			{
				return factoryParams.ToArray();
			}

			return null;
		}

		/// <summary>
		///
		/// </summary>
		/// <param name="parentNode"></param>
		/// <param name="nodeName"></param>
		/// <param name="dflt"></param>
		/// <returns></returns>
		protected static string GetNodeValueAttribute(XmlElement parentNode, string nodeName, string dflt)
		{
			XmlElement node = (XmlElement) parentNode.SelectSingleNode(nodeName);
			string val;

			if(null != node)
			{
				val = node.GetAttribute("value");
			}
			else
			{
				val = dflt;
			}

			return val;
		}

		/// <summary>
		/// Replace embedded variable markups with environment variable values.
		/// Variable markups are of the following form:
		///		${varname}
		/// </summary>
		/// <param name="srcText"></param>
		/// <returns></returns>
		public static string ReplaceEnvVar(string srcText)
		{
			// NOTE: Might be able to refactor to be more generic and support full variable
			// names that can be pulled from the environment.  Currently, we only support limited
			// hard-coded variable names.

			string defaultBroker = GetEnvVar("NMSTestBroker", "activemqhost");

			srcText = ReplaceEnvVar(srcText, "ActiveMQHost", defaultBroker);
			srcText = ReplaceEnvVar(srcText, "ActiveMQBackupHost", defaultBroker);

			srcText = ReplaceEnvVar(srcText, "TIBCOHost", defaultBroker);
			srcText = ReplaceEnvVar(srcText, "TIBCOBackupHost", defaultBroker);

			srcText = ReplaceEnvVar(srcText, "MSMQHost", defaultBroker);
			srcText = ReplaceEnvVar(srcText, "MSMQBackupHost", defaultBroker);
			return srcText;
		}

		/// <summary>
		/// Replace the variable with environment variable.
		/// </summary>
		/// <param name="srcText"></param>
		/// <param name="varName"></param>
		/// <param name="defaultValue"></param>
		/// <returns></returns>
		public static string ReplaceEnvVar(string srcText, string varName, string defaultValue)
		{
			string replacementValue = GetEnvVar(varName, defaultValue);
			return Regex.Replace(srcText, "\\${" + varName + "}", replacementValue, RegexOptions.IgnoreCase);
		}

		/// <summary>
		/// Get environment variable value.
		/// </summary>
		/// <param name="varName"></param>
		/// <param name="defaultValue"></param>
		/// <returns></returns>
		public static string GetEnvVar(string varName, string defaultValue)
		{
#if (PocketPC||NETCF||NETCF_2_0)
            string varValue = null;
#else
			string varValue = Environment.GetEnvironmentVariable(varName);
#endif
			if(null == varValue)
			{
				varValue = defaultValue;
			}

			return varValue;
		}

		public virtual string GetTestClientId()
		{

			System.Text.StringBuilder id = new System.Text.StringBuilder();

			id.Append("ID:");
			id.Append(this.GetType().Name);
			id.Append(":");
			id.Append(this.testRun);
			id.Append(":");
			id.Append(++idCounter);

			return id.ToString();
		}

		/// <summary>
		/// Create a new connection to the broker.
		/// </summary>
		/// <returns></returns>
		public virtual IConnection CreateConnection()
		{
			return CreateConnection(null);
		}

		/// <summary>
		/// Create a new connection to the broker.
		/// </summary>
		/// <param name="newClientId">Client ID of the new connection.</param>
		/// <returns></returns>
		public virtual IConnection CreateConnection(string newClientId)
		{
			IConnection newConnection = Factory.CreateConnection(userName, passWord);
			Assert.IsNotNull(newConnection, "connection not created");
			if(newClientId != null)
			{
				newConnection.ClientId = newClientId;
			}

			return newConnection;
		}

		/// <summary>
		/// Create a new connection to the broker, and start it.
		/// </summary>
		/// <returns></returns>
		public virtual IConnection CreateConnectionAndStart()
		{
			return CreateConnectionAndStart(null);
		}

		/// <summary>
		/// Create a new connection to the broker, and start it.
		/// </summary>
		/// <param name="newClientId">Client ID of the new connection.</param>
		/// <returns></returns>
		public virtual IConnection CreateConnectionAndStart(string newClientId)
		{
			IConnection newConnection = CreateConnection(newClientId);
			newConnection.Start();
			return newConnection;
		}

		public IDestination CreateDestination(ISession session, DestinationType type)
		{
			return CreateDestination(session, type, "");
		}

		public IDestination CreateDestination(ISession session, DestinationType type, string name)
		{
			switch(type)
			{
				case DestinationType.Queue:
					if(string.IsNullOrEmpty(name))
					{
						name = "queue://TEST." + this.GetType().Name + "." + Guid.NewGuid().ToString();
					}
					break;

				case DestinationType.Topic:
					if(string.IsNullOrEmpty(name))
					{
						name = "topic://TEST." + this.GetType().Name + "." + Guid.NewGuid().ToString();
					}
					break;

				case DestinationType.TemporaryQueue:
					if(string.IsNullOrEmpty(name))
					{
						name = "temp-queue://TEST." + this.GetType().Name + "." + Guid.NewGuid().ToString();
					}
					break;

				case DestinationType.TemporaryTopic:
					if(string.IsNullOrEmpty(name))
					{
						name = "temp-topic://TEST." + this.GetType().Name + "." + Guid.NewGuid().ToString();
					}
					break;

				default:
					throw new ArgumentException("type: " + type);
			}

			return CreateDestination(session, name);
		}

		/// <summary>
		/// Create a destination.  This will delete an existing destination and re-create it.
		/// </summary>
		/// <param name="session"></param>
		/// <param name="destinationName"></param>
		/// <returns></returns>
		public virtual IDestination CreateDestination(ISession session, string destinationName)
		{
			try
			{
				SessionUtil.DeleteDestination(session, destinationName);
			}
			catch(Exception)
			{
				// Can't delete it, so lets try and purge it.
				IDestination destination = SessionUtil.GetDestination(session, destinationName);

				using(IMessageConsumer consumer = session.CreateConsumer(destination))
				{
					while(consumer.Receive(TimeSpan.FromMilliseconds(750)) != null)
					{
					}
				}
			}

			return SessionUtil.GetDestination(session, destinationName);
		}

		/// <summary>
		/// Register a durable consumer
		/// </summary>
		/// <param name="connectionID">Connection ID of the consumer.</param>
		/// <param name="destination">Destination name to register.  Supports embedded prefix names.</param>
		/// <param name="consumerID">Name of the durable consumer.</param>
		/// <param name="selector">Selector parameters for consumer.</param>
		/// <param name="noLocal"></param>
		protected void RegisterDurableConsumer(string connectionID, string destination, string consumerID, string selector, bool noLocal)
		{
			using(IConnection connection = CreateConnection(connectionID))
			{
				connection.Start();
				using(ISession session = connection.CreateSession(AcknowledgementMode.DupsOkAcknowledge))
				{
					ITopic destinationTopic = (ITopic) SessionUtil.GetDestination(session, destination);
					Assert.IsNotNull(destinationTopic, "Could not get destination topic.");
					using(IMessageConsumer consumer = session.CreateDurableConsumer(destinationTopic, consumerID, selector, noLocal))
					{
						Assert.IsNotNull(consumer, "Could not create durable consumer.");
					}
				}
			}
		}

		/// <summary>
		/// Unregister a durable consumer for the given connection ID.
		/// </summary>
		/// <param name="connectionID">Connection ID of the consumer.</param>
		/// <param name="consumerID">Name of the durable consumer.</param>
		protected void UnregisterDurableConsumer(string connectionID, string consumerID)
		{
			using(IConnection connection = CreateConnection(connectionID))
			{
				connection.Start();
				using(ISession session = connection.CreateSession(AcknowledgementMode.DupsOkAcknowledge))
				{
					session.DeleteDurableConsumer(consumerID);
				}
			}
		}

		public static string ToHex(long value)
		{
			return String.Format("{0:x}", value);
		}

		public void SendMessages(IDestination destination, MsgDeliveryMode deliveryMode, int count)
		{
			IConnection connection = CreateConnection();
			connection.Start();
			SendMessages(connection, destination, deliveryMode, count);
			connection.Close();
		}

		public void SendMessages(IConnection connection, IDestination destination, MsgDeliveryMode deliveryMode, int count)
		{
			ISession session = connection.CreateSession(AcknowledgementMode.AutoAcknowledge);
			SendMessages(session, destination, deliveryMode, count);
			session.Close();
		}

		public void SendMessages(ISession session, IDestination destination, MsgDeliveryMode deliveryMode, int count)
		{
			IMessageProducer producer = session.CreateProducer(destination);
			producer.DeliveryMode = deliveryMode;
			for(int i = 0; i < count; i++)
			{
				producer.Send(session.CreateTextMessage("" + i));
			}
			producer.Close();
		}

		protected void AssertTextMessagesEqual(IMessage[] firstSet, IMessage[] secondSet)
		{
			AssertTextMessagesEqual(firstSet, secondSet, "");
		}

		protected void AssertTextMessagesEqual(IMessage[] firstSet, IMessage[] secondSet, string messsage)
		{
			Assert.AreEqual(firstSet.Length, secondSet.Length, "Message count does not match: " + messsage);

			for(int i = 0; i < secondSet.Length; i++)
			{
				ITextMessage m1 = firstSet[i] as ITextMessage;
				ITextMessage m2 = secondSet[i] as ITextMessage;

				AssertTextMessageEqual(m1, m2, "Message " + (i + 1) + " did not match : ");
			}
		}

		protected void AssertEquals(ITextMessage m1, ITextMessage m2)
		{
			AssertEquals(m1, m2, "");
		}

		protected void AssertTextMessageEqual(ITextMessage m1, ITextMessage m2, string message)
		{
			Assert.IsFalse(m1 == null ^ m2 == null, message + ": expected {" + m1 + "}, but was {" + m2 + "}");

			if(m1 == null)
			{
				return;
			}

			Assert.AreEqual(m1.Text, m2.Text, message);
		}

		protected void AssertEquals(IMessage m1, IMessage m2)
		{
			AssertEquals(m1, m2, "");
		}

		protected void AssertEquals(IMessage m1, IMessage m2, string message)
		{
			Assert.IsFalse(m1 == null ^ m2 == null, message + ": expected {" + m1 + "}, but was {" + m2 + "}");

			if(m1 == null)
			{
				return;
			}

			Assert.IsTrue(m1.GetType() == m2.GetType(), message + ": expected {" + m1 + "}, but was {" + m2 + "}");

			if(m1 is ITextMessage)
			{
				AssertTextMessageEqual((ITextMessage) m1, (ITextMessage) m2, message);
			}
			else
			{
				Assert.AreEqual(m1, m2, message);
			}
		}
	}
}
