//>>***************************************************************************
//                              UNCLASSIFIED
//
//                COPYRIGHT 2017 RAYTHEON MISSILE SYSTEMS 
//                         ALL RIGHTS RESERVED
//   This data was developed pursuant to Contract Number HQ0147-12-C-0004/1088370
//     with the US Government. The US Government's rights in and to this 
//        copyrighted data are as specified in DFAR 252.227-7013 
//               which was made part of the above contract.
//
//    Distribution Statement: D -Distribution authorized to the DoD and DoD 
//       contractors only based on Critical Technology Requirements, May 2001.
//       Other requests shall be referred to PEO THEATER AIR DEFENSE (PMS 422).
//    Warning: - This document contains technical data whose export is restricted
//       by the Arms Export Control Act (Title 22, U.S.C.) or Export 
//       Administration Act of 1979, as amended (Title 50, U.S.C.). Violations 
//       of these laws are subject to severe criminal penalties. Disseminate in 
//       accordance with provisions of DoD 5230.25.
//    Destruction Notice: - For unclassified, limited distribution information, 
//       destroy by any method that will prevent disclosure of contents or 
//       reconstruction of the document. Classified information, destroy in 
//       accordance with DoD-5220.22-M or OPNAVINST 5510.1h.
//>>***************************************************************************

using NLog;
using Raytheon.Common;
using Raytheon.Units;
using System;
using System.Threading;

namespace Raytheon.Instruments
{
   /// <summary>
   /// </summary>
   public class PowerMeterSim : IPowerMeter
	{
		#region PublicMembers
		#endregion

		#region PrivateMembers

		private State _state;
		private SelfTestResult _selfTestResult;
		private string _name;
		private double _lastPowerLevel;

		/// <summary>
		/// NLog logger
		/// </summary>
		private readonly ILogger _logger;
		/// <summary>
		/// Raytheon configuration
		/// </summary>
		private readonly IConfigurationManager _configurationManager;
		private readonly IConfiguration _configuration;

		#endregion

		#region PrivateFunctions

		/// <summary>
		/// The Finalizer which will release resources if required
		/// </summary>
		~PowerMeterSim()
		{
			Dispose(false);
		}

		/// <summary>
		/// Dispose of this object
		/// </summary>
		/// <param name="disposing"></param>
		protected virtual void Dispose(bool disposing)
		{
			try
			{
				if (disposing)
				{
					if (_state == State.Ready)
					{
						Reset();

						_state = State.Uninitialized;
					}
				}
			}
			catch (Exception)
			{
				try
				{
					//ErrorLogger.Instance().Write(err.Message + "\r\n" + err.StackTrace);
				}
				catch (Exception)
				{
					//Do not rethrow. Exception from error logger that has already been garbage collected
				}
			}
		}

		#endregion

		/// <summary>
		/// PowerMeterSim factory constructor
		/// </summary>
		/// <param name="deviceName"></param>
		/// <param name="configurationManager"></param>
		public PowerMeterSim(string deviceName, IConfigurationManager configurationManager, ILogger logger)
		{
			Name = deviceName;

			_logger = logger;

			_configurationManager = configurationManager;
			_configuration = _configurationManager.GetConfiguration(Name);

			_state = State.Uninitialized;
			_selfTestResult = SelfTestResult.Unknown;
			_lastPowerLevel = 100.0;
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="name"></param>
		public PowerMeterSim(string name)
		{
			_name = name;
			_logger = LogManager.GetCurrentClassLogger();
			_state = State.Uninitialized;
			_selfTestResult = SelfTestResult.Unknown;
			_lastPowerLevel = 100.0;
		}

		/// <summary>
		/// 
		/// </summary>
		public int Channels
		{
			get
			{
				throw new NotImplementedException();
			}

			set
			{
				throw new NotImplementedException();
			}
		}

		/// <summary>
		/// 
		/// </summary>
		/// <returns></returns>
		public bool ClearErrors()
		{
			throw new NotImplementedException();
		}

		/// <summary>
		/// 
		/// </summary>
		public string DetailedStatus
		{
			get
			{
				return "This is a Sim Power Meter";
			}
		}

		/// <summary>
		/// 
		/// </summary>
		public bool DisplayEnabled
		{
			get
			{
				throw new NotImplementedException();
			}

			set
			{
				throw new NotImplementedException();
			}
		}

		/// <summary>
		/// Dispose of this objects resources
		/// </summary>
		public void Dispose()
		{
			try
			{
				Dispose(true);

				GC.SuppressFinalize(this);
			}
			catch (Exception)
			{
				try
				{
					//ErrorLogger.Instance().Write(err.Message + "\r\n" + err.StackTrace);
				}
				catch (Exception)
				{
					//Do not rethrow. Exception from error logger that has already been garbage collected
				}
			}
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="channel"></param>
		/// <param name="enable"></param>
		/// <returns></returns>
		public bool EnableChannel(int channel, bool enable)
		{
			throw new NotImplementedException();
		}

		/// <summary>
		/// 
		/// </summary>
		public bool FrontPanelEnabled
		{
			get
			{
				throw new NotImplementedException();
			}

			set
			{
				throw new NotImplementedException();
			}
		}

		/// <summary>
		/// 
		/// </summary>
		public InstrumentMetadata Info
		{
			get
			{
				throw new NotImplementedException();
			}
		}

		/// <summary>
		/// 
		/// </summary>
		public void Initialize()
		{
			// if we have not yet been initialized, go ahead and create the socket
			if (_state == State.Uninitialized)
			{
				Reset();

				// we already connected to the instrument in the constructor
				_state = State.Ready;
			}
			else
			{
				throw new Exception("expected the state of System " + _name + " to be Uninitialized, state was: " + _state.ToString());
			}
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="channel"></param>
		/// <returns></returns>
		public Power GetMeasurement(int channel)
		{
			double max = _lastPowerLevel;

			double min = 1.0;

			Random rnd = new Random();

			double seed = rnd.NextDouble();

			double dataToReturn = (seed * (max - min)) + min;

			Thread.Sleep(200);

			return Power.FromWatts(dataToReturn);
		}

		/// <summary>
		/// 
		/// </summary>
		public string Name
		{
			get
			{
				return _name;
			}
			set { _name = value; }
		}

		/// <summary>
		/// 
		/// </summary>
		public SelfTestResult SelfTestResult
		{
			get
			{
				return _selfTestResult;
			}
		}

		/// <summary>
		/// 
		/// </summary>
		public State Status
		{
			get
			{
				return _state;
			}
		}

		/// <summary>
		/// 
		/// </summary>
		/// <returns></returns>
		public SelfTestResult PerformSelfTest()
		{
			try
			{
				_selfTestResult = SelfTestResult.Pass;
				return _selfTestResult;
			}
			catch (Exception)
			{
				throw;
			}
		}

		/// <summary>
		/// 
		/// </summary>
		public void Reset()
		{
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="channel"></param>
		/// <param name="frequency"></param>
		/// <returns></returns>
		public bool SetFrequency(int channel, Frequency frequency)
		{
			return true;
		}

		/// <summary>
		/// 
		/// </summary>
		public void Shutdown()
		{
			if (_state == State.Ready)
			{
				_state = State.Uninitialized;
			}
		}

		/// <summary>
		/// 
		/// </summary>
		/// <returns></returns>
		public bool ZeroMeter()
		{
			throw new NotImplementedException();
		}
	}
}
