using System;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using System.Linq;
using QC.CTDS.DM.DataStructures;
using QC.CTDS.DM.DataStructures.FormatDescriptorStructure;
using QC.CTDS.DM.DataStructures.InputDataStructure;
using QC.CTDS.DM.DataStructures.OutputDataStructure;
using QC.CTDS.DM.SharedLibrary;

namespace QC.CTDS.DM.DataProcessor;

public class MultiDimensionDescriptorProcessor : IDescriptorProcessor
{
	private const string BLANK_COLUMN = " ";

	private MultiDimensionOutputGroupDescriptor fdMultiDimensionChartDescriptor;

	internal ReportSettings reportSettings;

	internal List<TestRunInfo> testRuns;

	internal MultiDimensionDescriptorProcessor()
	{
	}

	public OutputGroup ProcessDescriptorData(ReportSettings settings, GroupSetDescriptor groupSetDesc, List<TestRunInfo> testRuns)
	{
		reportSettings = settings;
		fdMultiDimensionChartDescriptor = groupSetDesc as MultiDimensionOutputGroupDescriptor;
		this.testRuns = testRuns;
		if (reportSettings.FailureAnalysis)
		{
			return null;
		}
		if (fdMultiDimensionChartDescriptor == null)
		{
			throw new Exception("Unsopported descriptor type");
		}
		OutputGroup multiChartOutputDataGrp = new OutputGroup();
		multiChartOutputDataGrp.Name = fdMultiDimensionChartDescriptor.Name;
		if (fdMultiDimensionChartDescriptor.OGDisplayProperties != null && fdMultiDimensionChartDescriptor.OGDisplayProperties.Count > 0)
		{
			multiChartOutputDataGrp.DisplayProp = fdMultiDimensionChartDescriptor.OGDisplayProperties[0];
		}
		testRuns = DataProcessorUtils.GetTestFilteredSourceData(from res in fdMultiDimensionChartDescriptor.GetResultSets()
			where !string.IsNullOrEmpty(res.testID) && !string.IsNullOrEmpty(res.resID)
			select res, testRuns);
		if (testRuns.Count > 0)
		{
			string xAxisTitle = fdMultiDimensionChartDescriptor.xName;
			string yAxisTitle = fdMultiDimensionChartDescriptor.yName;
			string zAxisTitle = fdMultiDimensionChartDescriptor.zName;
			if (fdMultiDimensionChartDescriptor.Discriminator1.Count > 0 || fdMultiDimensionChartDescriptor.Filter.Count > 0)
			{
				List<DiscGroup> chartGroupedItems = DataProcessorUtils.GetFilteredSourceData(fdMultiDimensionChartDescriptor, testRuns, fdMultiDimensionChartDescriptor.sort);
				multiChartOutputDataGrp.ChartLevelDiscriminatorValues = new Dictionary<string, List<string>>();
				IEnumerable<DescriptorItem> descriptorItems = fdMultiDimensionChartDescriptor.GetDescriptorItems();
				descriptorItems?.ForEach(delegate(DescriptorItem disc)
				{
					multiChartOutputDataGrp.ChartLevelDiscriminatorValues.Add(disc.Id, null);
				});
				if (chartGroupedItems.Count <= 0)
				{
					return multiChartOutputDataGrp;
				}
				MultiDimensionData[] multiDimDataArray = new MultiDimensionData[chartGroupedItems.Count];
				CommonFunctions.RunLoop(reportSettings.RunInSequentialMode, 0, chartGroupedItems.Count, delegate(int index)
				{
					Stopwatch stopwatch = new Stopwatch();
					stopwatch.Start();
					MultiDimensionData multiDimensionData2 = ProcessResultDataSet(fdMultiDimensionChartDescriptor.MultiDimensionResultSet[0], chartGroupedItems[index].TestItems, chartGroupedItems[index].GrpName, ref xAxisTitle, ref yAxisTitle, ref zAxisTitle);
					multiDimensionData2.Name = fdMultiDimensionChartDescriptor.Name + " : " + chartGroupedItems[index].GrpName;
					multiDimensionData2.XAxisTitle = fdMultiDimensionChartDescriptor.xName;
					multiDimensionData2.YAxisTitle = fdMultiDimensionChartDescriptor.yName;
					multiDimensionData2.ZAxisTitle = fdMultiDimensionChartDescriptor.zName;
					multiDimDataArray[index] = multiDimensionData2;
				});
				new List<string>();
				for (int i = 0; i < multiDimDataArray.Length; i++)
				{
					if (multiDimDataArray[i] == null || multiDimDataArray.Count() <= 0)
					{
						continue;
					}
					multiChartOutputDataGrp.OutputDataList.Add(multiDimDataArray[i]);
					if (chartGroupedItems[i].ParamsDict == null)
					{
						continue;
					}
					foreach (DescriptorItem item2 in descriptorItems)
					{
						if (!chartGroupedItems[i].ParamsDict.ContainsKey(item2.Id))
						{
							continue;
						}
						ParamInfo paramInfo = chartGroupedItems[i].ParamsDict[item2.Id];
						string item = ((!string.IsNullOrEmpty(paramInfo.StrVal)) ? paramInfo.StrVal : paramInfo.Val.ToString());
						if (paramInfo != null)
						{
							if (multiChartOutputDataGrp.ChartLevelDiscriminatorValues[item2.Id] == null)
							{
								multiChartOutputDataGrp.ChartLevelDiscriminatorValues[item2.Id] = new List<string> { item };
							}
							else if (!multiChartOutputDataGrp.ChartLevelDiscriminatorValues[item2.Id].Contains(item))
							{
								multiChartOutputDataGrp.ChartLevelDiscriminatorValues[item2.Id].Add(item);
							}
						}
					}
				}
			}
			else
			{
				MultiDimensionData multiDimensionData = ProcessResultDataSet(fdMultiDimensionChartDescriptor.MultiDimensionResultSet[0], testRuns, "", ref xAxisTitle, ref yAxisTitle, ref zAxisTitle);
				multiDimensionData.Name = fdMultiDimensionChartDescriptor.Name;
				if (multiDimensionData != null)
				{
					multiChartOutputDataGrp.OutputDataList.Add(multiDimensionData);
				}
			}
			fdMultiDimensionChartDescriptor.xName = xAxisTitle;
			fdMultiDimensionChartDescriptor.yName = yAxisTitle;
			fdMultiDimensionChartDescriptor.zName = zAxisTitle;
		}
		return multiChartOutputDataGrp;
	}

