using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Text;
using System.Windows.Forms;
using System.Xml;
using System.Xml.Serialization;
using QC.QTMInterface;
using QC.QTMXmlSchema;

namespace QC.TestResultsLite;

internal class ConvertDataToFiles : IDisposable
{
	private string outputFileName;

	private StringBuilder errorMessage = new StringBuilder();

	private ROOT fileRoot = new ROOT();

	public string OutputFileName
	{
		get
		{
			return outputFileName;
		}
		set
		{
			outputFileName = value;
		}
	}

	public StringBuilder ErrorMessage
	{
		get
		{
			return errorMessage;
		}
		set
		{
			errorMessage = value;
		}
	}

	public ROOT FileRoot
	{
		get
		{
			return fileRoot;
		}
		set
		{
			fileRoot = value;
		}
	}

	public ConvertDataToFiles(string outFileName)
	{
		OutputFileName = outFileName;
		GenerateData();
		WriteToFile(outFileName);
	}

	public ConvertDataToFiles(DataTable resultsDT, ArrayList configs, string outFileName)
	{
		OutputFileName = outFileName;
		GenerateData(resultsDT, configs);
		WriteToFile(outFileName);
	}

	public void GenerateData()
	{
		try
		{
			DataTable resultData = (DataTable)TestData.ReadDataFromFile(ConstantNames.INTERMEDIATE_BIN_FILE);
			ArrayList configData = (ArrayList)TestData.ReadDataFromFile(ConstantNames.INTERMEDIATE_CONFIG_FILE);
			fileRoot.ConfigInfo = GenerateConfigInfo(configData);
			fileRoot.TEST = GenerateTests(resultData);
		}
		catch (Exception ex)
		{
			ErrorMessage.Append("GetDataFromFiles failed, " + ex.Message);
		}
	}

	public void GenerateData(DataTable resultsDT, ArrayList configs)
	{
		try
		{
			fileRoot.ConfigInfo = GenerateConfigInfo(configs);
			fileRoot.TEST = GenerateTests(resultsDT);
		}
		catch (Exception ex)
		{
			ErrorMessage.Append("GenerateData failed, " + ex.Message);
		}
	}

	public void WriteToFile(string fileName)
	{
		try
		{
			if (fileRoot != null)
			{
				SerializeObject(fileRoot, fileName);
			}
		}
		catch (Exception ex)
		{
			throw new Exception("WriteDataToFile failed, " + ex.Message);
		}
	}

	private string SerializeObject(object t)
	{
		XmlWriterSettings xmlWriterSettings = new XmlWriterSettings();
		XmlSerializerNamespaces xmlSerializerNamespaces = new XmlSerializerNamespaces();
		xmlSerializerNamespaces.Add("", "");
		xmlWriterSettings.OmitXmlDeclaration = true;
		StringWriter stringWriter = new StringWriter();
		XmlSerializer xmlSerializer = new XmlSerializer(t.GetType());
		using (XmlWriter xmlWriter = XmlWriter.Create(stringWriter, xmlWriterSettings))
		{
			xmlSerializer.Serialize(xmlWriter, t, xmlSerializerNamespaces);
		}
		return stringWriter.ToString();
	}

	private void SerializeObject(object obj, string fileName)
	{
		XmlWriterSettings xmlWriterSettings = new XmlWriterSettings();
		xmlWriterSettings.Indent = false;
		xmlWriterSettings.NewLineHandling = NewLineHandling.None;
		xmlWriterSettings.OmitXmlDeclaration = true;
		XmlSerializer xmlSerializer = new XmlSerializer(obj.GetType());
		using XmlWriter xmlWriter = XmlWriter.Create(fileName, xmlWriterSettings);
		string text = Path.Combine(Path.GetDirectoryName(Application.ExecutablePath), Path.Combine(GlobalInformation.RunTimeConfig.styleSheetsDirectory, "QTMData.xsl"));
		xmlWriter.WriteProcessingInstruction("xml-stylesheet", "type=\"text/xsl\" href=\"" + text + "\"");
		xmlSerializer.Serialize(xmlWriter, obj);
	}

