using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Threading;
using System.Xml.Serialization;
using QC.GlobalVariableManager;
using QC.QSPR;
using QC.QsprShared.Config;
using QC.QsprShared.GlobalData;
using QC.QsprShared.Trace;
using QC.QsprTestObjects;
using QC.QsprTestObjects.Loops;
using QC.QsprTestObjects.Registry;
using QC.QsprTestObjects.Tests.Base;
using QC.QTMDotNetKernelInterface;
using QC.QTMInterface;

namespace QC.QSPRSchedulerWrapper;

[ProgId("QSPR.Scheduler")]
[ComVisible(true)]
[ComSourceInterfaces(typeof(ISchedulerEvents))]
[ClassInterface(ClassInterfaceType.None)]
public class QSPRScheduler : IScheduler
{
	[ComVisible(false)]
	public delegate void OnDebugMessageEventHandler(string strWin, string strText, int traceLevel, bool NoEndOfLine);

	[ComVisible(false)]
	public delegate void OnRealTimeParamMsgEventHandler(string messageType, string id, string name = "", string value = "", string units = "", string lowerLimit = "", string upperLimit = "", byte pluginTypes = 7, string pluginNames = "");

	[ComVisible(false)]
	public delegate void OnRealTimeMessageEventHandler(string messageType, GenericTestData data = null, byte pluginTypes = 7, string pluginNames = "");

	[ComVisible(false)]
	public delegate void OnRealTimeCustomMsgEventHandler(object messageData, byte pluginTypes = 7, string pluginNames = "");

	[ComVisible(false)]
	public delegate void OnTestMessageEventHandler(int messageType, QSPRTestMessage messageData);

	[ComVisible(false)]
	public delegate void OnTestMsgEventHandler(int messageType, ITestMessage messageData);

	[ComVisible(false)]
	public delegate void OnGlobalVariableChangedEventHandler(string gvName, string gvValue);

	private TimeSpan totalTime = TimeSpan.Zero;

	private Mutex messageMutex = new Mutex(initiallyOwned: false);

	private QsprPluginManager qsprPluginManager;

	private Stack<ArrayList> retryMsgStack = new Stack<ArrayList>();

	internal Scheduler _scheduler;

	private string lastCallInfo = "";

	private string lastError = "No Error";

	private bool errorsExist;

	public ScenarioHandler scenarioHandler
	{
		get
		{
			if (_scheduler.QTMData.scenarioHandler == null)
			{
				_scheduler.QTMData.scenarioHandler = new ScenarioHandler();
			}
			return (ScenarioHandler)_scheduler.QTMData.scenarioHandler;
		}
		set
		{
			_scheduler.QTMData.scenarioHandler = value;
		}
	}

	public QTMRegistry theRegistry
	{
		get
		{
			if (_scheduler.QTMData.theRegistry == null)
			{
				_scheduler.QTMData.theRegistry = new QTMRegistry();
			}
			return (QTMRegistry)_scheduler.QTMData.theRegistry;
		}
		set
		{
			_scheduler.QTMData.theRegistry = value;
		}
	}

	private GlobalStatus GlobalStatus
	{
		get
		{
			return _scheduler.GlobalStatus;
		}
		set
		{
			_scheduler.GlobalStatus = value;
		}
	}

	private ArrayList messageQueue
	{
		get
		{
			if (_scheduler.QTMData.messageQueue == null)
			{
				_scheduler.QTMData.messageQueue = new ArrayList();
			}
			return _scheduler.QTMData.messageQueue;
		}
		set
		{
			_scheduler.QTMData.messageQueue = value;
		}
	}

	public string LastError => lastError;

	public int ErrorsExist
	{
		get
		{
			if (errorsExist)
			{
				return 1;
			}
			return 0;
		}
	}

	public QsprPluginManager QSPRPluginMgr => qsprPluginManager;

	public event OnDebugMessageEventHandler OnDebugMessage;

	public event OnRealTimeParamMsgEventHandler OnRealTimeParamMessage;

	public event OnRealTimeMessageEventHandler OnRealTimeMessage;

	public event OnRealTimeCustomMsgEventHandler OnRealTimeCustomMessage;

	public event OnTestMessageEventHandler OnTestMessage;

	public event OnTestMsgEventHandler OnTestMsg;

