context: using Halsign.DWM.Framework;
  using CookComputing.XmlRpc;
  using System;
  using System.Collections.Generic;
  using System.IO;
  using System.Net;
  using System.Net.Sockets;
  using System.Threading;
  using XenAPI;
  namespace Halsign.DWM.Collectors
  {
  	public class XenCollectorActions : XenCollectorBase, ICollectorActions
  	{
  		private Dictionary<string, string> _vmCache;
  		private Dictionary<string, string> _hostCache;
  		private object _vmCacheLock = new object();
  		private object _hostCacheLock = new object();
  		public XenCollectorActions()
  		{
  		}
  		public XenCollectorActions(string hostname, int port, string username, string password) : base(hostname, port, "http", username, password)
  		{
  		}
  		public void Start()
  		{
  			base.StartCollection();
  		}
  		public void Stop()
  		{
  			base.StopCollection();
  		}
  		protected override void ProcessVmEvent(string vmUuid, string operation, string serverOpaqueRef, XmlRpcStruct snapshot)
  		{
  			if (this._vmCache != null)
  			{
  				if (Localization.Compare(operation, "del", true) == 0)
  				{
  					if (this._vmCache.ContainsKey(vmUuid))
  					{
  						this._vmCache.Remove(vmUuid);
  					}
  				}
  				else
  				{
  					if (Localization.Compare(operation, "add", true) == 0)
  					{
  						if (!this._vmCache.ContainsKey(vmUuid))
  						{
  							this._vmCache.Add(vmUuid, serverOpaqueRef);
  						}
  						else
  						{
  							this._vmCache[vmUuid] = serverOpaqueRef;
  						}
  					}
  				}
  			}
  		}
  		protected override void ProcessHostEvent(string hostUuid, string operation, string serverOpaqueRef, XmlRpcStruct snapshot)
  		{
  			if (this._hostCache != null)
  			{
  				if (Localization.Compare(operation, "del", true) == 0)
  				{
  					if (this._hostCache.ContainsKey(hostUuid))
  					{
  						this._hostCache.Remove(hostUuid);
  					}
  				}
  				else
  				{
  					if (Localization.Compare(operation, "add", true) == 0)
  					{
  						if (!this._hostCache.ContainsKey(hostUuid))
  						{
  							this._hostCache.Add(hostUuid, serverOpaqueRef);
  						}
  						else
  						{
  							this._hostCache[hostUuid] = serverOpaqueRef;
  						}
  					}
  				}
  			}
  		}
  		protected override void EndSession()
  		{
  			base.EndSession();
  			if (this._hostCache != null)
  			{
  				this._hostCache.Clear();
  				this._hostCache = null;
  			}
  			if (this._vmCache != null)
  			{
  				this._vmCache.Clear();
  				this._vmCache = null;
  			}
  		}
  		public string GetPoolName()
  		{
  			string result = string.Empty;
  			if (this.IsInitialized)
  			{
  				Dictionary<XenRef<Pool>, Pool> dictionary = Pool.get_all_records(this._session);
  				foreach (KeyValuePair<XenRef<Pool>, Pool> current in dictionary)
  				{
  					result = current.Value.name_label;
  				}
  				return result;
  			}
  			throw new DwmException("Data collector is not properly initialized.  Call the Initialize method before calling the GetPoolName method", DwmErrorCode.NotInitialized, null);
  		}
  		public string GetPoolUniqueIdentifier()
  		{
  			string result = string.Empty;
  			if (this.IsInitialized)
  			{
  				Dictionary<XenRef<Pool>, Pool> dictionary = Pool.get_all_records(this._session);
  				foreach (KeyValuePair<XenRef<Pool>, Pool> current in dictionary)
  				{
  					result = current.Value.uuid;
  				}
  				return result;
  			}
  			throw new DwmException("Data collector is not properly initialized.  Call the Initialize method before calling the GetPoolUniqueIdentifier method", DwmErrorCode.NotInitialized, null);
  		}
  		public void GetCerts()
  		{
  			Session session = null;
  			try
  			{
  				session = new Session(this._hostName, this._hostPort);
  				session.login_with_password(this._username, this._password);
  			}
  			catch (Failure failure)
  			{
  				throw new DwmException(failure.Message, DwmErrorCode.XenCannotLogIn, failure);
  			}
  			catch (SocketException ex)
  			{
  				throw new DwmException(ex.Message, DwmErrorCode.XenCannotLogIn, ex);
  			}
  			catch (WebException innerException)
  			{
  				throw new DwmException(Localization.Format("Cannot connect to Xen {0}:{1} hypervisor.  The most likely causes include the machine being offline or an incorrect TCP/IP address.", this._hostName, this._hostPort), DwmErrorCode.XenCannotConnect, innerException);
  			}
  			try
  			{
  				Dictionary<XenRef<Host>, Host> dictionary = Host.get_all_records(session);
  				foreach (KeyValuePair<XenRef<Host>, Host> current in dictionary)
  				{
  					Host value = current.Value;
  					string value2 = Host.get_server_certificate(session, current.Key);
  					string text = string.Format("{0}\\{1}.cer", Logger.GetLogDirectory(), current.Value.name_label);
  					char[] invalidFileNameChars = Path.GetInvalidFileNameChars();
  					for (int i = 0; i < invalidFileNameChars.Length; i++)
  					{
  						if (text.IndexOf(invalidFileNameChars[i]) != -1)
  						{
  							text.Replace(invalidFileNameChars[i], '_');
  						}
  					}
  					using (StreamWriter streamWriter = new StreamWriter(text))
  					{
  						streamWriter.Write(value2);
  						streamWriter.Close();
  					}
  				}
  				session.logout();
  			}
  			catch (Failure ex2)
  			{
  				Logger.LogException(ex2);
  			}
  			catch (SocketException ex3)
  			{
  				Logger.LogException(ex3);
  			}
  			catch (WebException ex4)
  			{
  				Logger.LogException(ex4);
  			}
  		}
  		protected override void OnInterval()
  		{
  			if (this._session == null && base.InitializeSession(this._hostName, true, false) != XenCollectorBase.SessionInitStatus.Success)
  			{
  				base.OnConnectionLost(null);
  			}
  			if (this._session != null && base.Heartbeat())
  			{
  				object hostCacheLock = this._hostCacheLock;
  				Monitor.Enter(hostCacheLock);
  				try
  				{
  					if (this._hostCache == null)
  					{
  						this.GetHosts();
  					}
  				}
  				finally
  				{
  					Monitor.Exit(hostCacheLock);
  				}
  				object vmCacheLock = this._vmCacheLock;
  				Monitor.Enter(vmCacheLock);
  				try
  				{
  					if (this._vmCache == null)
  					{
  						this.GetVMs();
  					}
  				}
  				finally
  				{
  					Monitor.Exit(vmCacheLock);
  				}
  			}
  		}
  		private void GetHosts()
  		{
  			try
  			{
  				if (this._session != null)
  				{
  					Dictionary<XenRef<Host>, Host> dictionary = Host.get_all_records(this._session);
  					if (dictionary != null)
  					{
  						this._hostCache = new Dictionary<string, string>();
  						foreach (KeyValuePair<XenRef<Host>, Host> current in dictionary)
  						{
  							this._hostCache.Add(current.Value.uuid, current.Key.opaque_ref);
  						}
  					}
  				}
  			}
  			catch (Failure ex)
  			{
  				Logger.LogException(ex);
  			}
  			catch (SocketException ex2)
  			{
  				Logger.LogException(ex2);
  			}
  			catch (WebException ex3)
  			{
  				Logger.LogException(ex3);
  			}
  		}
  		private void GetVMs()
  		{
  			try
  			{
  				if (this._session != null)
  				{
  					Dictionary<XenRef<VM>, VM> dictionary = VM.get_all_records(this._session);
  					if (dictionary != null)
  					{
  						this._vmCache = new Dictionary<string, string>();
  						foreach (KeyValuePair<XenRef<VM>, VM> current in dictionary)
  						{
  							this._vmCache.Add(current.Value.uuid, current.Key.opaque_ref);
  						}
  					}
  				}
  			}
  			catch (Failure ex)
  			{
  				Logger.LogException(ex);
  			}
  			catch (SocketException ex2)
  			{
  				Logger.LogException(ex2);
  			}
  			catch (WebException ex3)
  			{
  				Logger.LogException(ex3);
  			}
  		}
  		public CantBootReason CanStartVM(string vmUuid, string hostUuid)
  		{
  			CantBootReason result = CantBootReason.None;
  			Logger.Trace("ICollectorActions.CanStartVM called for VM {0}, Host {1}", new object[]
  			{
  				vmUuid,
  				hostUuid
  			});
  			if (!string.IsNullOrEmpty(vmUuid) && !string.IsNullOrEmpty(hostUuid))
  			{
  				if (this.IsInitialized)
  				{
  					string hostRefForUuid = this.GetHostRefForUuid(hostUuid);
  					string text = null;
  					if (hostRefForUuid != null)
  					{
  						text = this.GetVmRefForUuid(vmUuid);
  					}
  					if (text != null && hostRefForUuid != null)
  					{
  						try
  						{
  							VM.assert_can_boot_here(this._session, text, hostRefForUuid);
  							Logger.Trace("VM.assert_can_boot_here returns true.  VM={0}  Host={1}", new object[]
  							{
  								vmUuid,
  								hostUuid
  							});
  						}
  						catch (Failure failure)
  						{
  							Logger.Trace("VM.assert_can_boot_here fails with {0}.  VM={1}  Host={2}", new object[]
  							{
  								failure.Message,
  								vmUuid,
  								hostUuid
  							});
  							result = base.FailureToReason(failure);
  						}
  						catch (SocketException)
  						{
  							result = CantBootReason.SocketException;
  						}
  						catch (WebException)
  						{
  							result = CantBootReason.WebException;
  						}
  						catch (Exception)
  						{
  							result = CantBootReason.GeneralException;
  						}
  					}
  					else
  					{
  						Logger.Trace("ICollectorActions.CanStartVM - failure - vmServerRef or hostServerRef is not initialized properly");
  					}
  				}
  				else
  				{
  					Logger.Trace("ICollectorActions.CanStartVM - Data collector not properly initialized");
  				}
  			}
  			return result;
  		}
  		public int StartVM(string vmUuid, string hostUuid, bool startPaused)
  		{
  			int result = 0;
  			if (!string.IsNullOrEmpty(vmUuid) && !string.IsNullOrEmpty(hostUuid))
  			{
  				if (this.IsInitialized)
  				{
  					string hostRefForUuid = this.GetHostRefForUuid(hostUuid);
  					string text = null;
  					if (hostRefForUuid != null)
  					{
  						text = this.GetVmRefForUuid(vmUuid);
  					}
  					if (text != null && hostRefForUuid != null)
  					{
  						try
  						{
  							VM.start_on(this._session, text, hostRefForUuid, startPaused, true);
  						}
  						catch (Failure ex)
  						{
  							Logger.LogError("Exception starting VM {0} to host {1}", new object[]
  							{
  								vmUuid,
  								hostUuid
  							});
  							Logger.LogException(ex);
  							result = 1;
  						}
  					}
  					else
  					{
  						result = 4007;
  					}
  				}
  				else
  				{
  					result = 4012;
  				}
  			}
  			else
  			{
  				result = 4007;
  			}
  			return result;
  		}
  		public int MigrateVM(string vmUuid, string migrateToHostUuid, int recommendationId, bool liveMigration)
  		{
  			int result = 0;
  			if (!string.IsNullOrEmpty(vmUuid) && !string.IsNullOrEmpty(migrateToHostUuid))
  			{
  				if (this.IsInitialized)
  				{
  					string hostRefForUuid = this.GetHostRefForUuid(migrateToHostUuid);
  					string text = null;
  					if (hostRefForUuid != null)
  					{
  						text = this.GetVmRefForUuid(vmUuid);
  					}
  
gt: 					if (text != null && hostRefForUuid != null)