	private ROOTTEST[] GenerateTests(DataTable resultData)
	{
		ROOTTEST[] result = null;
		try
		{
			ArrayList arrayList = new ArrayList();
			ROOTTEST rOOTTEST = null;
			ROOTTESTParamResults currParam = null;
			ArrayList arrayList2 = new ArrayList();
			ArrayList arrayList3 = new ArrayList();
			foreach (DataRow row in resultData.Rows)
			{
				try
				{
					if (Convert.ToInt16(GetStringValue(row, "SessionDataRID")) == 0)
					{
						AddCurrTest(arrayList, rOOTTEST, currParam, arrayList2, arrayList3);
						rOOTTEST = new ROOTTEST();
						currParam = null;
						arrayList2.Clear();
						arrayList3.Clear();
						rOOTTEST.TNAME = GetStringValue(row, "TestName");
						rOOTTEST.RES = GetStringValue(row, "TestResult");
						GetLoop(rOOTTEST, row);
						GetParamResult(row, ref currParam, arrayList2, arrayList3);
					}
					else
					{
						GetParamResult(row, ref currParam, arrayList2, arrayList3);
					}
				}
				catch (Exception ex)
				{
					ErrorMessage.Append("Parsing data row failed, " + ex.Message);
				}
			}
			AddCurrTest(arrayList, rOOTTEST, currParam, arrayList2, arrayList3);
			result = (ROOTTEST[])arrayList.ToArray(typeof(ROOTTEST));
		}
		catch (Exception ex2)
		{
			ErrorMessage.Append("GenerateTests failed, " + ex2.Message);
		}
		return result;
	}

	private static void AddCurrTest(ArrayList tests, ROOTTEST currTest, ROOTTESTParamResults currParam, ArrayList paramResults, ArrayList arrayResults)
	{
		if (currTest != null)
		{
			AddCurrParamToList(currParam, paramResults, arrayResults);
			if (paramResults.Count > 0)
			{
				currTest.ParamResults = (ROOTTESTParamResults[])paramResults.ToArray(typeof(ROOTTESTParamResults));
			}
			tests.Add(currTest);
		}
	}

	private static void AddCurrParamToList(ROOTTESTParamResults currParam, ArrayList paramResults, ArrayList arrayResults)
	{
		if (currParam != null)
		{
			if (arrayResults.Count > 0)
			{
				currParam.ParamArrayResults = (ROOTTESTParamArrayResults[])arrayResults.ToArray(typeof(ROOTTESTParamArrayResults));
			}
			paramResults.Add(currParam);
		}
	}

	private void GetLoop(ROOTTEST currTest, DataRow dr)
	{
		ROOTTESTLOOPVALUES rOOTTESTLOOPVALUES = new ROOTTESTLOOPVALUES();
		ROOTTESTLOOPVALUESLV rOOTTESTLOOPVALUESLV = new ROOTTESTLOOPVALUESLV();
		rOOTTESTLOOPVALUESLV.V = GetStringValue(dr, "ScnValue");
		if (!string.IsNullOrEmpty(rOOTTESTLOOPVALUESLV.V))
		{
			rOOTTESTLOOPVALUES.LV = rOOTTESTLOOPVALUESLV;
			currTest.LOOPVALUES = rOOTTESTLOOPVALUES;
		}
	}

	private void GetParamInfo(ROOTTESTParamResults currParam, DataRow paramData, out string newParamName, out bool isArray, out bool isNewParam, out string arrayIndex)
	{
		string stringValue = GetStringValue(paramData, "ParameterName");
		if (stringValue.Contains("::"))
		{
			string[] array = stringValue.Split(new string[1] { "::" }, StringSplitOptions.None);
			newParamName = array[0].ToString();
			arrayIndex = array[1].ToString();
			isArray = true;
		}
		else
		{
			newParamName = stringValue;
			isArray = false;
			arrayIndex = "-1";
		}
		if (currParam != null)
		{
			if (currParam.N == newParamName)
			{
				isNewParam = false;
			}
			else
			{
				isNewParam = true;
			}
		}
		else
		{
			isNewParam = true;
		}
	}

