using System;
using System.Collections.Generic;
using System.IO;
using System.Threading;
using Microsoft.Win32;
using MultiLanguageManger;
using QC.QSPRAutomationInterface;

namespace QC.QMSCT;

public class QSPRGUIUnitProgrammer : QSPRUnitProgrammer
{
	private string ExecutablePath;

	private int BasePortNumber = 1500;

	private Application qsprApplication;

	private XTTDocument xttDocument;

	public override bool IsProcessAlive
	{
		get
		{
			if (qsprApplication != null)
			{
				return qsprApplication.IsQsprProcessAlive != 0;
			}
			return false;
		}
	}

	public override bool IsTestTreeValid
	{
		get
		{
			if (!IsXttDocumentEmpty())
			{
				return true;
			}
			return false;
		}
	}

	public event EventHandler<IntEventArgs> OnReceiveNumTests;

	private void VerifyExecutablePath()
	{
		if (!File.Exists(ExecutablePath))
		{
			throw new Exception(CommonResource.BoxMsgQsprNotFound + " " + ExecutablePath);
		}
	}

	public string GetExecutablePathFromRegistry()
	{
		try
		{
			string location = GetType().Assembly.Location;
			string fullName = Directory.GetParent(location).FullName;
			string text = Path.Combine(fullName, "qspr.exe");
			if (File.Exists(text))
			{
				return text;
			}
			RegistryKey classesRoot = Registry.ClassesRoot;
			RegistryKey registryKey = classesRoot.OpenSubKey("QSPR3.Application\\CLSID");
			string text2 = registryKey.GetValue("").ToString();
			RegistryKey registryKey2 = classesRoot.OpenSubKey("Wow6432Node\\CLSID\\" + text2 + "\\InprocServer32");
			if (registryKey2 == null)
			{
				registryKey2 = classesRoot.OpenSubKey("CLSID\\" + text2 + "\\InprocServer32");
			}
			string uriString = registryKey2.GetValue("CodeBase").ToString();
			Uri uri = new Uri(uriString);
			fullName = Directory.GetParent(uri.LocalPath).FullName;
			text = Path.Combine(fullName, "qspr.exe");
			if (File.Exists(text))
			{
				return text;
			}
			return null;
		}
		catch
		{
			return null;
		}
	}

	public QSPRGUIUnitProgrammer()
	{
		base.EngineName = "QSPRGUI";
		if (Environment.Is64BitOperatingSystem)
		{
			ExecutablePath = "C:\\Program Files (x86)\\Qualcomm\\QDART\\bin\\QSPR.exe";
		}
		else
		{
			ExecutablePath = "C:\\Program Files\\Qualcomm\\QDART\\bin\\QSPR.exe";
		}
		RegistNonCommonFunction();
	}

	public override void Start()
	{
		try
		{
			int num = base.GenericSetup.ConfigurationString.LastIndexOf(";");
			ExecutablePath = base.GenericSetup.ConfigurationString.Substring(0, num);
			BasePortNumber = int.Parse(base.GenericSetup.ConfigurationString.Substring(num + 1));
			VerifyExecutablePath();
			if (qsprApplication == null || (qsprApplication != null && qsprApplication.IsQsprProcessAlive == 0))
			{
				if (base.GenericSetup.ShowStartStopMessages)
				{
					AppendToLog("Launching QSPR...");
					AppendToLog("BackGroundColor: " + base.BackGroundColor.Name);
					AppendToLog("BasePortNumber: " + (BasePortNumber + base.Index));
					AppendToLog("QSPRExecutablePath: " + ExecutablePath);
					AppendToLog("");
					AppendToLog("TestPlanFilePath: " + base.TechnicalSetup.TestPlanFilePath);
				}
				qsprApplication = new Application(hideQSPRWindow: true, base.TechnicalSetup.TestPlanFilePath, base.BackGroundColor.Name, BasePortNumber + base.Index, ExecutablePath);
				if (base.GenericSetup.ShowStartStopMessages)
				{
					AppendToLog("Launching QSPR complete.");
				}
				Thread.Sleep(500);
				qsprApplication.ReceiveQSPRDebugMessages = 1;
				xttDocument = qsprApplication.ActiveDocument;
				BindToXttDocumentEvents();
				BindToQsprApplicationEvents();
				ProcessStarted();
				ProcessHidden(hiddenOkay: true);
			}
			xttDocument.CloseXTT();
			UnBindXttDocumentEvents();
			UnbindQsprApplicationEvents();
			qsprApplication.OpenXTT(base.TechnicalSetup.TestPlanFilePath);
			xttDocument = qsprApplication.ActiveDocument;
			BindToXttDocumentEvents();
			BindToQsprApplicationEvents();
			foreach (KeyValuePair<string, string> globalVble in base.GlobalVbles)
			{
				qsprApplication.SetGlobalVariable(globalVble.Key, globalVble.Value);
			}
		}
		catch (Exception ex)
		{
			AppendToLog(ex.Message);
		}
	}

