using NLog;
using Raytheon.Common;
using System;
using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.IO;
using System.Reflection;

namespace Raytheon.Instruments
{
	[ExportInstrumentFactory(ModelNumber = "CommDeviceTcpClientFactory")]
	public class CommDeviceTcpClientFactory : IInstrumentFactory
	{
		/// <summary>
		/// The supported interfaces
		/// </summary>
		private readonly List<Type> _supportedInterfaces = new List<Type>();
		private ILogger _logger;
		private readonly IConfigurationManager _configurationManager;
		private const string DefaultConfigPath = @"C:\ProgramData\Raytheon\InstrumentManagerService";
		private static string DefaultPath;

		public CommDeviceTcpClientFactory(string defaultConfigPath = DefaultConfigPath)
			: this(null, defaultConfigPath)
		{
		}

		/// <summary>
		/// COECommDeviceInstrumentFactory injection constructor
		/// </summary>
		/// <param name="configManager"></param>
		/// <param name="simEngine"></param>
		/// <param name="logger"></param>
		[ImportingConstructor]
		public CommDeviceTcpClientFactory([Import(AllowDefault = false)] IConfigurationManager configManager,
									[Import(AllowDefault = true)] string defaultConfigPath = null)
		{
			DefaultPath = defaultConfigPath;

			if (LogManager.Configuration == null)
			{
				var assemblyFolder = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
				LogManager.Configuration = new NLog.Config.XmlLoggingConfiguration(assemblyFolder + "\\nlog.config");
			}

			_configurationManager = configManager ?? GetConfigurationManager();
			_supportedInterfaces.Add(typeof(ICommDevice));
		}
		/// <summary>
		/// Gets the instrument
		/// </summary>
		/// <param name="name"></param>
		/// <returns></returns>
		public IInstrument GetInstrument(string name)
		{
			try
			{
				_logger = LogManager.GetLogger(name);
				return new CommDeviceTcpClient(name, _configurationManager, _logger);
			}
			catch (Exception)
			{
				throw;
			}
		}

      /// <summary>
      /// Gets the instrument
      /// </summary>
      /// <param name="name"></param>
      /// <returns></returns>
      public object GetInstrument(string name, bool simulateHw)
      {
         try
         {
            _logger = LogManager.GetLogger(name);

            return new CommDeviceTcpClient(name, _configurationManager, _logger);
         }
         catch (Exception)
         {
            throw;
         }
      }

      /// <summary>
      /// Gets supported interfaces
      /// </summary>
      /// <returns></returns>
      public ICollection<Type> GetSupportedInterfaces()
		{
			return _supportedInterfaces.ToArray();
		}

		/// <summary>
		/// returns configuration based on the predefined path or default path c:/ProgramData/Raytheon/InstrumentManagerService
		/// </summary>
		/// <returns></returns>
		private static IConfigurationManager GetConfigurationManager()
		{
			return string.IsNullOrEmpty(DefaultPath) ? new RaytheonConfigurationManager() : new RaytheonConfigurationManager(DefaultPath);
		}
	}
}