	private void GetParamResult(DataRow paramData, ref ROOTTESTParamResults currParam, ArrayList paramResults, ArrayList arrayResults)
	{
		try
		{
			GetParamInfo(currParam, paramData, out var newParamName, out var isArray, out var isNewParam, out var arrayIndex);
			if (isNewParam)
			{
				AddCurrParamToList(currParam, paramResults, arrayResults);
				currParam = null;
				arrayResults.Clear();
				if (newParamName != "")
				{
					currParam = new ROOTTESTParamResults();
					currParam.N = newParamName;
					if (isArray)
					{
						AddArrayInfo(paramData, arrayResults, arrayIndex, newParamName);
						return;
					}
					currParam.LL = GetStringValue(paramData, "LowerLimit");
					currParam.UL = GetStringValue(paramData, "UpperLimit");
					currParam.CHAR_V = GetStringValue(paramData, "CharValue");
					currParam.V = GetStringValue(paramData, "NumValue");
					currParam.UOM = GetStringValue(paramData, "UOM");
				}
			}
			else if (isArray)
			{
				AddArrayInfo(paramData, arrayResults, arrayIndex, newParamName);
			}
			else
			{
				ErrorMessage.Append("Error generating array info");
			}
		}
		catch (Exception ex)
		{
			ErrorMessage.Append("GetParamResult failed, " + ex.Message);
		}
	}

	private void AddArrayInfo(DataRow paramData, ArrayList arrayResults, string arrayIndex, string paramName)
	{
		ROOTTESTParamArrayResults rOOTTESTParamArrayResults = new ROOTTESTParamArrayResults();
		rOOTTESTParamArrayResults.N = paramName;
		rOOTTESTParamArrayResults.LL = GetStringValue(paramData, "LowerLimit");
		rOOTTESTParamArrayResults.UL = GetStringValue(paramData, "UpperLimit");
		rOOTTESTParamArrayResults.CHAR_V = GetStringValue(paramData, "CharValue");
		rOOTTESTParamArrayResults.V = GetStringValue(paramData, "NumValue");
		rOOTTESTParamArrayResults.UOM = GetStringValue(paramData, "UOM");
		rOOTTESTParamArrayResults.I = arrayIndex;
		arrayResults.Add(rOOTTESTParamArrayResults);
	}

	private string GetStringValue(DataRow testRow, string valueName)
	{
		try
		{
			return testRow[valueName].ToString();
		}
		catch
		{
			return "";
		}
	}

	private Config GenerateConfigInfo(ArrayList configData)
	{
		Config config = new Config();
		try
		{
			Dictionary<string, string> configDictionary = GetConfigDictionary(configData);
			config.Comments = GetConfig(configDictionary, "Comments");
			config.Database = GetConfig(configDictionary, "Database");
			config.ERROR_CODE = GetConfig(configDictionary, "ERROR_CODE");
			config.MachineName = GetConfig(configDictionary, "MachineName");
			config.MCN = GetConfig(configDictionary, "MCN");
			config.Result = GetConfig(configDictionary, "Result");
			config.RunTitle = GetConfig(configDictionary, "RunTitle");
			config.Server = GetConfig(configDictionary, "Server");
			config.SessionDataRID = GetConfig(configDictionary, "SessionDataRID");
			config.SessionName = GetConfig(configDictionary, "SessionName");
			config.StartTime = GetConfig(configDictionary, "StartTime");
			config.StopTime = GetConfig(configDictionary, "StopTime");
			config.SW_MCN = GetConfig(configDictionary, "SW_MCN");
			config.SW_VER = GetConfig(configDictionary, "SW_VER");
			config.TESTERID = GetConfig(configDictionary, "TESTERID");
			config.TreeFileName = GetConfig(configDictionary, "TreeFileName");
			config.TreeID = (string.IsNullOrEmpty(GetConfig(configDictionary, "TreeID")) ? "-1" : GetConfig(configDictionary, "TreeID"));
			config.TreeType = GetConfig(configDictionary, "TreeType");
			config.UUT_SN = GetConfig(configDictionary, "UUT_SN");
			config.WORKSTATION = GetConfig(configDictionary, "WORKSTATION");
		}
		catch (Exception ex)
		{
			ErrorMessage.Append("GenerateConfigInfo failed, " + ex.Message);
		}
		return config;
	}

	private string GetConfig(Dictionary<string, string> configs, string configName)
	{
		try
		{
			if (configs.ContainsKey(configName))
			{
				return Convert.ToString(configs[configName]);
			}
			return "";
		}
		catch
		{
			return "";
		}
	}

	private Dictionary<string, string> GetConfigDictionary(ArrayList configData)
	{
		Dictionary<string, string> dictionary = new Dictionary<string, string>();
		foreach (TesterConfigurationInfo configDatum in configData)
		{
			if (!dictionary.ContainsKey(configDatum.Name))
			{
				dictionary.Add(configDatum.Name, configDatum.Value);
			}
		}
		return dictionary;
	}

	public void Dispose()
	{
	}
}
