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

namespace QC.MultiplexManager;

public class DutInformation
{
	private struct Grouping
	{
		public int ID { get; set; }

		public int NumDuts { get; set; }
	}

	private ConfigurationFile cfg;

	private string cfg_filename = "";

	private List<DutCfg> allDuts;

	private List<Grouping> grouping_list;

	private ConfigurationFile CfgFile
	{
		get
		{
			return cfg;
		}
		set
		{
			cfg = value;
		}
	}

	private string ConfigFileName
	{
		get
		{
			return cfg_filename;
		}
		set
		{
			cfg_filename = value;
		}
	}

	private List<DutCfg> AllDuts
	{
		get
		{
			return allDuts;
		}
		set
		{
			allDuts = value;
		}
	}

	private List<Grouping> GroupingList
	{
		get
		{
			return grouping_list;
		}
		set
		{
			grouping_list = value;
		}
	}

	public DutCfg GetDutInfo(string configFile, int dutNumber)
	{
		ExtractInfoForAllDuts(configFile);
		foreach (DutCfg allDut in AllDuts)
		{
			if (allDut.DutID == dutNumber)
			{
				return allDut;
			}
		}
		throw new Exception("No DUT Info available in " + ConfigFileName + " for DUT ID = " + dutNumber);
	}

	public void ExtractInfoForAllDuts(string configFile)
	{
		try
		{
			if (CfgFile == null || !ConfigFileName.Contains(configFile))
			{
				DeserializeConfigFile(configFile);
				ValidateConfigFileEntries();
				AllDuts = null;
			}
			if (AllDuts != null)
			{
				return;
			}
			AllDuts = new List<DutCfg>();
			if (GroupingList == null)
			{
				GroupingList = new List<Grouping>();
			}
			else
			{
				GroupingList.Clear();
			}
			Group[] groupList = CfgFile.MultiDUTConfigItems.GroupsSection.GroupList;
			foreach (Group group in groupList)
			{
				int num = 0;
				for (int j = 0; j < group.DutList.Length; j++)
				{
					DutCfg dutCfg = new DutCfg();
					dutCfg.GroupID = group.GroupID;
					dutCfg.DutID = group.DutList[j].DutID;
					dutCfg.MultiplexerType = group.DutList[j].MultiplexerType;
					if (dutCfg.MultiplexerCfgList == null)
					{
						dutCfg.MultiplexerCfgList = new List<MuxCfg>();
					}
					else
					{
						dutCfg.MultiplexerCfgList.Clear();
					}
					string[] array = group.DutList[j].MultiplexerIDs.Split(',');
					int[] array2 = new int[array.Length];
					for (int k = 0; k < array.Length; k++)
					{
						array2[k] = Convert.ToInt32(array[k]);
					}
					string[] array3 = group.DutList[j].MultiplexerPaths.Split(',');
					int[] array4 = new int[array3.Length];
					for (int l = 0; l < array3.Length; l++)
					{
						array4[l] = Convert.ToInt32(array3[l]);
					}
					for (int m = 0; m < array2.Length; m++)
					{
						if (array2[m] == -1)
						{
							continue;
						}
						bool flag = false;
						Multiplexer[] multiplexerList = CfgFile.MultiDUTConfigItems.MultiplexersSection.MultiplexerList;
						foreach (Multiplexer multiplexer in multiplexerList)
						{
							if (multiplexer.MultiplexerID == array2[m])
							{
								MuxCfg muxCfg = new MuxCfg();
								muxCfg.Mux = multiplexer;
								muxCfg.Path = array4[m];
								dutCfg.MultiplexerCfgList.Add(muxCfg);
								flag = true;
								break;
							}
						}
						if (!flag)
						{
							throw new Exception("MULTIPLEXER ID = " + array2[m] + " was specified for GROUP ID = " + dutCfg.GroupID + ", DUT ID = " + dutCfg.DutID + " but that MULTIPLEXER ID does not exist in " + ConfigFileName);
						}
					}
					AllDuts.Add(dutCfg);
					num++;
				}
				Grouping item = default(Grouping);
				item.ID = group.GroupID;
				item.NumDuts = num;
				GroupingList.Add(item);
			}
			int num2 = 1;
			string text = "";
			foreach (DutCfg allDut in AllDuts)
			{
				for (int num3 = num2; num3 < AllDuts.Count; num3++)
				{
					if (allDut.DutID == AllDuts[num3].DutID)
					{
						string text2 = text;
						text = text2 + "More than one DUT was assigned DUT ID = " + allDut.DutID + " in " + ConfigFileName + ". Each DUT must have a unique DUT ID.\n";
					}
				}
				num2++;
			}
			if (text.Length != 0)
			{
				throw new Exception(text);
			}
		}
		catch (Exception ex)
		{
			CfgFile = null;
			AllDuts = null;
			GroupingList = null;
			throw ex;
		}
	}

