using System;
using System.Collections.Generic;
using System.IO;
using QC.QSPRSchedulerWrapper;

namespace QC.QMSCT;

public class QIAUnitProgrammer : QSPRUnitProgrammer
{
	private QSPRScheduler qsprScheduler;

	private QSPRTestTree qsprTestTree;

	public override bool IsTestTreeValid
	{
		get
		{
			try
			{
				return File.Exists(base.TechnicalSetup.TestPlanFilePath);
			}
			catch (Exception)
			{
				return false;
			}
		}
	}

	public override bool IsProcessAlive => false;

	public QIAUnitProgrammer()
	{
		base.EngineName = "QIA";
	}

	public override void Start()
	{
		if (qsprScheduler == null)
		{
			qsprScheduler = new QSPRScheduler();
			BindToQsprSchedulerEvents();
		}
		if (qsprTestTree != null)
		{
			UnbindQsprTestTreeEvents();
		}
		qsprTestTree = qsprScheduler.OpenXTT(base.TechnicalSetup.TestPlanFilePath);
		BindToQsprTestTreeEvents();
		foreach (KeyValuePair<string, string> globalVble in base.GlobalVbles)
		{
			qsprScheduler.SetGlobalVariable(globalVble.Key, globalVble.Value);
		}
	}

	public override void RunTest()
	{
		qsprTestTree.RunTree();
	}

	public override void Close()
	{
		if (qsprTestTree != null)
		{
			UnbindQsprTestTreeEvents();
			qsprTestTree = null;
		}
		if (qsprScheduler != null)
		{
			qsprScheduler.Close();
			UnbindQsprSchedulerEvents();
			qsprScheduler = null;
		}
	}

	protected override string GetErrorCode()
	{
		string value = "";
		try
		{
			qsprScheduler.GetGlobalVariable("ERRORCODE", out value);
		}
		catch
		{
		}
		return value;
	}

	protected override string GetSubErrorCode()
	{
		string value = "";
		try
		{
			qsprScheduler.GetGlobalVariable("SUBERRORCODE", out value);
		}
		catch
		{
		}
		return value;
	}

	private void BindToQsprSchedulerEvents()
	{
		qsprScheduler.OnDebugMessage += scheduler_OnDebugMessage;
		qsprScheduler.OnGlobalVariableChanged += scheduler_OnGlobalVariableChanged;
		qsprScheduler.OnTestMessage += scheduler_OnTestMessage;
	}

	private void BindToQsprTestTreeEvents()
	{
		qsprTestTree.RunTreeDone += testTree_RunTreeDone;
	}

	private void UnbindQsprSchedulerEvents()
	{
		qsprScheduler.OnDebugMessage -= scheduler_OnDebugMessage;
		qsprScheduler.OnGlobalVariableChanged -= scheduler_OnGlobalVariableChanged;
		qsprScheduler.OnTestMessage -= scheduler_OnTestMessage;
	}

	private void UnbindQsprTestTreeEvents()
	{
		qsprTestTree.RunTreeDone -= testTree_RunTreeDone;
	}

	private void scheduler_OnGlobalVariableChanged(string gvName, string gvValue)
	{
		ProcessGlobalVariableModfied(gvName, gvValue);
	}

	private void scheduler_OnDebugMessage(string strWin, string strText, int traceLevel, bool NoEndOfLine)
	{
		SetStatus(strWin, strText, traceLevel);
	}

	private void scheduler_OnTestMessage(int messageType, QSPRTestMessage messageData)
	{
		switch ((TestMsgTypes)messageType)
		{
		case TestMsgTypes.ON_UNIT_START:
		{
			DateTime now = DateTime.Now;
			if (base.GenericSetup.ShowStartStopMessages)
			{
				AppendToLog("Test tree started at " + now.ToString());
			}
			DisplayStatus("Test tree started" + now.ToString());
			break;
		}
		case TestMsgTypes.ON_UNIT_END:
		{
			messageData.GetValue("ErrorCode");
			string value4 = messageData.GetValue("TestResult");
			TestResult testResu = (TestResult)Enum.Parse(typeof(TestResult), value4);
			if (base.GenericSetup.ShowStartStopMessages)
			{
				AppendToLog("Test tree ended at " + DateTime.Now.ToString());
			}
			DisplayStatus("Test tree ended at " + DateTime.Now.ToString());
			ProcessDone(testResu);
			break;
		}
		case TestMsgTypes.ON_TEST_START:
		{
			string value3 = messageData.GetValue("TestName");
			if (base.GenericSetup.ShowStartStopMessages)
			{
				AppendToLog("Run: " + value3);
			}
			TestItemStarted(value3);
			break;
		}
		case TestMsgTypes.ON_TEST_RESULT:
		{
			string value = messageData.GetValue("TestName");
			string value2 = messageData.GetValue("TestResult");
			TestResult testResult = (TestResult)Enum.Parse(typeof(TestResult), value2);
			string text = ((testResult == TestResult.Passed) ? "PASS" : "FAIL");
			if (base.GenericSetup.ShowStartStopMessages)
			{
				AppendToLog(text + ": " + value);
			}
			TestItemDone(value, testResult);
			break;
		}
		}
	}

	private void testTree_RunTreeDone(bool treePassed)
	{
		if (base.GenericSetup.ShowStartStopMessages)
		{
			AppendToLog("Test done");
		}
		if (!treePassed)
		{
			ProcessDone(TestResult.Failed);
		}
		else
		{
			ProcessDone(TestResult.Passed);
		}
	}
}