	private bool KillQspr()
	{
		if (qsprApplication != null)
		{
			if (qsprApplication.Exit() != 1)
			{
				return false;
			}
			return true;
		}
		return false;
	}

	public override void Close()
	{
		if (xttDocument != null)
		{
			UnBindXttDocumentEvents();
			xttDocument = null;
		}
		if (qsprApplication != null)
		{
			UnbindQsprApplicationEvents();
			KillQspr();
			qsprApplication = null;
		}
	}

	protected override string GetErrorCode()
	{
		string result = "";
		try
		{
			result = qsprApplication.GetGlobalVariable("ERRORCODE");
		}
		catch
		{
		}
		return result;
	}

	protected override string GetSubErrorCode()
	{
		string result = "";
		try
		{
			result = qsprApplication.GetGlobalVariable("SUBERRORCODE");
		}
		catch
		{
		}
		return result;
	}

	private void BindToXttDocumentEvents()
	{
		xttDocument.SendStatus += xttDocument_SendStatus;
		xttDocument.TestStarted += xttDocument_TestItemStarted;
		xttDocument.TestDone += xttDocument_TestItemDone;
		xttDocument.GoNoGoStartWithCount += xttDocument_GoNoGoStartWithCount;
		xttDocument.GoNoGoDone += xttDocument_GoNoGoDone;
		xttDocument.GoNoGoDidNotStart += xttDocument_GoNoGoDidNotStart;
	}

	private void UnBindXttDocumentEvents()
	{
		xttDocument.SendStatus -= xttDocument_SendStatus;
		xttDocument.TestStarted -= xttDocument_TestItemStarted;
		xttDocument.TestDone -= xttDocument_TestItemDone;
		xttDocument.GoNoGoStartWithCount -= xttDocument_GoNoGoStartWithCount;
		xttDocument.GoNoGoDone -= xttDocument_GoNoGoDone;
		xttDocument.GoNoGoDidNotStart -= xttDocument_GoNoGoDidNotStart;
	}

	private void xttDocument_GoNoGoDidNotStart(string errorCode)
	{
		if (base.GenericSetup.ShowStartStopMessages)
		{
			AppendToLog("Error: Gonogo not started. Error Code from Test Tree: " + errorCode);
		}
		DisplayStatus("Error: Gonogo not started. Error Code from Test Tree: " + errorCode);
		ProcessDone(TestResult.Exception);
	}

	private void xttDocument_GoNoGoDone(int bPass)
	{
		if (base.GenericSetup.ShowStartStopMessages)
		{
			AppendToLog("Test tree ended at " + DateTime.Now.ToString());
		}
		DisplayStatus("Test tree ended at " + DateTime.Now.ToString());
		if (bPass == 0)
		{
			ProcessDone(TestResult.Failed);
		}
		else
		{
			ProcessDone(TestResult.Passed);
		}
	}

