// **********************************************************************************************************
//    DIOAdvantechFactory.cs
//    2/20/2023
//    NGI - Next Generation Interceptor
//    
//    Contract No. HQ0856-21-C-0003/1022000209
//    
//    THIS DOCUMENT DOES NOT CONTAIN TECHNOLOGY OR TECHNICAL DATA CONTROLLED UNDER EITHER THE U.S. 
//    INTERNATIONAL TRAFFIC IN ARMS REGULATIONS OR THE U.S. EXPORT ADMINISTRATION REGULATIONS.
//    
//    RAYTHEON PROPRIETARY: THIS DOCUMENT CONTAINS DATA OR INFORMATION PROPRIETARY TO RAYTHEON 
//    COMPANY AND IS RESTRICTED TO USE ONLY BY PERSONS AUTHORIZED BY RAYTHEON COMPANY IN WRITING TO USE IT. 
//    DISCLOSURE TO UNAUTHORIZED PERSONS WOULD LIKELY CAUSE SUBSTANTIAL COMPETITIVE HARM TO RAYTHEON 
//    COMPANY'S BUSINESS POSITION. NEITHER SAID DOCUMENT NOR ITS CONTENTS SHALL BE FURNISHED OR DISCLOSED 
//    TO OR COPIED OR USED BY PERSONS OUTSIDE RAYTHEON COMPANY WITHOUT THE EXPRESS WRITTEN APPROVAL OF 
//    RAYTHEON COMPANY.
//    
//    UNPUBLISHED WORK - COPYRIGHT RAYTHEON COMPANY.
//    
//    DESTRUCTION NOTICE: FOR CLASSIFIED DOCUMENTS FOLLOW THE PROCEDURES IN DOD 5220.22-M, 
//    NATIONAL INDUSTRIAL SECURITY PROGRAM OPERATING MANUAL, FEBRUARY 2006, 
//    INCORPORATING CHANGE 1, MARCH 28, 2013, CHAPTER 5, SECTION 7, OR DODM 5200.01-VOLUME 3, 
//    DOD INFORMATION SECURITY PROGRAM: PROTECTION OF CLASSIFIED INFORMATION, ENCLOSURE 3, 
//    SECTION 17. FOR CONTROLLED UNCLASSIFIED INFORMATION FOLLOW THE PROCEDURES IN DODM 5200.01-VOLUME 4, 
//    INFORMATION SECURITY PROGRAM: CONTROLLED UNCLASSIFIED INFORMATION.
//    
//    CONTROLLED BY: MISSILE DEFENSE AGENCY
//    CONTROLLED BY: GROUND-BASED MIDCOURSE DEFENSE PROGRAM OFFICE
//    CUI CATEGORY: CTI 
//    DISTRIBUTION/DISSEMINATION CONTROL: F 
//    POC: Alex Kravchenko (1118268)
// **********************************************************************************************************
using System;
using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.IO;
using System.Reflection;
using NLog;
using Raytheon.Common;

namespace Raytheon.Instruments
{
   [ExportInstrumentFactory(ModelNumber = "DIOAdvantechFactory")]
   public class DIOAdvantechFactory : IInstrumentFactory
   {
      private readonly List<Type> _supportedInterfaces = new List<Type>();

      private readonly IConfigurationManager _configurationManager;
      private const string DefaultConfigPath = @"C:\ProgramData\Raytheon\InstrumentManagerService";
      private static string DefaultPath;

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

      /// <summary>
      /// DIOAdvantechFactory injection constructor
      /// </summary>
      [ImportingConstructor]
      public DIOAdvantechFactory([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(IGeneralIO));
      }

      /// <summary>
      /// Gets the instrument
      /// </summary>
      /// <param name="name"></param>
      /// <returns></returns>
      public IInstrument GetInstrument(string name)
      {
         try
         {
            return new DIOAdvantech(name, _configurationManager);
         }
         catch (Exception)
         {
            throw;
         }
      }

      /// <summary>
      /// Gets the instrument
      /// </summary>
      /// <param name="name"></param>
      /// <returns></returns>
      public object GetInstrument(string name, bool simulateHw)
      {
         try
         {
            if (simulateHw)
               return new DIOSim(name, _configurationManager);
            else
               return new DIOAdvantech(name, _configurationManager);
         }
         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);
      }
   }
}
