using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Xml.Serialization;
using QC.QsprShared.GlobalData;
using QC.QsprTestObjects;
using QC.QsprTestObjects.Loops;
using QC.QsprTestObjects.Parameters;
using QC.QsprTestObjects.Registry;
using QC.QsprTestObjects.Tests.Base;
using QC.QTMInterface;
using QsprMiscShared.Utilities;

namespace QC.QSPRSchedulerWrapper;

[ComSourceInterfaces(typeof(ITestTreeEvents))]
[ClassInterface(ClassInterfaceType.None)]
[ProgId("QSPR.TestTree")]
[ComVisible(true)]
public class QSPRTestTree : ITestTree
{
	public delegate void RunTreeDoneEventHandler(bool treePassed);

	private const string THISPC = "This PC";

	private const string TREE_FILE_EXTENSION = ".xtt";

	private const string COMPRESSED_TREE_FILE_EXTENSION = ".cxtt";

	internal Position FolderInsertPosition = Position.Last;

	private string lastCallInfo = "";

	private string lastError = "No Error";

	private bool errorsExist;

	private string TEMP_DECOMPRESS_TREE_FILE_TEMPLATE_NAME = Application.UserAppDataPath + "\\tmp_DecompressTree_";

	private TestTreeInfo treeInfo;

	private SerializeComponents currentTree;

	internal Scheduler scheduler;

	private string treeFileName;

	private CurrentTestInfo currentTestInfo;

	internal RootTest root
	{
		get
		{
			return scheduler.RootFolder;
		}
		set
		{
			scheduler.RootFolder = value;
		}
	}

	internal GlobalStatus globalStatus => scheduler.GlobalStatus;

	internal QTMData qtmData
	{
		get
		{
			return scheduler.QTMData;
		}
		set
		{
			scheduler.QTMData = value;
		}
	}

	internal TestTreeInfo TreeInfo
	{
		get
		{
			return treeInfo;
		}
		set
		{
			treeInfo = value;
		}
	}

	public string LastError => lastError;

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

	public event RunTreeDoneEventHandler RunTreeDone;