	private MultiDimensionData ProcessResultDataSet(MultiDimensionResult multiDimensionResult, List<TestRunInfo> testRuns, string combinedStr, ref string xAxisTitle, ref string yAxisTitle, ref string zAxisTitle)
	{
		_ = string.Empty;
		MultiDimensionData outputData = new MultiDimensionData();
		List<TestRunInfo> testFilteredSourceData = DataProcessorUtils.GetTestFilteredSourceData(new ResultDataSet[1] { multiDimensionResult }, testRuns);
		testFilteredSourceData = testFilteredSourceData.Where((TestRunInfo runinfo) => runinfo.ContainsParam(multiDimensionResult.resID)).ToList();
		if (testFilteredSourceData.Count > 0)
		{
			Dictionary<string, List<DataRow>> dictionary = new Dictionary<string, List<DataRow>>();
			if (multiDimensionResult.XAxis != null)
			{
				List<DiscGroup> filteredSourceData = DataProcessorUtils.GetFilteredSourceData(multiDimensionResult.ZAxis, testFilteredSourceData, multiDimensionResult.sort);
				outputData.DataTbl = new DataTable();
				if (!outputData.DataTbl.Columns.Contains(" "))
				{
					outputData.DataTbl.Columns.Add(" ");
				}
				List<DescriptorItem> descItems = new List<DescriptorItem>(multiDimensionResult.XAxis.GetDescriptorItems());
				descItems = DataProcessorUtils.RemoveDuplicateDescriptorItems(descItems);
				List<DescriptorItem> descItems2 = new List<DescriptorItem>(multiDimensionResult.ZAxis.GetDescriptorItems());
				descItems2 = DataProcessorUtils.RemoveDuplicateDescriptorItems(descItems2);
				List<DiscGroup> filteredSourceData2 = DataProcessorUtils.GetFilteredSourceData(multiDimensionResult, testFilteredSourceData, multiDimensionResult.sort);
				TestRunInfo runInfo = filteredSourceData2[0].TestItems.Find((TestRunInfo s) => s.ContainsParam(multiDimensionResult.resID));
				if (string.IsNullOrEmpty(yAxisTitle))
				{
					yAxisTitle = multiDimensionResult.resID;
				}
				if (string.IsNullOrEmpty(xAxisTitle))
				{
					xAxisTitle = GetAxisTitle(descItems, runInfo);
				}
				if (string.IsNullOrEmpty(zAxisTitle))
				{
					zAxisTitle = GetAxisTitle(descItems2, runInfo);
				}
				if (filteredSourceData == null || filteredSourceData.Count == 0)
				{
					filteredSourceData = DataProcessorUtils.GetFilteredSourceData(multiDimensionResult, testFilteredSourceData, multiDimensionResult.sort);
					outputData.DataTbl.Namespace = "NoZAxisData";
				}
				foreach (DiscGroup item in filteredSourceData)
				{
					List<DiscGroup> filteredSourceData3 = DataProcessorUtils.GetFilteredSourceData(multiDimensionResult.XAxis, item.TestItems, multiDimensionResult.sort);
					foreach (DiscGroup item2 in filteredSourceData3)
					{
						foreach (TestRunInfo testItem in item2.TestItems)
						{
							ParamInfo paramValue = testItem.GetParamValue(multiDimensionResult.resID);
							OutputParamInfo outputParamInfo = null;
							if (paramValue != null)
							{
								outputParamInfo = ((!(paramValue is OutputParamInfo)) ? new OutputParamInfo(paramValue) : (paramValue as OutputParamInfo));
							}
							if (outputParamInfo == null)
							{
								continue;
							}
							string columnName = CombineColumnValues(descItems, testItem);
							string key = CombineColumnValues(descItems2, testItem);
							if (!string.IsNullOrEmpty(columnName) && !outputData.DataTbl.Columns.Contains(columnName))
							{
								outputData.DataTbl.Columns.Add(columnName);
							}
							string value = ((!double.IsNaN(outputParamInfo.Val)) ? outputParamInfo.Val.ToString() : outputParamInfo.StrVal);
							if (dictionary.ContainsKey(key))
							{
								DataRow dataRow = dictionary[key].Find((DataRow dRow) => Convert.IsDBNull(dRow[columnName]));
								if (dataRow != null)
								{
									dataRow[columnName] = value;
									continue;
								}
								dataRow = outputData.DataTbl.NewRow();
								dataRow[columnName] = value;
								dictionary[key].Add(dataRow);
							}
							else
							{
								DataRow dataRow = outputData.DataTbl.NewRow();
								dataRow[columnName] = value;
								List<DataRow> list = new List<DataRow>();
								list.Add(dataRow);
								dictionary.Add(key, list);
							}
						}
					}
				}
				if (dictionary.Count > 0)
				{
					foreach (KeyValuePair<string, List<DataRow>> seriesRowPair in dictionary)
					{
						KeyValuePair<string, List<DataRow>> keyValuePair = seriesRowPair;
						List<DataRow> value2 = keyValuePair.Value;
						Action<DataRow> action = delegate(DataRow row)
						{
							KeyValuePair<string, List<DataRow>> keyValuePair3 = seriesRowPair;
							row[" "] = keyValuePair3.Key;
						};
						value2.ForEach(action);
						KeyValuePair<string, List<DataRow>> keyValuePair2 = seriesRowPair;
						keyValuePair2.Value.ForEach(delegate(DataRow row)
						{
							outputData.DataTbl.Rows.Add(row);
						});
					}
				}
				RemoveEmptyRowsFromTable(outputData.DataTbl);
			}
		}
		return outputData;
	}

