/*
 * 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.Reflection;
using System.Collections.Generic;
using Apache.NMS.ActiveMQ.Util;
using Apache.NMS.ActiveMQ.Transport.Discovery;
using Apache.NMS.ActiveMQ.Transport.Failover;
using Apache.NMS.ActiveMQ.Transport.Mock;
using Apache.NMS.ActiveMQ.Transport.Tcp;

namespace Apache.NMS.ActiveMQ.Transport
{
	public class TransportFactory
	{
		public static event ExceptionListener OnException;

        private static readonly FactoryFinder<ActiveMQTransportFactoryAttribute, ITransportFactory> FACTORY_FINDER =
            new FactoryFinder<ActiveMQTransportFactoryAttribute, ITransportFactory>();
		
        private readonly static object TRANSPORT_FACTORY_TYPES_LOCK = new object();
        private readonly static IDictionary<String, Type> TRANSPORT_FACTORY_TYPES = new Dictionary<String, Type>();

		public static void HandleException(Exception ex)
		{
			if(TransportFactory.OnException != null)
			{
				TransportFactory.OnException(ex);
			}
		}

        public void RegisterTransportFactory(string scheme, Type factoryType)
        {
			lock (TRANSPORT_FACTORY_TYPES_LOCK)
			{
            	TRANSPORT_FACTORY_TYPES[scheme] = factoryType;
			}
        }

		/// <summary>
		/// Creates a normal transport. 
		/// </summary>
		/// <param name="location"></param>
		/// <returns>the transport</returns>
		public static ITransport CreateTransport(Uri location)
		{
			ITransportFactory tf = TransportFactory.CreateTransportFactory(location);
			return tf.CreateTransport(location);
		}

		public static ITransport CompositeConnect(Uri location)
		{
			ITransportFactory tf = TransportFactory.CreateTransportFactory(location);
			return tf.CompositeConnect(location);
		}

		public static ITransport AsyncCompositeConnect(Uri location, SetTransport setTransport)
		{
			ITransportFactory tf = TransportFactory.CreateTransportFactory(location);
			return tf.CompositeConnect(location, setTransport);
		}

		/// <summary>
		/// Create a transport factory for the scheme.  If we do not support the transport protocol,
		/// an NMSConnectionException will be thrown.
		/// </summary>
		/// <param name="location"></param>
		/// <returns></returns>
		private static ITransportFactory CreateTransportFactory(Uri location)
		{
			string scheme = location.Scheme;

			if(string.IsNullOrEmpty(scheme))
			{
				throw new NMSConnectionException(String.Format("Transport scheme invalid: [{0}]", location.ToString()));
			}

			ITransportFactory factory = null;

			try
			{
                factory = NewInstance(scheme.ToLower());
			}
			catch(NMSConnectionException)
			{
				throw;
			}
			catch(Exception e)
			{
				throw new NMSConnectionException("Error creating transport.", e);
			}

			if(null == factory)
			{
				throw new NMSConnectionException("Unable to create a transport.");
			}

			return factory;
		}

        private static ITransportFactory NewInstance(string scheme)
        {
            try
            {
                Type factoryType = FindTransportFactory(scheme);

                if(factoryType == null)
                {
                    throw new Exception("NewInstance failed to find a match for id = " + scheme);
                }

                return (ITransportFactory) Activator.CreateInstance(factoryType);
            }
            catch(Exception ex)
            {
                Tracer.WarnFormat("NewInstance failed to create an ITransportFactory with error: {1}", ex.Message);
                throw;
            }
        }

        private static Type FindTransportFactory(string scheme)
        {
			lock (TRANSPORT_FACTORY_TYPES_LOCK)
			{			
	            if(TRANSPORT_FACTORY_TYPES.ContainsKey(scheme))
	            {
	                return TRANSPORT_FACTORY_TYPES[scheme];
	            }
			}
			
            try
            {
                Type factoryType = FACTORY_FINDER.FindFactoryType(scheme);
				
				lock (TRANSPORT_FACTORY_TYPES_LOCK)
				{			
                	TRANSPORT_FACTORY_TYPES[scheme] = factoryType;
				}
                return factoryType;
            }
            catch
            {
                throw new NMSConnectionException("Failed to find Factory for Transport type: " + scheme);
            }
        }
	}
}