	public QSPRTestTree(string testTreeName, QSPRScheduler qsprScheduler)
	{
		FileStream fileStream = null;
		QTMRegistry qTMRegistry = null;
		try
		{
			if (!string.IsNullOrWhiteSpace(testTreeName))
			{
				XmlSerializer xmlSerializer = new XmlSerializer(typeof(SerializeComponents));
				string path = testTreeName;
				if (testTreeName.ToLower().EndsWith(".cxtt"))
				{
					string decompressedFileName = GetDecompressedFileName(testTreeName);
					FileCompressionUtility.DecompressFile(testTreeName, decompressedFileName);
					path = decompressedFileName;
				}
				fileStream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read);
				if (fileStream != null)
				{
					currentTree = (SerializeComponents)xmlSerializer.Deserialize(fileStream);
					fileStream.Close();
					scheduler = qsprScheduler._scheduler;
					root = currentTree.theRootTest;
					root.Scheduler = scheduler;
					root.Scheduler.GlobalStatus.PauseOnTestFailure = root.RootProperties.PauseOnTestFailure;
					root.Scheduler.GlobalStatus.StopOnFirstTestFailure = root.RootProperties.StopOnFirstTestFailure;
					root.Scheduler.Env.GlobalVariable.SetGlobalVariable("TesterConfigFile", root.RootProperties.ConfigFileName);
					root.Scheduler.Env.GlobalVariable.SetGlobalVariable("TreeFileName", testTreeName);
					root.Scheduler.Env.GlobalVariable.SetGlobalVariable("TreeStringID", root.RootProperties.TreeStringID);
					treeInfo = currentTree.theTestTreeInfo;
					InitializeParent(root);
					treeFileName = testTreeName;
					qTMRegistry = currentTree.theRegistry;
					qTMRegistry.scheduler = scheduler;
					qTMRegistry.CreateHastable();
					if (qsprScheduler.QSPRPluginMgr != null)
					{
						try
						{
							qsprScheduler.QSPRPluginMgr.LoadPluginSettingsFromTree(currentTree.thePlugInConfig);
						}
						catch (Exception)
						{
						}
					}
					foreach (GlobalVariable item in currentTree.theTestTreeInfo.QGlobalVariables.QGlobalVariable)
					{
						string gvValue = null;
						if (!scheduler.Env.GlobalVariable.GetGlobalVariable(item.Name, out gvValue) || gvValue == null)
						{
							scheduler.Env.GlobalVariable.SetGlobalVariable(item.Name, "");
						}
					}
					if (testTreeName.ToLower().EndsWith(".cxtt"))
					{
						string decompressedFileName2 = GetDecompressedFileName(testTreeName);
						File.Delete(decompressedFileName2);
					}
				}
			}
			else
			{
				scheduler = qsprScheduler._scheduler;
				root = new RootTest("ROOT");
				root.Properties.CheckStateTest = CheckState.Checked;
				root.Properties.Expanded = true;
				root.Scheduler = qsprScheduler._scheduler;
				root.Scheduler.GlobalStatus.PauseOnTestFailure = root.RootProperties.PauseOnTestFailure;
				root.Scheduler.GlobalStatus.StopOnFirstTestFailure = root.RootProperties.StopOnFirstTestFailure;
				root.Scheduler.Env.GlobalVariable.SetGlobalVariable("TesterConfigFile", root.RootProperties.ConfigFileName);
				root.Scheduler.Env.GlobalVariable.SetGlobalVariable("TreeFileName", "");
				root.Scheduler.Env.GlobalVariable.SetGlobalVariable("TreeStringID", root.RootProperties.TreeStringID);
				FolderTest baseTest = new FolderTest("StartUp")
				{
					Properties = 
					{
						CheckStateTest = CheckState.Checked,
						Expanded = true
					}
				};
				root.Add(baseTest);
				treeInfo = new TestTreeInfo();
				InitializeParent(root);
				treeFileName = "";
				qTMRegistry = new QTMRegistry();
				qTMRegistry.scheduler = qsprScheduler._scheduler;
				qTMRegistry.CreateHastable();
			}
			globalStatus.RootTest = root;
			GlobalStatus obj = globalStatus;
			string treeName = (root.RootProperties.TreeFileName = treeFileName);
			obj.TreeName = treeName;
			qtmData.theRegistry = qTMRegistry;
			qtmData.scenarioHandler = new ScenarioHandler();
		}
		catch (Exception ex2)
		{
			fileStream?.Close();
			throw ex2;
		}
	}

	private string GetDecompressedFileName(string compressedFileName)
	{
		string text = Path.GetFileNameWithoutExtension(compressedFileName) + ".xtt";
		return TEMP_DECOMPRESS_TREE_FILE_TEMPLATE_NAME + text;
	}

	public void RunTree()
	{
		RunTree(interactiveMode: false);
	}

	public void RerunFailed()
	{
		RunTree(interactiveMode: false, rerun: true);
	}

	public bool CanRerun()
	{
		if (scheduler.GlobalStatus.GlobalTestResult == TestResult.Failed)
		{
			return true;
		}
		return false;
	}

	public void RunTest(string testName)
	{
		if (root == null)
		{
			return;
		}
		BaseTest baseTest = root.FindTestFromTestName(testName, isPartialName: false);
		if (baseTest != null)
		{
			FolderTest multiSelectTests = new FolderTest("MultipleSelect");
			multiSelectTests.AddDummyTest(baseTest);
			Task.Factory.StartNew(delegate
			{
				scheduler.ScheduleTests(multiSelectTests, Scheduler.TestingType.Debug);
			});
		}
	}

	public void RunTreeInteractive()
	{
		scheduler.GlobalStatus.InteractiveStatus = GlobalStatus.ExecutionStatus.Executing;
		RunTree(interactiveMode: true);
	}

	public int GetExecutionStatus()
	{
		return (int)scheduler.GlobalStatus.InteractiveStatus;
	}

	public TestInfo GetNextTestInfo()
	{
		TestInfo result = null;
		if (scheduler.GlobalStatus.InteractiveStatus == GlobalStatus.ExecutionStatus.AwaitingFeedback)
		{
			CurrentTestInfo nextTestInfo = scheduler.GlobalStatus.NextTestInfo;
			while (nextTestInfo == null || (currentTestInfo != null && currentTestInfo.ID == nextTestInfo.ID))
			{
				if (!scheduler.GlobalStatus.IsInteractiveMode && (scheduler.GlobalStatus.InteractiveStatus == GlobalStatus.ExecutionStatus.Passed || scheduler.GlobalStatus.InteractiveStatus == GlobalStatus.ExecutionStatus.Failed))
				{
					return null;
				}
				Thread.Sleep(30);
				nextTestInfo = scheduler.GlobalStatus.NextTestInfo;
			}
			result = new TestInfo(nextTestInfo.TestName, nextTestInfo.RealName, nextTestInfo.DLLName, nextTestInfo.TestIndex, nextTestInfo.Parameters as ParameterCollection);
			currentTestInfo = nextTestInfo;
		}
		return result;
	}

	public int RunNextTest()
	{
		scheduler.GlobalStatus.ExternalRunTestStatus = GlobalStatus.TestStatus.NotSet;
		scheduler.GlobalStatus.InteractiveStatus = GlobalStatus.ExecutionStatus.Executing;
		scheduler.GlobalStatus.Pause = false;
		WaitForInteractiveTestCompleted();
		return (int)scheduler.GlobalStatus.InternalRunTestStatus;
	}

	public void SetNextTestResult(int status)
	{
		if (scheduler.GlobalStatus.InteractiveStatus != GlobalStatus.ExecutionStatus.Passed && scheduler.GlobalStatus.InteractiveStatus != GlobalStatus.ExecutionStatus.Failed)
		{
			scheduler.GlobalStatus.InteractiveStatus = GlobalStatus.ExecutionStatus.Executing;
			scheduler.GlobalStatus.ExternalRunTestStatus = (GlobalStatus.TestStatus)status;
			scheduler.GlobalStatus.Pause = false;
			WaitForInteractiveTestCompleted();
		}
	}

	private void WaitForInteractiveTestCompleted()
	{
		while (scheduler.GlobalStatus.InteractiveStatus != GlobalStatus.ExecutionStatus.AwaitingFeedback && scheduler.GlobalStatus.InteractiveStatus != GlobalStatus.ExecutionStatus.Failed && scheduler.GlobalStatus.InteractiveStatus != GlobalStatus.ExecutionStatus.Passed)
		{
			Thread.Sleep(30);
		}
	}

	public void StopTest()
	{
		globalStatus.Stop = true;
		globalStatus.GlobalTestResult = TestResult.Failed;
		root.FolderProperties.Failed = true;
	}

	public void AbortTest()
	{
		globalStatus.Abort = true;
		globalStatus.GlobalTestResult = TestResult.Failed;
		root.FolderProperties.Failed = true;
	}

	public int PauseTree()
	{
		try
		{
			if (!globalStatus.Pause)
			{
				globalStatus.Pause = true;
			}
			return 1;
		}
		catch
		{
			return 0;
		}
	}

	public int ResumeTree()
	{
		try
		{
			if (globalStatus.Pause)
			{
				globalStatus.Pause = false;
			}
			return 1;
		}
		catch
		{
			return 0;
		}
	}

	public void SetLoopValuesByRow(string folderName, int rowID, string[] values, int valueCount)
	{
		List<FolderTest> allFolderTests = root.GetAllFolderTests(folderName);
		foreach (FolderTest item in allFolderTests)
		{
			ArrayList loopConditions = item.Properties.Scenarios.LoopConditions;
			while (item.Properties.Scenarios.ConditionCheck.Count < rowID)
			{
				item.Properties.Scenarios.ConditionCheck.Add(true);
			}
			while (item.Properties.Scenarios.Descriptions.Count < rowID)
			{
				item.Properties.Scenarios.Descriptions.Add("");
			}
			while (item.Properties.Scenarios.DontRunCondition.Count < rowID)
			{
				item.Properties.Scenarios.DontRunCondition.Add("");
			}
			if (loopConditions.Count > 0)
			{
				for (int i = 0; i < loopConditions.Count; i++)
				{
					LoopCondition loopCondition = (LoopCondition)loopConditions[i];
					while (loopCondition.LoopValues.Count < rowID)
					{
						loopCondition.LoopValues.Add("");
					}
					if (valueCount > i)
					{
						loopCondition.LoopValues[rowID - 1] = values[i];
					}
					loopCondition.OriginalValue = loopCondition.LoopValuesAsString;
				}
			}
			item.Properties.Scenarios.ConditionCheck[rowID - 1] = true;
		}
	}

	public void DeleteLoopRow(string folderName, int rowID)
	{
		List<FolderTest> allFolderTests = root.GetAllFolderTests(folderName);
		foreach (FolderTest item in allFolderTests)
		{
			ArrayList loopConditions = item.Properties.Scenarios.LoopConditions;
			item.Properties.Scenarios.ConditionCheck.RemoveAt(rowID - 1);
			item.Properties.Scenarios.Descriptions.RemoveAt(rowID - 1);
			item.Properties.Scenarios.DontRunCondition.RemoveAt(rowID - 1);
			foreach (LoopCondition item2 in loopConditions)
			{
				if (item2.LoopValues.Count >= rowID)
				{
					item2.LoopValues.RemoveAt(rowID - 1);
				}
				item2.OriginalValue = item2.LoopValuesAsString;
			}
		}
	}

	public void DeleteLoopName(string folderName, string loopname)
	{
		List<FolderTest> allFolderTests = root.GetAllFolderTests(folderName);
		foreach (FolderTest item in allFolderTests)
		{
			LoopCondition loopConditionByName = GetLoopConditionByName(item, loopname);
			if (loopConditionByName != null)
			{
				item.Properties.Scenarios.LoopConditions.Remove(loopConditionByName);
			}
			if (item.Properties.Scenarios.LoopConditions.Count == 0)
			{
				item.Properties.Scenarios = null;
			}
		}
	}

	public QSPRTestNode GetTestNode(string testName)
	{
		QSPRTestNode qSPRTestNode = null;
		if (testName == "")
		{
			qSPRTestNode = new QSPRTestNode();
			qSPRTestNode.TestIndex = root.Index;
			qSPRTestNode.TestTree = this;
		}
		else
		{
			BaseTest baseTest = root.FindTestFromTestName(testName, isPartialName: false);
			if (baseTest != null)
			{
				qSPRTestNode = new QSPRTestNode();
				qSPRTestNode.TestIndex = baseTest.Index;
				qSPRTestNode.TestTree = this;
			}
		}
		return qSPRTestNode;
	}

	public int AddDotNetDll(string dllPath)
	{
		if (string.IsNullOrEmpty(dllPath))
		{
			lastCallInfo = "AddDotNetDll called with invalid dllPath";
			lastError = "AddDotNetDll failed, dllPath is not valid";
			errorsExist = true;
			return 0;
		}
		lastCallInfo = "AddDotNetDll(" + dllPath + ")";
		if (AddTestContainer(dllPath, QC.QsprTestObjects.Tests.Base.QTMTestTypes.DotNetTest))
		{
			return 1;
		}
		lastError = "AddDotNetDll failed";
		errorsExist = true;
		return 0;
	}

	public int DeleteTest(string TestName)
	{
		lastCallInfo = "DeleteTest(" + TestName + ")";
		if (!DeleteTestNode(TestName))
		{
			lastError = "Failed to delete the test: " + TestName;
			errorsExist = true;
			return 0;
		}
		return 1;
	}

	public int Save()
	{
		lastCallInfo = "Save()";
		if (SaveTree() == 1)
		{
			return 1;
		}
		lastError = "Save file failed";
		errorsExist = true;
		return 0;
	}

	public int SaveAs(string treeFilePath)
	{
		if (string.IsNullOrEmpty(treeFilePath))
		{
			lastCallInfo = "SaveAs called with invalid treeFilePath";
			lastError = "SaveAs failed, the treeFilePath is not valid";
			errorsExist = true;
			return 0;
		}
		lastCallInfo = "SaveAs(" + treeFilePath + ")";
		if (SaveTree(treeFilePath) == 1)
		{
			return 1;
		}
		lastError = "SaveAs failed";
		errorsExist = true;
		return 0;
	}

	public int SaveAsQSPRFormat(string treeFilePath)
	{
		if (string.IsNullOrEmpty(treeFilePath))
		{
			lastCallInfo = "SaveAsQSPRFormat called with invalid treefilePath";
			lastError = "SaveAsQSPRFormat called with invalid treefilePath";
			errorsExist = true;
			return 0;
		}
		lastCallInfo = "SaveAsQSPRFormat(" + treeFilePath + ")";
		if (SaveTree(treeFilePath) == 0)
		{
			lastError = "Failed to save file in QSPR format";
			errorsExist = true;
			return 0;
		}
		return 1;
	}

	public void SelectLoopRowWithValue(string folderName, string loopname, string loopValue, bool set = true)
	{
		List<FolderTest> allFolderTests = root.GetAllFolderTests(folderName);
		foreach (FolderTest item in allFolderTests)
		{
			int loopValueIndex = GetLoopValueIndex(item, loopname, loopValue);
			if (loopValueIndex >= 0)
			{
				item.Properties.Scenarios.ConditionCheck[loopValueIndex] = set;
			}
		}
	}

	public void SelectLoopRows(string folderName, bool set, int startRowId, int endRowId = -1)
	{
		List<FolderTest> allFolderTests = root.GetAllFolderTests(folderName);
		foreach (FolderTest item in allFolderTests)
		{
			int num = endRowId;
			if (num == -1)
			{
				num = item.FolderProperties.Scenarios.ConditionCheck.Count;
			}
			for (int i = startRowId; i <= num; i++)
			{
				item.Properties.Scenarios.ConditionCheck[i - 1] = set;
			}
		}
	}

	public void SetParameterValue(string paramname, string paramvalue, string testname = "", bool isPartialName = false)
	{
		List<BaseTest> list = root.FindAllTestWithParameter(paramname);
		List<BaseTest> list2 = new List<BaseTest>();
		if (!string.IsNullOrWhiteSpace(testname))
		{
			foreach (BaseTest item in list)
			{
				if (isPartialName)
				{
					if (TestNameContainsPath(testname))
					{
						if (!testname.EndsWith("|"))
						{
							string value = testname.Substring(0, testname.LastIndexOf('|'));
							string value2 = testname.Substring(testname.LastIndexOf('|') + 1);
							if (!item.Parent.UniqueTestPathWithoutIndex.EndsWith(value) || !item.Properties.TestName.Contains(value2))
							{
								list2.Add(item);
							}
						}
					}
					else if (!item.Properties.TestName.Contains(testname))
					{
						list2.Add(item);
					}
				}
				else if (TestNameContainsPath(testname))
				{
					if (!item.UniqueTestPathWithoutIndex.EndsWith(testname))
					{
						list2.Add(item);
					}
				}
				else if (item.Properties.TestName != testname)
				{
					list2.Add(item);
				}
			}
		}
		foreach (BaseTest item2 in list2)
		{
			list.Remove(item2);
		}
		foreach (BaseTest item3 in list)
		{
			item3.Properties.Parameters.SetParamValue(paramname, paramvalue, 0, "-1");
		}
	}

	public void GetParameterValue(string testName, string paramName, out string paramValue)
	{
		paramValue = null;
		BaseTest baseTest = root.FindTestFromTestName(testName, isPartialName: false);
		if (baseTest != null)
		{
			paramValue = baseTest.Properties.Parameters.GetParamValue(paramName);
		}
	}

	public void SelectTestToRun(string testName, bool selectedToRun = true)
	{
		BaseTest baseTest = root.FindTestFromTestName(testName, isPartialName: false);
		if (baseTest == null)
		{
			throw new Exception("Test not found " + testName);
		}
		baseTest.Properties.CheckStateTest = (selectedToRun ? CheckState.Checked : CheckState.Unchecked);
	}

	public void SelectTestFromFolderToRun(string folderName, string testName, bool selectedToRun = true)
	{
		BaseTest baseTest = root.FindTestFromTestName(folderName, isPartialName: false);
		if (baseTest == null || !(baseTest is FolderTest))
		{
			throw new Exception("Folder not found " + folderName);
		}
		SelectTestFromFolderToRun((FolderTest)baseTest, testName, selectedToRun);
	}

	public void GetAllFolderTests(string folderName, out string[] tests, out int testCount)
	{
		List<string> list = new List<string>();
		BaseTest baseTest = root.FindTestFromTestName(folderName, isPartialName: false);
		if (baseTest is FolderTest)
		{
			List<FolderTest> allFolderTests = ((FolderTest)baseTest).GetAllFolderTests();
			foreach (FolderTest item in allFolderTests)
			{
				list.Add(item.Properties.TestName);
			}
		}
		tests = list.ToArray();
		testCount = list.Count;
	}

	public void GetAllChildTests(string folderName, out string[] tests, out int testCount)
	{
		List<string> list = new List<string>();
		new ArrayList();
		new ArrayList();
		BaseTest baseTest = root.FindTestFromTestName(folderName, isPartialName: false);
		if (baseTest is FolderTest)
		{
			FolderTest folderTest = baseTest as FolderTest;
			foreach (BaseTest test in folderTest.TestList)
			{
				list.Add(test.Properties.TestName);
			}
		}
		else
		{
			list.Add(baseTest.Properties.TestName);
		}
		tests = list.ToArray();
		testCount = list.Count;
	}

	public int GetLoopRowCount(string folderName)
	{
		FolderTest folder = GetFolder(folderName);
		if (folder.FolderProperties.Scenarios.Count > 0 && folder.FolderProperties.Scenarios.LoopConditions.Count > 0)
		{
			LoopCondition loopCondition = (LoopCondition)folder.FolderProperties.Scenarios.LoopConditions[0];
			return loopCondition.LoopValues.Count;
		}
		return 0;
	}

	public int SaveTree(string treename = "")
	{
		if (treename == "")
		{
			if (string.IsNullOrWhiteSpace(treeFileName))
			{
				lastError = "Empty filename specified for tree that has no name yet.";
				errorsExist = true;
				return 0;
			}
			treename = treeFileName;
		}
		else
		{
			treeFileName = treename;
		}
		string text = treename;
		bool flag = false;
		if (treename.ToLower().EndsWith(".cxtt"))
		{
			text = GetDecompressedFileName(text);
			flag = true;
		}
		StreamWriter streamWriter = new StreamWriter(text);
		try
		{
			XmlSerializer xmlSerializer = new XmlSerializer(typeof(SerializeComponents));
			currentTree = new SerializeComponents();
			currentTree.theRegistry = scheduler.Registry;
			scheduler.GlobalStatus.SavingTree = true;
			root.GetSetNumberOfTests();
			currentTree.theRootTest = root;
			TreeInfo = new TestTreeInfo();
			TreeInfo.GlobalExcludeList = new ArrayList();
			TreeInfo.GlobalIncludeList = new ArrayList();
			TreeInfo.QGlobalVariables = new GlobalVariables();
			TreeInfo.TestTreeVersion = 13.0;
			currentTree.theTestTreeInfo = TreeInfo;
			xmlSerializer.Serialize(streamWriter, currentTree);
			if (flag)
			{
				if (streamWriter != null)
				{
					streamWriter.Close();
					streamWriter = null;
				}
				FileCompressionUtility.CompressFile(text, treename);
			}
			scheduler.GlobalStatus.SavingTree = false;
		}
		catch (Exception)
		{
			return 0;
		}
		finally
		{
			if (streamWriter != null)
			{
				streamWriter.Close();
				streamWriter = null;
			}
		}
		return 1;
	}

	public int SetFolderPosition(int insertPosition)
	{
		lastCallInfo = "SetFolderPosition(" + insertPosition + ")";
		bool flag = true;
		switch (insertPosition)
		{
		case 0:
			FolderInsertPosition = Position.First;
			break;
		case 1:
			FolderInsertPosition = Position.Last;
			break;
		default:
			flag = false;
			break;
		}
		if (!flag)
		{
			lastError = "Failed to set folder position. Setting default position to First";
			errorsExist = true;
			return 0;
		}
		return 1;
	}

	private bool TestNameContainsPath(string testName)
	{
		if (testName.Contains("|"))
		{
			return true;
		}
		return false;
	}

	private void RunTree(bool interactiveMode, bool rerun = false)
	{
		if (root == null)
		{
			return;
		}
		string gvValue = "";
		scheduler.Env.GlobalVariable.GetGlobalVariable("SN", out gvValue);
		if (string.IsNullOrWhiteSpace(gvValue))
		{
			scheduler.Env.GlobalVariable.SetGlobalVariable("SN", "Auto");
			gvValue = "Auto";
		}
		scheduler.QTMData.WConfig.LastUsedSerialNumber = gvValue;
		Task.Factory.StartNew(delegate
		{
			scheduler.GlobalStatus.IsInteractiveMode = interactiveMode;
			bool treePassed = scheduler.ScheduleTests(root, Scheduler.TestingType.GoNoGo, rerun);
			if (this.RunTreeDone != null)
			{
				this.RunTreeDone(treePassed);
			}
			scheduler.GlobalStatus.IsInteractiveMode = false;
		});
	}

	private void InitializeParent(FolderTest folderTest)
	{
		foreach (BaseTest test in folderTest.TestList)
		{
			test.Parent = folderTest;
			if (test is FolderTest)
			{
				InitializeParent((FolderTest)test);
			}
		}
	}

	private LoopCondition GetLoopConditionByName(FolderTest folder, string loopName)
	{
		ArrayList loopConditions = folder.Properties.Scenarios.LoopConditions;
		foreach (LoopCondition item in loopConditions)
		{
			if (item.LoopName == loopName)
			{
				return item;
			}
		}
		return null;
	}

	private int GetLoopValueIndex(FolderTest folder, string loopName, string loopValue)
	{
		ArrayList loopConditions = folder.Properties.Scenarios.LoopConditions;
		foreach (LoopCondition item in loopConditions)
		{
			if (item.LoopName == loopName)
			{
				return item.LoopValues.IndexOf(loopValue);
			}
		}
		return -1;
	}

	private FolderTest GetFolder(string folderName)
	{
		BaseTest baseTest = root.FindTestFromTestName(folderName, isPartialName: false);
		if (baseTest == null || !(baseTest is FolderTest))
		{
			throw new Exception("Folder not found " + folderName);
		}
		return (FolderTest)baseTest;
	}

	private void SelectTestFromFolderToRun(FolderTest folderTest, string testName, bool selectedToRun = true)
	{
		foreach (BaseTest test in folderTest.TestList)
		{
			if (test.Properties.TestName == testName)
			{
				test.Properties.CheckStateTest = (selectedToRun ? CheckState.Checked : CheckState.Unchecked);
			}
			if (test is FolderTest)
			{
				SelectTestFromFolderToRun((FolderTest)test, testName, selectedToRun);
			}
		}
	}

	private bool DeleteTestNode(string testName)
	{
		try
		{
			if (!string.IsNullOrEmpty(testName))
			{
				bool result = false;
				for (BaseTest baseTest = root.FindTestFromTestName(testName, isPartialName: false); baseTest != null; baseTest = root.FindTestFromTestName(testName, isPartialName: false))
				{
					result = true;
					DeleteNode(baseTest);
				}
				return result;
			}
		}
		catch (Exception ex)
		{
			lastError = "DeleteTest failed, " + ex.ToString();
			errorsExist = true;
		}
		return false;
	}

	private bool DeleteNode(BaseTest nodeToDelete)
	{
		try
		{
			if (nodeToDelete == root)
			{
				lastError = "Root node can not be deleted";
				errorsExist = true;
				return false;
			}
			if (nodeToDelete.Properties.LinkNode && nodeToDelete.Properties.IsLinkActive == true)
			{
				lastError = "Linked nodes cannot be modified.";
				errorsExist = true;
				return false;
			}
			FolderTest parent = nodeToDelete.Parent;
			parent.TestList.Remove(nodeToDelete);
			scheduler.GlobalStatus.RegistrationStatus.TreeNodeDeleted = true;
			if (parent.TestList.Count == 0)
			{
				parent.Properties.CheckStateTest = CheckState.Unchecked;
			}
			return true;
		}
		catch (Exception ex)
		{
			lastError = "Delete Node failed with exception: " + ex.ToString();
			errorsExist = true;
		}
		return false;
	}

	private bool AddTestContainer(string filePath, QC.QsprTestObjects.Tests.Base.QTMTestTypes testType)
	{
		try
		{
			if (((QTMRegistry)scheduler.QTMData.theRegistry).Targets.Count > 0)
			{
				if (!File.Exists(filePath))
				{
					lastError = "Failed to add test container. The path doesn't exist: " + filePath;
					return false;
				}
				if (AddContainer(testType, filePath))
				{
					return true;
				}
				lastError = "Failed to add test container " + filePath;
				return false;
			}
			lastError = "Failed to add test container, no targets exist in the tree registry";
			return false;
		}
		catch (Exception ex)
		{
			lastError = "Failed to add test container: " + Environment.NewLine + ex.ToString();
			return false;
		}
	}

	private bool AddContainer(QC.QsprTestObjects.Tests.Base.QTMTestTypes testType, string containerName)
	{
		QTMRegistry qTMRegistry = (QTMRegistry)scheduler.QTMData.theRegistry;
		QTMTarget qTMTarget = qTMRegistry.Targets["This PC"] as QTMTarget;
		try
		{
			string oldName = "";
			if (TestContainerExists(qTMTarget, containerName, out oldName))
			{
				string containerStringName = QTMTestContainer.GetContainerStringName(testType);
				QTMTestContainer container = qTMTarget.GetContainer(oldName);
				if (container.Loaded && container.ContainerType == QC.QsprTestObjects.Tests.Base.QTMTestTypes.DotNetTest)
				{
					lastError = containerStringName + " is already present!\nDotNet DLLs cannot be unloaded and replaced. To replace the DLL, close and reopen the application.";
					return false;
				}
				if (container.Loaded)
				{
					UnloadContainer(container);
				}
				QTMTestContainer qTMTestContainer = container;
				qTMTarget.DeleteTestContainer(oldName);
				qTMTarget.AddTestContainer(containerName, testType);
				qTMTestContainer = qTMTarget.GetContainer(containerName);
				qTMTestContainer.Key = qTMTarget.Name + containerName;
				LoadContainer(qTMTestContainer, newContainer: true);
				scheduler.GlobalStatus.RegistrationStatus.RegistryChanged = true;
				return true;
			}
			AddDLLToTarget(testType, containerName, qTMTarget);
			return true;
		}
		catch (Exception ex)
		{
			lastError = "AddContainer failed with exception: " + ex.ToString();
			return false;
		}
	}

	private bool TestContainerExists(QTMTarget target, string newName, out string oldName)
	{
		oldName = "";
		try
		{
			FileInfo fileInfo = new FileInfo(newName);
			foreach (QTMTestContainer value in target.HashContainers.Values)
			{
				FileInfo fileInfo2 = new FileInfo(value.Name);
				if (fileInfo.Name.Trim().ToUpper() == fileInfo2.Name.Trim().ToUpper())
				{
					oldName = value.Name;
					return true;
				}
			}
		}
		catch
		{
		}
		return false;
	}

	internal void LoadContainer(QTMTestContainer containerNode, bool newContainer)
	{
		try
		{
			((QTMRegistry)scheduler.QTMData.theRegistry).LoadContainer(containerNode, newContainer);
			containerNode.UserInterfaceProperties.UnloadSupported = containerNode.ContainerType != QC.QsprTestObjects.Tests.Base.QTMTestTypes.DotNetTest;
		}
		catch (Exception ex)
		{
			lastError = "LoadContainer failed with exception: " + ex.ToString();
		}
	}

	internal void UnloadContainer(QTMTestContainer containerNode)
	{
		try
		{
			try
			{
				QTMTarget target = ((QTMRegistry)scheduler.QTMData.theRegistry).GetTarget(containerNode.TargetName);
				target.UnloadContainer(containerNode.ContainerType, containerNode.Name);
				containerNode.Reset();
			}
			catch (Exception ex)
			{
				lastError = "Unload Failed with exception: " + ex.ToString();
			}
		}
		catch (Exception ex2)
		{
			lastError = "UnloadContainer failed with exception: " + ex2.ToString();
		}
	}

	private void AddDLLToTarget(QC.QsprTestObjects.Tests.Base.QTMTestTypes testType, string strContainer, QTMTarget Target, bool tryToLoadDLL = true)
	{
		Target.Expanded = true;
		Target.AddTestContainer(strContainer, testType);
		QTMTestContainer container = Target.GetContainer(strContainer);
		container.Key = Target.Name + strContainer;
		if (tryToLoadDLL)
		{
			LoadContainer(container, newContainer: true);
		}
		container.Expanded = true;
		scheduler.GlobalStatus.RegistrationStatus.RegistryChanged = true;
	}
}