	private void xttDocument_TestItemStarted(string testName, string testPath)
	{
		if (base.GenericSetup.ShowStartStopMessages)
		{
			AppendToLog("Run: " + testName);
		}
		TestItemStarted(testName);
	}

	private void xttDocument_TestItemDone(string testName, int testStatus)
	{
		string text = ((testStatus == 0) ? "FAIL" : "PASS");
		TestResult testResu = ((testStatus != 0) ? TestResult.Passed : TestResult.Failed);
		if (base.GenericSetup.ShowStartStopMessages)
		{
			AppendToLog(text + ": " + testName);
		}
		TestItemDone(testName, testResu);
	}

	private void xttDocument_SendStatus(string status)
	{
	}

	private void xttDocument_GoNoGoStartWithCount(DateTime unitStartTime, int testCount)
	{
		if (base.GenericSetup.ShowStartStopMessages)
		{
			AppendToLog("Test tree started at " + unitStartTime.ToString());
		}
		DisplayStatus("Test tree started" + unitStartTime.ToString());
		if (this.OnReceiveNumTests != null)
		{
			this.OnReceiveNumTests(this, new IntEventArgs(testCount));
		}
	}

	private void BindToQsprApplicationEvents()
	{
		qsprApplication.QsprStarted += base.ProcessStarted;
		qsprApplication.QsprExited += base.ProcessExited;
		qsprApplication.QsprShown += base.ProcessShown;
		qsprApplication.QsprHidden += base.ProcessHidden;
		qsprApplication.DebugMessage += base.ProcessDebugMessage;
		qsprApplication.GlobalVariableModified += base.ProcessGlobalVariableModfied;
	}

	private void UnbindQsprApplicationEvents()
	{
		qsprApplication.QsprStarted -= base.ProcessStarted;
		qsprApplication.QsprExited -= base.ProcessExited;
		qsprApplication.QsprShown -= base.ProcessShown;
		qsprApplication.QsprHidden -= base.ProcessHidden;
		qsprApplication.DebugMessage -= base.ProcessDebugMessage;
		qsprApplication.GlobalVariableModified -= base.ProcessGlobalVariableModfied;
	}

	private bool IsXttDocumentEmpty()
	{
		if (xttDocument == null)
		{
			return true;
		}
		try
		{
			TestNode testNode = xttDocument.GetTestNode("");
			TestNode firstChild = testNode.GetFirstChild();
			if (firstChild.IsValid() == 1 && firstChild.GetFirstChild() != null)
			{
				return false;
			}
			return true;
		}
		catch
		{
			return true;
		}
	}

	private void RegistNonCommonFunction()
	{
		base.ShowEvent += Show;
		base.HideEvent += Hide;
		base.AbortEvent += Abort;
	}

	private void UnregistNonCommonFunction()
	{
		base.ShowEvent -= Show;
		base.HideEvent -= Hide;
		base.AbortEvent -= Abort;
	}

	public override void RunTest()
	{
		xttDocument.GoNoGo();
	}

	private void Show(object obj, BoolEventArgs args)
	{
		qsprApplication.MinimizeApp = 0;
		args.Data = true;
	}

	private void Hide(object obj, BoolEventArgs args)
	{
		qsprApplication.MinimizeApp = 1;
		args.Data = true;
	}

	private void Stop(object obj, BoolEventArgs args)
	{
		if (xttDocument != null)
		{
			xttDocument.XTTStop();
			args.Data = true;
		}
		args.Data = false;
	}

	private void Abort(object obj, BoolEventArgs args)
	{
		if (xttDocument != null)
		{
			args.Data = xttDocument.XTTAbort() == 1;
		}
		args.Data = false;
	}

	public override void Dispose()
	{
		Close();
		UnregistNonCommonFunction();
	}
}
