using System;
using System.Collections;
using System.IO;
using System.Security.Cryptography;
using System.Xml.XPath;
using QC.QsprShared.Trace;
using QC.QsprTestObjects.Tests.Base;
using QsprMiscShared.Utilities;

namespace QC.QTMApplication;

public class LinkedTree
{
	public struct LinkInformation
	{
		public string configFileName;

		public byte[] configFileChecksum;
	}

	public static Hashtable LinkInfo = new Hashtable();

	public static string configFileName(string fName)
	{
		try
		{
			return ((LinkInformation)LinkInfo[fName]).configFileName;
		}
		catch (Exception)
		{
			return "";
		}
	}

	public static byte[] configFileChecksum(string fName)
	{
		try
		{
			return ((LinkInformation)LinkInfo[fName]).configFileChecksum;
		}
		catch (Exception)
		{
			return new byte[0];
		}
	}

	public static void updateConfig(string fName)
	{
		LinkInformation linkInformation = default(LinkInformation);
		linkInformation.configFileName = getConfigFileName(fName);
		if (linkInformation.configFileName != "")
		{
			linkInformation.configFileChecksum = GetFileHash(linkInformation.configFileName);
		}
		else
		{
			linkInformation.configFileChecksum = new byte[0];
		}
		if (LinkInfo[fName] == null)
		{
			LinkInfo.Add(fName, linkInformation);
		}
		else
		{
			LinkInfo[fName] = linkInformation;
		}
	}

	public static void checkConfig(FolderTestProperties folderProperties)
	{
		if (!folderProperties.LinkConfigLocationEdited && hasChanged(folderProperties))
		{
			updateConfig(folderProperties.LinkLocation);
		}
	}

	private static bool hasChanged(FolderTestProperties folderProperties)
	{
		string text = getConfigFileName(folderProperties.LinkLocation);
		string configLocation = folderProperties.ConfigLocation;
		byte[] configChecksum = folderProperties.ConfigChecksum;
		if (text != configLocation)
		{
			return true;
		}
		if (text != "")
		{
			byte[] fileHash = GetFileHash(text);
			if (!AreChecksumsEqual(fileHash, configChecksum))
			{
				return true;
			}
		}
		return false;
	}

	public static string getConfigFileName(string fName)
	{
		string result = "";
		try
		{
			XPathDocument xPathDocument = new XPathDocument(fName);
			XPathNavigator xPathNavigator = xPathDocument.CreateNavigator();
			XPathNodeIterator xPathNodeIterator = xPathNavigator.Select("/SerializeComponents/theRootTest/RootProperties/ConfigFileName");
			if (xPathNodeIterator.MoveNext())
			{
				result = xPathNodeIterator.Current.Value;
			}
		}
		catch (Exception ex)
		{
			TraceMessage.Write("LinkedTreeConfig.cs ", "getConfigFileName " + ex.Message, TraceMessageType.Exception);
		}
		return result;
	}

	public static byte[] GetFileHash(string source)
	{
		byte[] result = new byte[0];
		try
		{
			using FileStream inputStream = new FileStream(source, FileMode.Open, FileAccess.Read);
			using MD5 mD = new MD5CryptoServiceProvider();
			result = mD.ComputeHash(inputStream);
		}
		catch (Exception ex)
		{
			TraceMessage.Write("LinkedTreeConfig.cs ", "GetFileHash  " + ex.Message, TraceMessageType.Exception);
		}
		return result;
	}

	public static bool AreChecksumsEqual(byte[] sourceChecksum, byte[] checksumToComapre)
	{
		if (sourceChecksum.Length != checksumToComapre.Length)
		{
			return false;
		}
		for (int i = 0; i < sourceChecksum.Length; i++)
		{
			if (sourceChecksum[i] != checksumToComapre[i])
			{
				return false;
			}
		}
		return true;
	}

	public static bool CanLinkTree(string fName, bool registeredOnly)
	{
		try
		{
			if (registeredOnly)
			{
				if (fName.ToLower().EndsWith(".cxtt"))
				{
					string decompressedFileName = TTDWpfTreeView.GetDecompressedFileName(fName);
					FileCompressionUtility.DecompressFile(fName, decompressedFileName);
					fName = decompressedFileName;
				}
				XPathDocument xPathDocument = new XPathDocument(fName);
				XPathNavigator navigator = xPathDocument.CreateNavigator();
				string xmlValue = GetXmlValue(navigator, "/SerializeComponents/theRootTest/RootProperties/TreeStringID");
				if (fName.ToLower().EndsWith(".cxtt"))
				{
					string decompressedFileName2 = TTDWpfTreeView.GetDecompressedFileName(fName);
					File.Delete(decompressedFileName2);
				}
				if (string.IsNullOrEmpty(xmlValue) || xmlValue == "-1")
				{
					return false;
				}
				return true;
			}
			return true;
		}
		catch (Exception ex)
		{
			TraceMessage.Write("LinkedTreeConfig.cs ", "getRegistration " + ex.Message, TraceMessageType.Exception);
			return false;
		}
	}

	public static Hashtable getRegistrationInfo(string fName)
	{
		Hashtable hashtable = new Hashtable();
		try
		{
			XPathDocument xPathDocument = new XPathDocument(fName);
			XPathNavigator navigator = xPathDocument.CreateNavigator();
			string value = GetXmlValue(navigator, "/SerializeComponents/theRootTest/RootProperties/TreeStringID");
			if (string.IsNullOrEmpty(value))
			{
				value = "-1";
			}
			hashtable.Add("TreeStringID", value);
			string value2 = GetXmlValue(navigator, "/SerializeComponents/theRootTest/RootProperties/NodeRID");
			if (string.IsNullOrEmpty(value2))
			{
				value2 = "-1";
			}
			hashtable.Add("TreeID", value2);
			hashtable.Add("SiteTreeID", GetXmlValue(navigator, "/SerializeComponents/theRootTest/RootProperties/SiteTreeID"));
			hashtable.Add("SiteKey", GetXmlValue(navigator, "/SerializeComponents/theRootTest/RootProperties/SiteKey"));
			hashtable.Add("RegisteredMachine", GetXmlValue(navigator, "/SerializeComponents/theRootTest/RootProperties/RegisteredMachine"));
		}
		catch (Exception ex)
		{
			TraceMessage.Write("LinkedTreeConfig.cs ", "getRegistrationInfo " + ex.Message, TraceMessageType.Exception);
		}
		return hashtable;
	}

	private static string GetXmlValue(XPathNavigator navigator, string nodePath)
	{
		string result = "";
		try
		{
			XPathNodeIterator xPathNodeIterator = navigator.Select(nodePath);
			if (xPathNodeIterator.MoveNext())
			{
				result = xPathNodeIterator.Current.Value;
			}
		}
		catch (Exception ex)
		{
			TraceMessage.Write("LinkedTreeConfig.cs ", "GetXmlValue " + ex.Message, TraceMessageType.Exception);
		}
		return result;
	}
}