	private string CombineColumnValues(List<DescriptorItem> axisDiscItems, TestRunInfo runInfo)
	{
		List<string> list = new List<string>();
		if (runInfo != null)
		{
			for (int i = 0; i < axisDiscItems.Count; i++)
			{
				if (!axisDiscItems[i].IsVisible)
				{
					continue;
				}
				if (axisDiscItems[i].IsFilter)
				{
					if (!string.IsNullOrEmpty(axisDiscItems[i].Name))
					{
						list.Add(axisDiscItems[i].Name + axisDiscItems[i].Value);
					}
					else
					{
						list.Add(axisDiscItems[i].Id + axisDiscItems[i].Value);
					}
				}
				else if (runInfo.ContainsParam(axisDiscItems[i].Id))
				{
					ParamInfo paramValue = runInfo.GetParamValue(axisDiscItems[i].Id);
					list.Add(double.IsNaN(paramValue.Val) ? paramValue.StrVal : paramValue.Val.ToString());
				}
			}
		}
		return string.Join(":", list);
	}

	private void RemoveEmptyRowsFromTable(DataTable dataTable)
	{
		if (dataTable == null)
		{
			return;
		}
		List<DataRow> list = new List<DataRow>();
		for (int i = 0; i < dataTable.Rows.Count; i++)
		{
			bool flag = true;
			for (int j = 1; j < dataTable.Columns.Count; j++)
			{
				if (!Convert.IsDBNull(dataTable.Rows[i][j]) && !string.IsNullOrEmpty(dataTable.Rows[i][j].ToString()))
				{
					flag = false;
					break;
				}
			}
			if (flag)
			{
				list.Add(dataTable.Rows[i]);
			}
		}
		list.ForEach(delegate(DataRow dataRow)
		{
			dataTable.Rows.Remove(dataRow);
		});
	}

	private string GetAxisTitle(List<DescriptorItem> axisDiscItems, TestRunInfo runInfo)
	{
		List<string> list = new List<string>();
		_ = string.Empty;
		if (runInfo != null)
		{
			for (int i = 0; i < axisDiscItems.Count; i++)
			{
				_ = string.Empty;
				if (!axisDiscItems[i].IsVisible)
				{
					continue;
				}
				if (!string.IsNullOrEmpty(axisDiscItems[i].Name))
				{
					if (axisDiscItems[i].IsFilter)
					{
						list.Add(axisDiscItems[i].Name + axisDiscItems[i].Value);
					}
					else
					{
						list.Add(axisDiscItems[i].Name);
					}
				}
				else if (runInfo.ContainsParam(axisDiscItems[i].Id))
				{
					string text = axisDiscItems[i].Id;
					if (!string.IsNullOrEmpty(runInfo.GetParamValue(axisDiscItems[i].Id).ParamUnit))
					{
						text = text + "(" + runInfo.GetParamValue(axisDiscItems[i].Id).ParamUnit + ")";
					}
					if (axisDiscItems[i].IsFilter)
					{
						text += axisDiscItems[i].Value;
					}
					list.Add(text);
				}
			}
		}
		return string.Join(":", list);
	}
}
