/*
 * 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>
		/// <param name="newClientId">Client ID of the new connection.</param>
		/// <returns></returns>
		public virtual IConnection CreateConnectionAndStart(string newClientId = null)
		{
			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);
			}
		}
	}
}