	private void DeserializeConfigFile(string configFileName)
	{
		CfgFile = null;
		try
		{
			XmlSerializer xmlSerializer = new XmlSerializer(typeof(ConfigurationFile));
			FileStream fileStream = new FileStream(configFileName, FileMode.Open, FileAccess.Read, FileShare.Read);
			CfgFile = (ConfigurationFile)xmlSerializer.Deserialize(fileStream);
			fileStream.Close();
			fileStream = null;
			if (CfgFile == null)
			{
				throw new Exception("Deserialization of " + configFileName + "failed!\n");
			}
			ConfigFileName = configFileName;
			EnvManager.GetInstance().DebugMessageWrite("Debug", "Multiplex Manager Config File: " + ConfigFileName);
		}
		catch (Exception ex)
		{
			CfgFile = null;
			ConfigFileName = "";
			throw ex;
		}
	}

	private void ValidateConfigFileEntries()
	{
		string text = "";
		if (CfgFile.MultiDUTConfigItems == null)
		{
			text += " MULTI_DUT_CONFIG node is missing.\n";
		}
		else
		{
			if (CfgFile.MultiDUTConfigItems.MultiplexersSection == null)
			{
				text += " MULTIPLEXERS node is missing.\n";
			}
			else if (CfgFile.MultiDUTConfigItems.MultiplexersSection.MultiplexerList.Length == 0)
			{
				text += " No MULTIPLEXER nodes listed.\n";
			}
			else
			{
				int num = 1;
				Multiplexer[] multiplexerList = CfgFile.MultiDUTConfigItems.MultiplexersSection.MultiplexerList;
				foreach (Multiplexer multiplexer in multiplexerList)
				{
					string text2 = multiplexer.MultiplexerID.ToString();
					if (multiplexer.MultiplexerID < 1)
					{
						if (multiplexer.MultiplexerID == -1)
						{
							text2 = "Unknown";
						}
						text = text + " MULTIPLEXER ID = " + text2 + ". Missing or invalid MULTIPLEXER ID. Must be an integer value greater than or equal to 1.\n";
					}
					if (multiplexer.DriverDLL.Length == 0)
					{
						text = text + " DRIVER_DLL was not specified for MULTIPLEXER ID = " + text2 + ".\n";
					}
					if (multiplexer.BusConfig.Length == 0)
					{
						text = text + " BUS_CONFIG was not specified for MULTIPLEXER ID = " + text2 + ".\n";
					}
					for (int j = 0; j < multiplexer.RoutingList.Length; j++)
					{
						if (multiplexer.RoutingList[j].Routing_Config.Length == 0)
						{
							text = text + " ROUTING_CONFIG was not specified for MULTIPLEXER ID = " + text2 + ".\n";
						}
						if (multiplexer.RoutingList[j].Ports.Length == 0)
						{
							EnvManager.GetInstance().DebugMessageWrite("Debug", " Config item PORTS is missing in xml file");
						}
					}
					string text3 = multiplexer.BusConfig.ToUpper().Replace(" ", "");
					for (int k = num; k < CfgFile.MultiDUTConfigItems.MultiplexersSection.MultiplexerList.Length; k++)
					{
						if (multiplexer.MultiplexerID == CfgFile.MultiDUTConfigItems.MultiplexersSection.MultiplexerList[k].MultiplexerID)
						{
							text = text + " More than one MULTIPLEXER was assigned MULTIPLEXER ID = " + multiplexer.MultiplexerID + ". ID must be unique for each MULTIPLEXER.\n";
						}
						string value = CfgFile.MultiDUTConfigItems.MultiplexersSection.MultiplexerList[k].BusConfig.ToUpper().Replace(" ", "");
						if (text3.Equals(value))
						{
							text = text + " More than one MULTIPLEXER is using BUS_CONFIG = \"" + multiplexer.BusConfig + "\". BUS_CONFIG must be unique for each MULTIPLEXER.\n";
						}
					}
					List<string> list = new List<string>();
					string text4 = "";
					for (int l = 0; l < multiplexer.RoutingList.Length; l++)
					{
						string text5 = multiplexer.RoutingList[l].Ports.ToUpper().Replace(" ", "");
						if (multiplexer.RoutingList[l].bands != "")
						{
							text4 = multiplexer.RoutingList[l].bands.ToUpper().Replace(" ", "");
						}
						text5 = text5 + " " + text4;
						if (list.Contains(text5))
						{
							text += " PORTS are duplicated in xml file . PORTS must be unique for each MULTIPLEXER.\n";
						}
						list.Add(text5);
					}
					num++;
				}
			}
			if (CfgFile.MultiDUTConfigItems.GroupsSection == null)
			{
				text += " GROUPS node is missing.\n";
			}
			else if (CfgFile.MultiDUTConfigItems.GroupsSection.GroupList.Length == 0)
			{
				text += " No GROUP nodes listed.\n";
			}
			else
			{
				int num2 = 1;
				Group[] groupList = CfgFile.MultiDUTConfigItems.GroupsSection.GroupList;
				foreach (Group group in groupList)
				{
					string text6 = group.GroupID.ToString();
					if (group.GroupID < 1)
					{
						if (group.GroupID == -1)
						{
							text6 = "Unknown";
						}
						text = text + " GROUP ID = " + text6 + ". Missing or invalid GROUP ID. Must be an integer value greater than or equal to 1.\n";
					}
					if (group.DutList.Length == 0)
					{
						text = text + " No DUT nodes listed for GROUP ID = " + text6 + ".\n";
					}
					else
					{
						Dut[] dutList = group.DutList;
						foreach (Dut dut in dutList)
						{
							string text7 = dut.DutID.ToString();
							if (dut.DutID < 1)
							{
								if (dut.DutID == -1)
								{
									text7 = "Unknown";
								}
								text = text + " DUT ID = " + text7 + ". Missing or invalid DUT ID. Must be an integer value greater than or equal to 1.\n";
							}
							if (dut.MultiplexerIDs.Length == 0)
							{
								text = text + " Missing MULTIPLEXER_IDS for DUT ID = " + text7 + ".\n";
							}
							if (dut.MultiplexerPaths.Length == 0)
							{
								text = text + " Missing MULTIPLEXER_PATHS for DUT ID = " + text7 + ".\n";
							}
							if (dut.MultiplexerIDs.Length <= 0 || dut.MultiplexerPaths.Length <= 0)
							{
								continue;
							}
							string[] array = dut.MultiplexerIDs.Split(',');
							string[] array2 = dut.MultiplexerPaths.Split(',');
							if (array.Length != array2.Length)
							{
								text = text + " MULTIPLEXER_IDS and MULTIPLEXER_PATHS for DUT ID = " + text7 + " must contain the same number of entries.\n";
								string text8 = text;
								text = text8 + "\tThey contain " + array.Length + " and " + array2.Length + " entries, respectively.\n";
								continue;
							}
							for (int num3 = 0; num3 < array.Length; num3++)
							{
								if (Convert.ToInt32(array[num3]) != -1 && Convert.ToInt32(array2[num3]) <= 0)
								{
									string text9 = text;
									text = text9 + " Invalid entry in MULTIPLEXER_PATHS: " + array2[num3] + " for DUT ID = " + text7 + " MULTIPLEXER ID = " + array[num3] + ".\n";
								}
							}
						}
					}
					for (int num4 = num2; num4 < CfgFile.MultiDUTConfigItems.GroupsSection.GroupList.Length; num4++)
					{
						if (group.GroupID == CfgFile.MultiDUTConfigItems.GroupsSection.GroupList[num4].GroupID)
						{
							text = text + " More than one GROUP was assigned GROUP ID = " + group.GroupID + ". ID must be unique for each GROUP.\n";
						}
					}
					num2++;
				}
			}
		}
		if (text.Length != 0)
		{
			throw new Exception("Error in " + ConfigFileName + ":\n" + text);
		}
	}

	public int GetNumDutsInGroup(int groupID)
	{
		int num = 0;
		if (AllDuts == null)
		{
			throw new Exception("ExtractInfoForAllDuts must be called prior to calling this function");
		}
		if (GroupingList == null)
		{
			throw new Exception("Grouping list is not available");
		}
		foreach (Grouping grouping in GroupingList)
		{
			if (grouping.ID == groupID)
			{
				num = grouping.NumDuts;
				break;
			}
		}
		if (num == 0)
		{
			throw new Exception("Unable to determine number of DUTs with Group ID = " + groupID);
		}
		return num;
	}

	public void GetDutAndGroupIds(out string dutIDs, out string groupIDs)
	{
		if (AllDuts == null)
		{
			throw new Exception("ExtractInfoForAllDuts must be called prior to calling this function");
		}
		dutIDs = "";
		groupIDs = "";
		for (int i = 0; i < AllDuts.Count; i++)
		{
			dutIDs += AllDuts[i].DutID;
			groupIDs += AllDuts[i].GroupID;
			if (i + 1 < AllDuts.Count)
			{
				dutIDs += ",";
				groupIDs += ",";
			}
		}
	}
}
