//                           UNCLASSIFIED
/*-------------------------------------------------------------------------
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.

THIS PROPRIETARY NOTICE IS NOT APPLICABLE IF DELIVERED TO THE U.S.
GOVERNMENT.

UNPUBLISHED WORK - COPYRIGHT RAYTHEON COMPANY.
-------------------------------------------------------------------------*/

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

namespace Raytheon.Instruments
{
   /// <summary>
   /// A simulated video recorder
   /// </summary>
   public class VideoRecorderSim : IVideoRecorder
	{
		#region PrivateClassMembers
		private const string _SIM_VIDEO_FILE_NAME = "SimVideo";
		private string _lastGrabFileName;

		public string DetailedStatus { get; protected set; }

		public bool DisplayEnabled { get; set; }
		public bool FrontPanelEnabled { get; set; }

		public InstrumentMetadata Info { get; set; }

		public string Name { get; protected set; }

		public SelfTestResult SelfTestResult => PerformSelfTest();

		public State Status { get; set; }

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

		#endregion

		#region PrivateClassFunctions
		/// <summary>
		/// The Finalizer
		/// </summary>
		~VideoRecorderSim()
		{
			Dispose(false);
		}

		/// <summary>
		/// Dispose of this object
		/// </summary>
		/// <param name="disposing"></param>
		protected virtual void Dispose(bool disposing)
		{
			try
			{
				if (disposing)
				{
					Disconnect();
				}
			}
			catch (Exception err)
			{
				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

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

			_logger = logger;

			_configurationManager = configurationManager;
			_configuration = _configurationManager.GetConfiguration(Name);
		}
		/// <summary>
		/// The sim constructor
		/// </summary>
		public VideoRecorderSim()
		{
			_lastGrabFileName = "";
			_logger = LogManager.GetCurrentClassLogger();
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="videoFile"></param>
		/// <param name="attributeFile"></param>
		public void AddNcdfAttributes(string videoFile, string attributeFile)
		{
			Thread.Sleep(1000);
		}

		/// <summary>
		/// 
		/// </summary>
		public void Connect()
		{
			Thread.Sleep(1000);
		}

		/// <summary>
		/// 
		/// </summary>
		public void Disconnect()
		{
			Thread.Sleep(1000);
		}

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

				GC.SuppressFinalize(this);
			}
			catch (Exception err)
			{
				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>
		/// This will create an empty video file in the user temp folder
		/// </summary>
		/// <param name="numberOfFrames"></param>
		/// <param name="format"></param>
		public void GrabVideoToDisk(uint numberOfFrames, VideoSaveFormat format)
		{
			Thread.Sleep(1000);

			// create a dummy file
			string tempDirectory = Path.GetTempPath();

			string time = Util.GetTimeString();

			if (format == VideoSaveFormat.BIN)
			{
				tempDirectory += time + _SIM_VIDEO_FILE_NAME + ".bin";
			}
			else if (format == VideoSaveFormat.NCDF)
			{
				tempDirectory += time + _SIM_VIDEO_FILE_NAME + ".ncdf";
			}
			else
			{
				throw new Exception("UnhandledExceptionEventArgs save format" + format);
			}

			string simFileName = tempDirectory;

			File.Create(simFileName);

			_lastGrabFileName = simFileName;
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="driveSpace1">The number of free Gigabytes</param>
		/// <param name="driveSpace2">The number of free Gigabytes</param>
		/// <param name="driveSpace3">The number of free Gigabytes</param>
		/// <param name="driveSpace4">The number of free Gigabytes</param>
		public void QueryHardDrive(ref float driveSpace1, ref float driveSpace2, ref float driveSpace3, ref float driveSpace4)
		{
			const float FREE_SPACE_IN_GB = 10.0f;
			const float FULL_IN_GB = 0.0f;

			driveSpace1 = FREE_SPACE_IN_GB;
			driveSpace2 = FULL_IN_GB;
			driveSpace3 = FULL_IN_GB;
			driveSpace4 = FULL_IN_GB;
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="fromFile"></param>
		/// <param name="toFile"></param>
		/// <param name="control"></param>
		public void MoveFile(string fromFile, string toFile, MoveControl control)
		{
			File.Move(fromFile, toFile);
		}

		/// <summary>
		/// 
		/// </summary>
		public void ShowLiveVideo()
		{
			Thread.Sleep(1000);
		}

		/// <summary>
		/// 
		/// </summary>
		public void StopLiveVideo()
		{
			Thread.Sleep(1000);
		}

		/// <summary>
		/// This will return the file created by GrabVideoToDisk()
		/// </summary>
		/// <param name="timeoutms"></param>
		/// <returns></returns>
		public string WaitForGrabToComplete(int timeoutms)
		{
			Thread.Sleep(1000);

			// return the last file that was created, and clear the last file name for the next time
			string lastFileName = _lastGrabFileName;
			_lastGrabFileName = "";
			return lastFileName;
		}

		public bool ClearErrors()
		{
			return false;
		}

		public void Initialize()
		{
		}

		public SelfTestResult PerformSelfTest()
		{
			return SelfTestResult.Unknown;
		}

		public void Reset()
		{
			Shutdown();
			Initialize();
		}

		public void Shutdown()
		{
			Disconnect();
			Dispose();
		}

		public byte[] GetSmallVideoFrame(string name, int nFrames, bool sensor, ref uint numBytesRead, bool deleteVideoFile)
		{
			return new byte[1024];
		}
		#endregion
	}
}
