using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using QC.QsprTestObjects.Registry;
using QC.QsprTestObjects.Tests.Base;
using QC.QsprTestObjects.Tests.DotNet;

namespace QC.QTMApplication.Validation;

public class DLLVersionValidator
{
	private QTMRegistry _registry;

	private Dictionary<string, Version> _filenames = new Dictionary<string, Version>();

	private List<string> _invalidTestIndexList = new List<string>();

	public DLLVersionValidator(QTMRegistry registry)
	{
		_registry = registry;
	}

	public bool Validate(BaseTest startingTest, out List<string> invalidTestIndexList)
	{
		invalidTestIndexList = new List<string>();
		GetFileVersions();
		ValidateTest(startingTest);
		invalidTestIndexList = _invalidTestIndexList;
		return invalidTestIndexList.Count == 0;
	}

	private void GetFileVersions()
	{
		_filenames.Clear();
		foreach (QTMThisPCTarget value in _registry.Targets.Values)
		{
			foreach (QTMTestContainer testContainer in value.TestContainers)
			{
				_registry.UpdateDllPath(testContainer, out var _);
			}
			foreach (QTMTestContainer testContainer2 in value.TestContainers)
			{
				string fileName = Path.GetFileName(testContainer2.Name);
				if (_filenames.ContainsKey(fileName) || !File.Exists(testContainer2.Name))
				{
					continue;
				}
				FileVersionInfo versionInfo = FileVersionInfo.GetVersionInfo(testContainer2.Name);
				Version result = null;
				if (versionInfo.FileVersion != null)
				{
					if (!Version.TryParse(versionInfo.FileVersion, out result))
					{
						result = new Version();
					}
				}
				else
				{
					result = new Version();
				}
				_filenames.Add(fileName, result);
			}
		}
	}

	private bool ValidateTest(BaseTest test)
	{
		if (test is DotNetTest)
		{
			if (!IsDllVersionValidForTest(test as DotNetTest))
			{
				_invalidTestIndexList.Add(test.Index);
			}
		}
		else if (test is FolderTest)
		{
			foreach (BaseTest test2 in ((FolderTest)test).TestList)
			{
				if (!ValidateTest(test2))
				{
					return false;
				}
			}
		}
		return true;
	}

	private bool IsDllVersionValidForTest(DotNetTest dotNetTest)
	{
		Version dLLVersion = GetDLLVersion(dotNetTest.DotNetProperties.DllName);
		if (dLLVersion == null)
		{
			return true;
		}
		if (!Version.TryParse(dotNetTest.DotNetProperties.MinDllVersion, out var result))
		{
			result = new Version();
		}
		return result <= dLLVersion;
	}

	private Version GetDLLVersion(string name)
	{
		if (string.IsNullOrEmpty(name) || !_filenames.ContainsKey(name))
		{
			return null;
		}
		return _filenames[name];
	}

	public bool ValidateRegistryVersions(out string errorMessage)
	{
		errorMessage = string.Empty;
		new List<string>();
		GetFileVersions();
		foreach (object value in _registry.Targets.Values)
		{
			QTMTarget qTMTarget = value as QTMTarget;
			foreach (object value2 in qTMTarget.HashContainers.Values)
			{
				QTMTestContainer qTMTestContainer = value2 as QTMTestContainer;
				if (!string.IsNullOrWhiteSpace(qTMTestContainer.Version))
				{
					if (!File.Exists(qTMTestContainer.Name))
					{
						errorMessage = $"The DLL {qTMTestContainer.Name} is required but not found.";
						return false;
					}
					FileVersionInfo versionInfo = FileVersionInfo.GetVersionInfo(qTMTestContainer.Name);
					Version result = new Version();
					if (!Version.TryParse(versionInfo.FileVersion, out result))
					{
						result = new Version();
					}
					Version version = new Version();
					if (!Version.TryParse(qTMTestContainer.Version, out result))
					{
						version = new Version();
					}
					if (version > result)
					{
						errorMessage = $"The DLL {qTMTestContainer.Name} version {result.ToString()} is lower than the required version {version.ToString()}";
						return false;
					}
				}
			}
		}
		return true;
	}
}
