using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Xml.Serialization;

namespace QC.QSPRLogSchema;

[Serializable]
[XmlType(AnonymousType = true)]
[XmlRoot(Namespace = "", IsNullable = false)]
public class Run
{
	[DebuggerBrowsable(DebuggerBrowsableState.Never)]
	private List<Test> tcField;

	[DebuggerBrowsable(DebuggerBrowsableState.Never)]
	private RunInfo runInfoField;

	[DebuggerBrowsable(DebuggerBrowsableState.Never)]
	private List<int> validDSIds;

	private int dsIDCounter;

	[XmlIgnore]
	public Test CurrentTest;

	[XmlElement(IsNullable = false)]
	public string ExtendedData { get; set; }

	[XmlElement(IsNullable = false)]
	public string IsRunning { get; set; }

	[XmlElement(IsNullable = false)]
	public RunInfo RunInfo
	{
		get
		{
			return runInfoField;
		}
		set
		{
			runInfoField = value;
		}
	}

	[XmlArray("TC", IsNullable = false)]
	[XmlArrayItem(typeof(Test), ElementName = "Test")]
	public List<Test> TestCollection => tcField;

	[XmlIgnore]
	public List<Test> TestCasesCollection => TestCollection.Where((Test test) => Convert.ToInt64(test.TCCaseRefId) < 1 && test.TestCase != null && test.TestCase.TCCaseID != null).ToList();

	public bool ShouldSerializeExtendedData()
	{
		return string.Compare(ExtendedData, "false", ignoreCase: true) != 0;
	}

	public bool ShouldSerializeIsRunning()
	{
		return string.Compare(IsRunning, "false", ignoreCase: true) != 0;
	}

	public Run()
	{
		runInfoField = new RunInfo();
		CurrentTest = new Test();
		tcField = new List<Test>();
		validDSIds = new List<int>();
		dsIDCounter = 0;
		ExtendedData = "false";
		IsRunning = "false";
	}

	public Run(string path)
	{
		XmlSerializer xmlSerializer = new XmlSerializer(typeof(Run));
		using FileStream stream = new FileStream(path, FileMode.Open);
		Run run = (Run)xmlSerializer.Deserialize(stream);
		tcField = run.tcField;
		runInfoField = run.runInfoField;
		ExtendedData = run.ExtendedData;
		IsRunning = run.IsRunning;
	}

	public Run(List<Test> tc = null, RunInfo runInfo = null)
	{
		if (runInfo != null)
		{
			runInfoField = runInfo;
		}
		else
		{
			runInfoField = new RunInfo();
		}
		if (tc != null)
		{
			tcField = tc;
		}
		else
		{
			tcField = new List<Test>();
		}
		CurrentTest = new Test();
		validDSIds = new List<int>();
		dsIDCounter = 0;
		ExtendedData = "false";
		IsRunning = "false";
	}

	public int AddCurrentTest(bool useDSRefID = true)
	{
		int num = -1;
		foreach (DataSetReference dataSetReference in CurrentTest.DataSet.DataSetReferences)
		{
			if (!validDSIds.Contains(int.Parse(dataSetReference.Id)))
			{
				throw new Exception("DS With ID \"" + dataSetReference.Id + "\" Is Referenced But Does Not Exist.");
			}
		}
		if (CurrentTest.DataSet.Input.Inputs.Count > 0 || CurrentTest.DataSet.Input.ArrayInputs.Count > 0 || CurrentTest.DataSet.Output.Outputs.Count > 0 || CurrentTest.DataSet.Output.ArrayOutputs.Count > 0 || CurrentTest.DataSet.DataSetReferences.Count > 0)
		{
			if (useDSRefID)
			{
				string text = MatchExistingDataSet();
				if (!text.Equals("-1"))
				{
					CurrentTest.DataSet = new DataSet();
					CurrentTest.DataSet.DataSetReferences.Add(new DataSetReference(text));
				}
			}
			CurrentTest.DataSet.Id = (++dsIDCounter).ToString();
			validDSIds.Add(int.Parse(CurrentTest.DataSet.Id));
		}
		tcField.Add(CurrentTest);
		CurrentTest = new Test();
		return dsIDCounter;
	}

	private string MatchExistingDataSet()
	{
		string result = "-1";
		if (CurrentTest.DataSet != null)
		{
			Test test = tcField.Find((Test T) => T.DataSet.Output.Equals(CurrentTest.DataSet.Output) && T.DataSet.Input.Equals(CurrentTest.DataSet.Input));
			if (test != null && test.DataSet != null && !string.IsNullOrEmpty(test.DataSet.Id))
			{
				result = test.DataSet.Id;
			}
		}
		return result;
	}

	public int AddTest(Test test)
	{
		int num = -1;
		Test currentTest = CurrentTest;
		CurrentTest = test.DeepClone();
		num = AddCurrentTest();
		CurrentTest = currentTest;
		return num;
	}

	public int AddTestsWithoutDSRefrences(List<Test> tests)
	{
		int result = -1;
		Test currentTest = CurrentTest;
		foreach (Test test in tests)
		{
			CurrentTest = test.DeepClone();
			if (CurrentTest.DataSet.DataSetReferences.Count > 0)
			{
				CurrentTest.DataSet = tests.Find((Test T) => T.DataSet.Id == CurrentTest.DataSet.DataSetReferences[0].Id).DataSet.DeepClone();
			}
			result = AddCurrentTest(useDSRefID: false);
		}
		CurrentTest = currentTest;
		return result;
	}

	public void ReplaceTestList(List<Test> tests)
	{
		if (tests.Count <= 0)
		{
			return;
		}
		validDSIds.Clear();
		tcField.Clear();
		foreach (Test test in tests)
		{
			CurrentTest = test.DeepClone();
			AddCurrentTest();
		}
	}

	public void Clear()
	{
		runInfoField = null;
		runInfoField = new RunInfo();
		CurrentTest = null;
		CurrentTest = new Test();
		tcField.Clear();
		tcField = null;
		tcField = new List<Test>();
		validDSIds.Clear();
		validDSIds = null;
		validDSIds = new List<int>();
		dsIDCounter = 0;
	}

	public Test GetLastTestCopy()
	{
		Test lastTest = TestCollection.Last().DeepClone();
		if (lastTest.DataSet.DataSetReferences.Count > 0)
		{
			lastTest.DataSet = TestCollection.Find((Test T) => T.DataSet.Id == lastTest.DataSet.DataSetReferences[0].Id).DataSet.DeepClone();
		}
		return lastTest;
	}
}