	public event OnGlobalVariableChangedEventHandler OnGlobalVariableChanged;

	public QSPRScheduler()
		: this(null)
	{
	}

	public QSPRScheduler(string pluginDirectory)
	{
		_scheduler = new Scheduler();
		InitializeKernels();
		InitializeDelegates();
		if (pluginDirectory == null)
		{
			string pluginDirectory2 = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "..\\QSPRPlugins");
			qsprPluginManager = new QsprPluginManager(this, pluginDirectory2);
		}
		else
		{
			qsprPluginManager = new QsprPluginManager(this, pluginDirectory);
		}
		_scheduler.QTMData.UpdateGVForLinkTree = UpdateGlobalVbleForLinkedTree;
	}

	public QSPRTestTree NewXTT()
	{
		return new QSPRTestTree("", this);
	}

	public QSPRTestTree OpenXTT(string treename)
	{
		return new QSPRTestTree(treename, this);
	}

	public void LoadWorkspaceConfig(string wsConfigFileName)
	{
		TraceMessage.WriteAlways("QC.QSPRSchedulerWrapper.QSPRScheduler", "LoadWorkspaceConfig", TraceMessageType.Trace);
		FileStream fileStream = null;
		try
		{
			LoadFeatureConfig();
			XmlSerializer xmlSerializer = new XmlSerializer(typeof(WorkspaceConfig));
			if (File.Exists(wsConfigFileName))
			{
				fileStream = new FileStream(wsConfigFileName, FileMode.Open, FileAccess.Read, FileShare.Read);
				if (fileStream != null)
				{
					TraceMessage.WriteAlways("QC.QSPRSchedulerWrapper.QSPRScheduler.LoadWorkspaceConfig", "Loading config from " + wsConfigFileName, TraceMessageType.Trace);
					WorkspaceConfig wConfig = (WorkspaceConfig)xmlSerializer.Deserialize(fileStream);
					_scheduler.QTMData.WConfig = wConfig;
					fileStream.Close();
				}
			}
			else
			{
				TraceMessage.WriteAlways("QC.QSPRSchedulerWrapper.QSPRScheduler.LoadWorkspaceConfig", "No config file found reverting to default config ", TraceMessageType.Trace);
				_scheduler.QTMData.WConfig = new WorkspaceConfig();
			}
		}
		catch (Exception ex)
		{
			_scheduler.QTMData.WConfig = new WorkspaceConfig();
			TraceMessage.WriteAlways("QC.QSPRSchedulerWrapper.QSPRScheduler.LoadWorkspaceConfig", "LoadWConfig " + ex.ToString(), TraceMessageType.Exception);
		}
		finally
		{
			fileStream?.Close();
			ConfigureHiveKernel();
		}
	}

	public void SaveWorkspaceConfig(string wsConfigFileName)
	{
		TextWriter textWriter = new StreamWriter(wsConfigFileName);
		XmlSerializer xmlSerializer = new XmlSerializer(typeof(WorkspaceConfig));
		xmlSerializer.Serialize(textWriter, _scheduler.QTMData.WConfig);
		textWriter.Close();
	}

	public void GetGlobalVariable(string gvName, out string value)
	{
		value = "";
		_scheduler.Env.GlobalVariable.GetGlobalVariable(gvName, out value);
	}

	public void SetGlobalVariable(string gvName, string value)
	{
		_scheduler.Env.GlobalVariable.SetGlobalVariable(gvName, value);
	}

	public void Close()
	{
		_scheduler.KernelMgr.HandleHiveTestToolsClick("Exit");
		_scheduler.mutTest.Close();
		_scheduler.KernelMgr.ShutdownHiveKernel();
		_scheduler.KernelMgr.ShutdownScriptKernel();
		_scheduler.KernelMgr.ShutdownDotNetKernel();
		_scheduler.KernelMgr.ShutdownLabVIEWKernel();
	}

	public int Exit()
	{
		try
		{
			Close();
			return 1;
		}
		catch
		{
			return 0;
		}
	}

	public ArrayList UpdateGlobalVbleForLinkedTree(string ConfigFileName, out Dictionary<string, string> overwriteConfigs)
	{
		ArrayList arrayList = new ArrayList();
		overwriteConfigs = new Dictionary<string, string>();
		if (ConfigFileName != "")
		{
			try
			{
				arrayList = GetTesterConfigurationForLinkedTree(ConfigFileName);
				if (arrayList != null && arrayList.Count > 0)
				{
					foreach (TesterConfigurationInfo item in arrayList)
					{
						if (_scheduler.Env.GlobalVariable.Contains(item.Name))
						{
							if (!item.OverwriteWhenLinked && _scheduler.GlobalStatus.TestRunning)
							{
								_scheduler.Env.GlobalVariable.GetGlobalVariable(item.Name, out var gvValue);
								if (gvValue != null && !overwriteConfigs.ContainsKey(item.Name))
								{
									overwriteConfigs.Add(item.Name, gvValue);
								}
								_scheduler.Registry.SetGlobalVariable(item.Name, item.Value);
							}
						}
						else
						{
							_scheduler.Registry.SetGlobalVariable(item.Name, item.Value);
						}
					}
				}
			}
			catch (Exception ex)
			{
				TraceMessage.Write("QC.QTMApplication.WPFTestTreeWindowColl", "UpdateGlobalVbleForLinkedTree " + ex.Message, TraceMessageType.Exception);
			}
		}
		return arrayList;
	}

	public ArrayList GetTesterConfigurationForLinkedTree(string ConfigFileName)
	{
		_scheduler.Env.GlobalVariable.GetGlobalVariable("TreeFileName", out var gvValue);
		PathUtils.ConvertToAbsolute(gvValue, ConfigFileName);
		TraceMessage.Write(ToString(), "GetTesterConfigurationForLinkedTree", TraceMessageType.Trace);
		try
		{
			return new ArrayList();
		}
		catch (Exception ex)
		{
			TraceMessage.Write(ToString(), "GetTesterConfigurationForLinkedTree " + ex.Message, TraceMessageType.Exception);
		}
		return null;
	}

	private void InitializeKernels()
	{
		try
		{
			_scheduler.KernelMgr.InitializeHiveKernel(_scheduler.TestMsgBroadCaster);
			QTMData.Kernels.HiveKernel = true;
		}
		catch (Exception ex)
		{
			Console.WriteLine("Exception loading HiveKernel: " + Environment.NewLine + ex);
		}
		try
		{
			_scheduler.KernelMgr.InitializeScriptKernel(_scheduler.TestMsgBroadCaster);
			QTMData.Kernels.ScriptKernel = true;
		}
		catch (Exception ex2)
		{
			Console.WriteLine("Exception loading ScriptKernel: " + Environment.NewLine + ex2);
		}
		try
		{
			_scheduler.KernelMgr.InitializeLabVIEWKernel(_scheduler.TestMsgBroadCaster);
			QTMData.Kernels.LabViewKernel = true;
		}
		catch (Exception ex3)
		{
			Console.WriteLine("Exception loading LabVIEWKernel: " + Environment.NewLine + ex3);
		}
		try
		{
			_scheduler.KernelMgr.InitializeDotNetKernel(_scheduler.TestMsgBroadCaster);
			QTMData.Kernels.DotNetKernel = true;
		}
		catch (Exception ex4)
		{
			Console.WriteLine("Exception loading DotNetKernel: " + Environment.NewLine + ex4);
		}
	}

	private void ConfigureHiveKernel()
	{
		if (GlobalStatus.AutomationMode)
		{
			_scheduler.KernelMgr.IsInAutomation(isInAutomation: true);
		}
		if (_scheduler.QTMData.WConfig.EnableHiveTracing)
		{
			_scheduler.KernelMgr.SetTracingForHiveKernel(enableTracing: true);
		}
		if (_scheduler.QTMData.WConfig.EnableSUITEOutParam)
		{
			_scheduler.KernelMgr.EnableSUITEOutParams(enable: true);
		}
	}

	private void InitializeDelegates()
	{
		_scheduler.TestMsgBroadCaster.SetMessageDelegate(OnTestMessages);
		_scheduler.TestMsgBroadCaster.SetTextOutDelegate(OnTextOut);
		_scheduler.TestMsgBroadCaster.SetOnGenericMessageDelegate(OnGenericMsg);
		_scheduler.TestMsgBroadCaster.SetOnGenericParamMessageDelegate(OnGenericParamMessage);
		_scheduler.TestMsgBroadCaster.SetOnCustomMessageDelegate(OnCustomMsg);
		_scheduler.TestMsgBroadCaster.SetOnTpl2WindowDelegate(OnTPL2WindowMsg);
		_scheduler.TestMsgBroadCaster.SetOnHTMLWindowDelegate(OnHTMLWindowMsg);
		_scheduler.TestMsgBroadCaster.SetClearDebugMessageDelegate(OnClearDebugMsg);
		_scheduler.TestMsgBroadCaster.SetSaveDebugMessageDelegate(OnSaveDebugMsg);
		_scheduler.TestMsgBroadCaster.SetClearAllDebugDelegate(OnClearAllDebugMsg);
		_scheduler.TestMsgBroadCaster.SetSaveAllDebugDelegate(OnSaveAllDebugMsg);
		_scheduler.SetMessageDelegate(OnTestMessages);
		_scheduler.Env.GlobalVariable.OnGlobalVariableChange += GlobalVariable_OnGlobalVariableChange;
	}

	private void GlobalVariable_OnGlobalVariableChange(object sender, GlobalVariableEventArgs e)
	{
		if (this.OnGlobalVariableChanged != null)
		{
			this.OnGlobalVariableChanged(e.GVName, e.GVValue);
		}
	}

	private void OnGenericParamMessage(string messageType, string id, string name = "", string value = "", string units = "", string lowerLimit = "", string upperLimit = "", byte pluginTypes = 7, string pluginNames = "")
	{
		if (this.OnRealTimeParamMessage != null)
		{
			this.OnRealTimeParamMessage(messageType, id, name, value, units, lowerLimit, upperLimit, pluginTypes, pluginNames);
		}
	}

	private void OnGenericMsg(string messageType, GenericTestData data = null, byte pluginTypes = 7, string pluginNames = "")
	{
		if (this.OnRealTimeMessage != null)
		{
			this.OnRealTimeMessage(messageType, data, pluginTypes, pluginNames);
		}
	}

	private void OnCustomMsg(object messageData, byte pluginTypes = 7, string pluginNames = "")
	{
		if (this.OnRealTimeCustomMessage != null)
		{
			this.OnRealTimeCustomMessage(messageData, pluginTypes, pluginNames);
		}
	}

	private void OnHTMLWindowMsg(string windowName, HTMLCommand command, string TextStr)
	{
		QSPRPluginMgr.HandleHTMLMsg(windowName, command, TextStr);
	}

	private void OnTPL2WindowMsg(string windowName, Tpl2Command command, Tpl2Info commandInfo)
	{
		QSPRPluginMgr.HandleTPL2Msg(windowName, command, commandInfo);
	}

	private void OnClearAllDebugMsg()
	{
		QSPRPluginMgr.HandleClearAllDebugMsg();
	}

	private void OnSaveDebugMsg(string strWindowName, bool appendText)
	{
		QSPRPluginMgr.HandleSaveDebugMsg(strWindowName, appendText);
	}

	private void OnClearDebugMsg(string strWindowName)
	{
		QSPRPluginMgr.HandleClearDebugMsg(strWindowName);
	}

	private void OnSaveAllDebugMsg(bool appendText)
	{
		QSPRPluginMgr.HandleSaveAllDebugMsg(appendText);
	}

	private void LoadFeatureConfig()
	{
		QTMData.FeatureConfigInfo = new FeatureConfig();
		GlobalInformation.RunTimeConfig = QTMData.FeatureConfigInfo.ExportToStruct();
	}

	private void OnTextOut(string strWin, string strText, TraceLevel traceLevel, bool NoEndOfLine)
	{
		if (this.OnDebugMessage != null)
		{
			this.OnDebugMessage(strWin, strText, (int)traceLevel, NoEndOfLine);
		}
	}

	private void OnTestMessages(TestMsgType msgType, TestMessage message)
	{
		HandleMessages(msgType, message);
	}

	private MsgData GetMsgDataFromTestMsg(TestMessage testMsg)
	{
		MsgData result = default(MsgData);
		result.ParamResult = testMsg.Object;
		result.TestFullPath = testMsg.Message;
		result.Result = testMsg.Result;
		result.time = DateTime.Now;
		result.TestIndex = testMsg.TestIndex;
		result.NodeRID = testMsg.NodeRID;
		result.UnitIndex = testMsg.UnitIndex;
		result.SerialNumber = testMsg.SerialNumber;
		result.ErrorCode = testMsg.ErrorCode;
		result.IsLinkedRoot = testMsg.IsLinkedRoot;
		result.TestName = testMsg.RealName;
		result.TestCaseInfo.TestCaseID = testMsg.TestCaseID;
		result.TestCaseInfo.DisplayId = testMsg.DisplayID;
		result.TestCaseInfo.TestCaseRefID = testMsg.TestCaseRefID;
		result.TestCaseInfo.TestCaseName = testMsg.TestCaseName;
		result.BlockedCRNumber = testMsg.BlockedCRNumber;
		result.DoNotSendToPlugins = testMsg.DoNotSendToPlugins;
		result.TestPathInTree = testMsg.TestPathInTree;
		result.ResultDetails = testMsg.ResultDetails;
		result.TestCaseInfo.IsApprovedTestPlan = testMsg.IsApprovedTestPlan;
		result.TestCaseInfo.TestPlanVersion = testMsg.TestPlanVersion;
		result.RealName = testMsg.RealName;
		result.ContainerInfo = testMsg.ContainerInfo;
		result.TestStartTime = testMsg.TestStartTime;
		result.TestStopTime = testMsg.TestStopTime;
		result.LimitsEnforced = testMsg.LimitsEnforced;
		result.CurrentLoopIteration = testMsg.CurrentLoopIteration;
		result.MaxLoopIteration = testMsg.MaxLoopIteration;
		return result;
	}

	private bool TestMessageHasListeners()
	{
		if (this.OnTestMessage == null)
		{
			return this.OnTestMsg != null;
		}
		return true;
	}

	private void SendTestMessage(TestMsgTypes messageType, QSPRTestMessage message)
	{
		if (this.OnTestMessage != null)
		{
			this.OnTestMessage((int)messageType, message);
		}
		if (this.OnTestMsg != null)
		{
			this.OnTestMsg((int)messageType, message);
		}
	}

	private void HandleMessages(TestMsgType msgType, TestMessage message)
	{
		DateTime now = DateTime.Now;
		GetMsgDataFromTestMsg(message);
		scenarioHandler.ProcessMessage(msgType, message, _scheduler.RootFolder);
		theRegistry.OnTestMessage(msgType, message.Message, message.Result);
		_scheduler.Env.QTMInfo.OnMsgFromQTM(msgType, GetMsgDataFromTestMsg(message));
		switch (msgType)
		{
		case TestMsgType.OnAbort:
			if (GlobalStatus.GlobalTestResult != TestResult.IgnoreSession)
			{
				GlobalStatus.GlobalTestResult = TestResult.Exception;
			}
			break;
		case TestMsgType.OnUnitStart:
			now = DateTime.Now;
			if (TestMessageHasListeners())
			{
				QSPRTestMessage qSPRTestMessage5 = new QSPRTestMessage();
				qSPRTestMessage5.MessageItems.Add("SN", message.Message);
				qSPRTestMessage5.MessageItems.Add("NodeRID", message.NodeRID.ToString());
				qSPRTestMessage5.MessageItems.Add("TestCount", ((PhoneStart)message.Object).count.ToString());
				qSPRTestMessage5.MessageItems.Add("TestIndex", message.TestIndex);
				SendTestMessage(TestMsgTypes.ON_UNIT_START, qSPRTestMessage5);
			}
			break;
		case TestMsgType.OnUnitEnd:
			totalTime = DateTime.Now - now;
			if (message.Result != TestResult.Passed && message.Result != 0)
			{
				_ = message.Result;
				_ = 2;
			}
			if (TestMessageHasListeners())
			{
				QSPRTestMessage qSPRTestMessage2 = new QSPRTestMessage();
				qSPRTestMessage2.MessageItems.Add("SN", message.SerialNumber);
				qSPRTestMessage2.MessageItems.Add("ErrorCode", message.ErrorCode);
				qSPRTestMessage2.MessageItems.Add("TestResult", message.Result.ToString());
				qSPRTestMessage2.MessageItems.Add("TestIndex", message.TestIndex);
				qSPRTestMessage2.MessageItems.Add("NodeRID", message.NodeRID.ToString());
				SendTestMessage(TestMsgTypes.ON_UNIT_END, qSPRTestMessage2);
			}
			break;
		case TestMsgType.OnTestStart:
			if (TestMessageHasListeners())
			{
				QSPRTestMessage qSPRTestMessage4 = new QSPRTestMessage();
				qSPRTestMessage4.MessageItems.Add("SN", message.SerialNumber);
				qSPRTestMessage4.MessageItems.Add("TestName", message.ErrorCode);
				qSPRTestMessage4.MessageItems.Add("TestIndex", message.TestIndex);
				qSPRTestMessage4.MessageItems.Add("TestFullPath", message.TestPathInTree);
				qSPRTestMessage4.MessageItems.Add("StartTime", message.Object.ToString());
				qSPRTestMessage4.MessageItems.Add("Status", "Started");
				qSPRTestMessage4.MessageItems.Add("NodeRID", message.NodeRID.ToString());
				qSPRTestMessage4.MessageItems.Add("LoopDetails", GlobalStatus.LoopDetails);
				SendTestMessage(TestMsgTypes.ON_TEST_START, qSPRTestMessage4);
			}
			break;
		case TestMsgType.OnFolderStart:
			if (TestMessageHasListeners())
			{
				QSPRTestMessage qSPRTestMessage6 = new QSPRTestMessage();
				qSPRTestMessage6.MessageItems.Add("TestName", message.Message);
				qSPRTestMessage6.MessageItems.Add("Status", "Started");
				SendTestMessage(TestMsgTypes.ON_FOLDER_START, qSPRTestMessage6);
			}
			break;
		case TestMsgType.OnTestResult:
		{
			if (!TestMessageHasListeners())
			{
				break;
			}
			QSPRTestMessage qSPRTestMessage3 = new QSPRTestMessage();
			qSPRTestMessage3.MessageItems.Add("SN", message.SerialNumber);
			qSPRTestMessage3.MessageItems.Add("TestName", message.Message);
			qSPRTestMessage3.MessageItems.Add("TestIndex", message.TestIndex);
			qSPRTestMessage3.MessageItems.Add("TestFullPath", message.TestPathInTree);
			qSPRTestMessage3.MessageItems.Add("RealName", message.RealName);
			qSPRTestMessage3.MessageItems.Add("TestResult", message.Result.ToString());
			qSPRTestMessage3.MessageItems.Add("Status", message.Result.ToString());
			qSPRTestMessage3.MessageItems.Add("Duration", message.Duration.ToString());
			qSPRTestMessage3.MessageItems.Add("LoopDetails", GlobalStatus.LoopDetails);
			if (message.ContainerInfo.FileName != null)
			{
				qSPRTestMessage3.MessageItems.Add("TestContainerName", message.ContainerInfo.FileName);
			}
			if (message.ContainerInfo.Version != null)
			{
				qSPRTestMessage3.MessageItems.Add("TestContainerVersion", message.ContainerInfo.Version);
			}
			qSPRTestMessage3.MessageItems.Add("NodeRID", message.NodeRID.ToString());
			qSPRTestMessage3.MessageItems.Add("ErrorCode", message.ErrorCode);
			if (message.LimitsEnforced == true)
			{
				qSPRTestMessage3.MessageItems.Add("LimitsEnforced", message.LimitsEnforced.ToString());
			}
			ArrayList arrayList = (ArrayList)message.Object;
			foreach (ParamValue item in arrayList)
			{
				string key = "OutputParam_" + item.ParamName;
				if (item.Value.Count == 1)
				{
					qSPRTestMessage3.MessageItems.Add(key, item.Value[0].ToString());
					continue;
				}
				string text = "";
				foreach (object item2 in item.Value)
				{
					text = ((item2 == null) ? (text + "_,_") : (text + item2.ToString() + "_,_"));
				}
				if (text.EndsWith("_,_"))
				{
					text = text.Remove(text.Length - "_,_".Length);
				}
				qSPRTestMessage3.MessageItems.Add(key, text);
			}
			SendTestMessage(TestMsgTypes.ON_TEST_RESULT, qSPRTestMessage3);
			break;
		}
		case TestMsgType.OnFolderEnd:
			if (TestMessageHasListeners())
			{
				QSPRTestMessage qSPRTestMessage = new QSPRTestMessage();
				qSPRTestMessage.MessageItems.Add("TestName", message.Message);
				qSPRTestMessage.MessageItems.Add("Status", message.Result.ToString());
				SendTestMessage(TestMsgTypes.ON_FOLDER_END, qSPRTestMessage);
			}
			break;
		}
		GlobalStatus.ProcessTestResultsPlugIns = true;
		HandleTestMessages(msgType, message);
	}

	private ArrayList GetMessagesForPlugins(ArrayList messageQueue)
	{
		ArrayList arrayList = new ArrayList();
		foreach (MsgData item in messageQueue)
		{
			if (!item.DoNotSendToPlugins)
			{
				arrayList.Add(item);
			}
		}
		return arrayList;
	}

	private void HandleTestMessages(TestMsgType msgType, TestMessage testMsg)
	{
		try
		{
			messageMutex.WaitOne();
			TraceMessage.Write(ToString(), "HandleTestMessage " + msgType, TraceMessageType.Trace);
			bool flag = false;
			bool flag2 = false;
			MsgData msgDataFromTestMsg = GetMsgDataFromTestMsg(testMsg);
			msgDataFromTestMsg.msgType = msgType;
			switch (msgType)
			{
			case TestMsgType.OnStartOfDebugTesting:
				messageQueue.Clear();
				messageQueue.Add(msgDataFromTestMsg);
				break;
			case TestMsgType.OnTestMsgHold:
				flag2 = true;
				if (GlobalStatus.TestMsgHold)
				{
					retryMsgStack.Push((ArrayList)messageQueue.Clone());
				}
				else
				{
					flag = true;
				}
				GlobalStatus.TestMsgHold = true;
				break;
			case TestMsgType.OnTestMsgClear:
				messageQueue.Clear();
				break;
			case TestMsgType.OnTestMsgRetryDone:
				if (retryMsgStack.Count > 0)
				{
					messageQueue.InsertRange(0, retryMsgStack.Pop());
				}
				break;
			case TestMsgType.OnTestMsgSend:
				flag = true;
				flag2 = true;
				GlobalStatus.TestMsgHold = false;
				if (GlobalStatus.GlobalTestResult != 0)
				{
					for (int num = messageQueue.Count - 1; num >= 0; num--)
					{
						MsgData msgData = (MsgData)messageQueue[num];
						if (msgData.msgType == TestMsgType.OnTestResult && msgData.Result != TestResult.Passed)
						{
							GlobalStatus.GlobalTestResult = msgData.Result;
							break;
						}
					}
				}
				if (retryMsgStack.Count > 0)
				{
					messageQueue.InsertRange(0, retryMsgStack.Pop());
				}
				break;
			case TestMsgType.OnTestStart:
			case TestMsgType.OnTestResult:
			case TestMsgType.OnUnitStart:
			case TestMsgType.OnUnitEnd:
			case TestMsgType.OnDLLLoaded:
			case TestMsgType.OnEndOfDebugTesting:
			case TestMsgType.OnSessionStop:
			case TestMsgType.OnTargetConnected:
			case TestMsgType.OnTargetDisConnected:
			case TestMsgType.OnTreeDone:
				msgDataFromTestMsg.LoopDetails = GlobalStatus.LoopDetails;
				msgDataFromTestMsg.TesterConfiguration = _scheduler.GetTesterConfig();
				messageQueue.Add(msgDataFromTestMsg);
				flag2 = true;
				if (msgType == TestMsgType.OnTestStart || msgType == TestMsgType.OnTestResult)
				{
					if (!GlobalStatus.TestMsgHold)
					{
						flag = true;
					}
				}
				else
				{
					flag = true;
				}
				break;
			case TestMsgType.OnLinkedTreeStart:
			case TestMsgType.OnLinkedTreeEnd:
				msgDataFromTestMsg.TesterConfiguration = _scheduler.GetTesterConfig();
				if (!string.IsNullOrEmpty(_scheduler.LinkedLoopName) || !string.IsNullOrEmpty(_scheduler.LinkedLoopValue))
				{
					if (string.IsNullOrEmpty(GlobalStatus.LoopDetails))
					{
						msgDataFromTestMsg.LoopDetails = _scheduler.LinkedLoopName + "__" + _scheduler.LinkedLoopValue;
					}
					else
					{
						msgDataFromTestMsg.LoopDetails = GlobalStatus.LoopDetails + "_._" + _scheduler.LinkedLoopName + "__" + _scheduler.LinkedLoopValue;
					}
				}
				else
				{
					msgDataFromTestMsg.LoopDetails = GlobalStatus.LoopDetails;
				}
				messageQueue.Add(msgDataFromTestMsg);
				flag2 = true;
				if (!GlobalStatus.TestMsgHold)
				{
					flag = true;
				}
				break;
			case TestMsgType.OnTestSkipped:
			case TestMsgType.OnBreak:
			{
				if (QTMGlobalVariable.GetGlobalVariable("TestCaseExecutionMode", out var gvValue) && string.Compare(gvValue, "SkipAllManual", ignoreCase: true) == 0)
				{
					structLoopValues structLoopValues2 = (structLoopValues)msgDataFromTestMsg.ParamResult;
					QTMGlobalVariable.SetGlobalVariable("LOOPDETAILS_" + structLoopValues2.sLoopName, structLoopValues2.sLoopValue);
					msgDataFromTestMsg.LoopDetails = GlobalStatus.LoopDetails;
				}
				messageQueue.Add(msgDataFromTestMsg);
				flag2 = true;
				break;
			}
			case TestMsgType.OnLoopStart:
			{
				structLoopValues structLoopValues = (structLoopValues)msgDataFromTestMsg.ParamResult;
				_scheduler.Env.GlobalVariable.SetGlobalVariable("LOOPDETAILS_" + structLoopValues.sLoopName, structLoopValues.sLoopValue);
				_scheduler.Env.GlobalVariable.SetGlobalVariable("LOOPDETAILS", GlobalStatus.LoopDetails);
				msgDataFromTestMsg.LoopDetails = GlobalStatus.LoopDetails;
				messageQueue.Add(msgDataFromTestMsg);
				break;
			}
			case TestMsgType.OnLoopEnd:
				_scheduler.Env.GlobalVariable.SetGlobalVariable("LOOPDETAILS", GlobalStatus.LoopDetails);
				msgDataFromTestMsg.LoopDetails = GlobalStatus.LoopDetails;
				messageQueue.Add(msgDataFromTestMsg);
				break;
			case TestMsgType.OnGoNoGoDidNotStart:
				flag = true;
				flag2 = true;
				messageQueue.Add(msgDataFromTestMsg);
				break;
			case TestMsgType.OnTestNodeSelected:
				flag = true;
				flag2 = true;
				messageQueue.Add(msgDataFromTestMsg);
				break;
			case TestMsgType.OnLoggingDone:
				flag = true;
				flag2 = true;
				messageQueue.Add(msgDataFromTestMsg);
				break;
			case TestMsgType.OnTreePause:
			case TestMsgType.OnTreeResume:
				flag = true;
				flag2 = true;
				messageQueue.Add(msgDataFromTestMsg);
				break;
			case TestMsgType.OnEnqueueTest:
			case TestMsgType.OnDequeueTest:
				flag = false;
				flag2 = true;
				break;
			default:
				messageQueue.Add(msgDataFromTestMsg);
				break;
			case TestMsgType.OnDebugMsg:
				break;
			}
			try
			{
				if (flag && !msgDataFromTestMsg.DoNotSendToPlugins)
				{
					GlobalStatus.ProcessTestResultsPlugIns = true;
					qsprPluginManager.OnMsg(GetMessagesForPlugins(messageQueue), 7, msgDataFromTestMsg);
					messageQueue.Clear();
					TraceMessage.Write(ToString(), "HandleTestMessage Processing- Done ", TraceMessageType.Trace);
				}
				else if (flag2)
				{
					qsprPluginManager.OnMsg((ArrayList)messageQueue.Clone(), 1, msgDataFromTestMsg);
					TraceMessage.Write(ToString(), "HandleTestMessage Processing for test trees only - Done ", TraceMessageType.Trace);
				}
			}
			catch (Exception ex)
			{
				TraceMessage.Write(ToString(), "HandleTestMessage Processing" + ex.Message, TraceMessageType.Exception);
			}
		}
		catch (Exception ex2)
		{
			TraceMessage.Write(ToString(), "HandleTestMessage Outermost " + msgType.ToString() + " " + ex2, TraceMessageType.Exception);
		}
		finally
		{
			messageMutex.ReleaseMutex();
		}
	}
}
