using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using QC.CTDS.DM.DataProcessor;
using QC.CTDS.DM.DataStructures;
using QC.CTDS.DM.DataStructures.FormatDescriptorStructure;
using QC.CTDS.DM.DataStructures.InputDataStructure;
using QC.CTDS.DM.DataStructures.LimitDescriptorDataStructure;
using QC.CTDS.DM.DataStructures.OutputDataStructure;
using QC.CTDS.DM.DataStructures.PluginDataStructure;
using QC.CTDS.DM.SharedLibrary;

namespace QC.CTDS.DM.ApplicationsManager;

public class ReportGenerator
{
	private const string defaultTech = "";

	private PluginManager pluginManager = new PluginManager();

	private string selectedInputPluginName;

	private Dictionary<string, InputData> techToInputDataMapping = new Dictionary<string, InputData>(StringComparer.Ordinal);

	private Dictionary<string, FormatDescriptorCollection> techToFormatDescMapping = new Dictionary<string, FormatDescriptorCollection>(StringComparer.Ordinal);

	private string preGroupingAppliedFormatDescString = string.Empty;

	private Dictionary<string, LimitDescriptorCollection> techToLimitDescMapping = new Dictionary<string, LimitDescriptorCollection>(StringComparer.Ordinal);

	private ReportSettings reportSettingsInfo = new ReportSettings();

	private List<ILogger> loggerList = new List<ILogger>();

	private List<string> enabledCharts = new List<string>();

	public string ReportEnviornment { get; set; }

	public string HiddenReportCommandForReprocessing { get; set; }

	public string ServicePluginVersion { get; set; }

	public ReportSettings ReportSettingsInfo
	{
		get
		{
			return reportSettingsInfo;
		}
		set
		{
			reportSettingsInfo = value;
		}
	}

	public List<ILogger> LoggerList
	{
		get
		{
			return loggerList;
		}
		set
		{
			loggerList = value;
		}
	}

	public ReportGenerator()
		: this(null)
	{
	}

	public ReportGenerator(string pluginFolderPath)
	{
		pluginManager.LoadPlugins(pluginFolderPath);
		pluginManager.InitializePlugins();
		pluginManager.SetLogger(WriteLog);
	}

	private void WriteLog(string message, LogType logType)
	{
		if (loggerList.Count > 0)
		{
			for (int i = 0; i < loggerList.Count; i++)
			{
				loggerList[i].WriteLog(message, logType);
			}
		}
	}

	public void LoadDescriptor(List<string> filePathsList)
	{
		foreach (string filePaths in filePathsList)
		{
			AddFormatDescriptor(filePaths);
		}
	}

	public void LoadDescriptor(string filePath)
	{
		AddFormatDescriptor(filePath);
	}

	public void ReloadFormatDescriptor(FormatDescriptor formatDescriptor, string technology)
	{
		if (techToFormatDescMapping != null && techToFormatDescMapping.ContainsKey(technology))
		{
			techToFormatDescMapping[""] = new FormatDescriptorCollection();
			techToFormatDescMapping[""].FormatDescriptors.Add(formatDescriptor);
		}
	}

	public FormatDescriptor CreateDynamicFormatDescriptor(string xAxis, string yAxis, string testId, string chartTitle, string zAxis = "", Dictionary<string, string> aggressorsNextDimension = null, string chartType = "")
	{
		FormatDescriptor formatDescriptor = new FormatDescriptor();
		formatDescriptor.OutputGroupSet = new ObservableCollection<OutputGroupSetDescriptor>();
		OutputGroupSetDescriptor outputGroupSetDescriptor = new OutputGroupSetDescriptor();
		if (chartType == "MultiDimension")
		{
			outputGroupSetDescriptor.CreateNewMultiDimensionChart(xAxis, yAxis, zAxis, testId, chartTitle);
			outputGroupSetDescriptor.GroupSetDescCollection[0].Discriminator1 = new ObservableCollection<Discriminator>();
			if (aggressorsNextDimension != null && aggressorsNextDimension.Count > 0)
			{
				Discriminator discriminator = new Discriminator();
				for (int i = 0; i < aggressorsNextDimension.Count(); i++)
				{
					switch (i)
					{
					case 0:
						discriminator.id = aggressorsNextDimension.ElementAt(i).Key;
						break;
					case 1:
						discriminator.Discriminator1 = new ObservableCollection<Discriminator>();
						discriminator.Discriminator1.Add(new Discriminator
						{
							id = aggressorsNextDimension.ElementAt(i).Key
						});
						break;
					case 2:
						discriminator.Discriminator1[0].Discriminator1 = new ObservableCollection<Discriminator>();
						discriminator.Discriminator1[0].Discriminator1.Add(new Discriminator
						{
							id = aggressorsNextDimension.ElementAt(i).Key
						});
						break;
					case 3:
						discriminator.Discriminator1[0].Discriminator1[0].Discriminator1 = new ObservableCollection<Discriminator>();
						discriminator.Discriminator1[0].Discriminator1[0].Discriminator1.Add(new Discriminator
						{
							id = aggressorsNextDimension.ElementAt(i).Key
						});
						break;
					case 4:
						discriminator.Discriminator1[0].Discriminator1[0].Discriminator1[0].Discriminator1 = new ObservableCollection<Discriminator>();
						discriminator.Discriminator1[0].Discriminator1[0].Discriminator1[0].Discriminator1.Add(new Discriminator
						{
							id = aggressorsNextDimension.ElementAt(i).Key
						});
						break;
					case 5:
						discriminator.Discriminator1[0].Discriminator1[0].Discriminator1[0].Discriminator1[0].Discriminator1 = new ObservableCollection<Discriminator>();
						discriminator.Discriminator1[0].Discriminator1[0].Discriminator1[0].Discriminator1[0].Discriminator1.Add(new Discriminator
						{
							id = aggressorsNextDimension.ElementAt(i).Key
						});
						break;
					}
				}
				outputGroupSetDescriptor.GroupSetDescCollection[0].Discriminator1.Add(discriminator);
			}
			formatDescriptor.OutputGroupSet.Add(outputGroupSetDescriptor);
		}
		return formatDescriptor;
	}

	public void LoadDescriptor(FormatDescriptor fd)
	{
		if (!string.IsNullOrEmpty(fd.FilePath))
		{
			fd.FilePath = string.Empty;
		}
		AddFormatDescriptor(fd);
	}

	public void SetInputFormat(string inputFormatType)
	{
		selectedInputPluginName = inputFormatType;
	}

	public void LoadSourceData(QueryFilter[] queryFilterArray)
	{
		LoadSourceData(null, isGetAllParams: false, queryFilterArray);
	}

	public void LoadSourceData(Dictionary<string, object[][]> sourceData)
	{
		if (sourceData != null && sourceData.Count > 0)
		{
			selectedInputPluginName = "GenericDataInputPlugin";
			InputPlugin inputPlugin2 = null;
			inputPlugin2 = pluginManager.InputPluginsList.Find((InputPlugin inputPlugin) => inputPlugin.PluginName == selectedInputPluginName);
			if (inputPlugin2 != null)
			{
				if (techToFormatDescMapping.ContainsKey(""))
				{
					FormatDescriptorCollection formatDescColl = techToFormatDescMapping[""];
					LimitDescriptorCollection limitDescColl = ((!techToLimitDescMapping.ContainsKey("")) ? null : techToLimitDescMapping[""]);
					ApplyPrefixGrouping();
					inputPlugin2.ReportSettingsInfo = ReportSettingsInfo;
					techToInputDataMapping[""] = inputPlugin2.GetInputData(sourceData, formatDescColl, limitDescColl);
				}
				else
				{
					WriteLog("No format descriptor loaded to process source data", LogType.Error);
				}
			}
			else
			{
				WriteLog("No input plugin loaded to parse source data", LogType.Error);
			}
		}
		else
		{
			WriteLog("Source data provided is empty", LogType.Error);
		}
	}

	public void LoadSourceData(FileSystemItemsGroupingCollection fileGroupingColl, bool isGetAllParams = false, QueryFilter[] queryDetails = null)
	{
		InputPlugin inputPlugin2 = null;
		FormatDescriptor formatDescriptor = new FormatDescriptor();
		LimitDefinition limitDescriptor = new LimitDefinition();
		List<Tuple<string, List<string>>> dataGrpColl = null;
		inputPlugin2 = ((!string.IsNullOrEmpty(selectedInputPluginName)) ? pluginManager.InputPluginsList.Find((InputPlugin inputPlugin) => inputPlugin.PluginName == selectedInputPluginName) : pluginManager.InputPluginsList.Find((InputPlugin inputPlugin) => inputPlugin.CanParseData(fileGroupingColl)));
		if (inputPlugin2 != null)
		{
			if (inputPlugin2 is ConnectionBasedInputPlugin)
			{
				inputPlugin2.Intialize(queryDetails, ref reportSettingsInfo, ref formatDescriptor, ref limitDescriptor, ref dataGrpColl);
				if (formatDescriptor != null)
				{
					techToFormatDescMapping.Add("", new FormatDescriptorCollection
					{
						FormatDescriptors = new List<FormatDescriptor> { formatDescriptor }
					});
				}
				if (limitDescriptor != null)
				{
					techToLimitDescMapping.Add("", new LimitDescriptorCollection
					{
						LimitDescriptors = new List<LimitDefinition> { limitDescriptor }
					});
				}
			}
			if (ReportSettingsInfo.AutoFormatDescriptor || ReportSettingsInfo.AutoLimitDescriptor)
			{
				WriteLog("Grabbing descriptors automatically", LogType.Status);
				Dictionary<string, string> fileGroupInformation = fileGroupingColl.GetFileGroupInformation();
				Dictionary<string, FileSystemItemsGroupingCollection> dictionary = new Dictionary<string, FileSystemItemsGroupingCollection>(StringComparer.Ordinal);
				AutoDescriptorPlugin selectedAutoDescriptorPlugin = GetSelectedAutoDescriptorPlugin();
				bool failureAnalysisEnabled = ((ReportSettingsInfo.FailureAnalysis || ReportSettingsInfo.AllFailureAnalysis) ? true : false);
				HashSet<string> hashSet = new HashSet<string>();
				if (selectedAutoDescriptorPlugin != null)
				{
					foreach (KeyValuePair<string, string> fileGroupInfoPair in fileGroupInformation)
					{
						InputPlugin inputPlugin3 = inputPlugin2;
						KeyValuePair<string, string> keyValuePair = fileGroupInfoPair;
						List<string> dllNames = inputPlugin3.GetDllNames(keyValuePair.Key);
						string text = null;
						if (dllNames != null && dllNames.Count > 0)
						{
							text = dllNames[0];
							Dictionary<string, Tuple<string, string>> dictionary2 = new Dictionary<string, Tuple<string, string>>();
							string condition = text;
							KeyValuePair<string, string> keyValuePair2 = fileGroupInfoPair;
							dictionary2 = selectedAutoDescriptorPlugin.GetAutoDescriptor(condition, keyValuePair2.Key, inputPlugin2.GetTestNames, failureAnalysisEnabled);
							if (dictionary2 == null || dictionary2.Count <= 0)
							{
								continue;
							}
							foreach (KeyValuePair<string, Tuple<string, string>> item in dictionary2)
							{
								if (hashSet.Contains(item.Key))
								{
									continue;
								}
								hashSet.Add(item.Key);
								if (techToFormatDescMapping.ContainsKey(""))
								{
									WriteLog("Using user specified format descriptor for technology: " + item.Key, LogType.Verbose);
									techToFormatDescMapping[item.Key] = techToFormatDescMapping[""];
								}
								else if (!techToFormatDescMapping.ContainsKey(item.Key) && AddFormatDescriptor(item.Value.Item1, item.Key))
								{
									WriteLog($"Grabbed descriptor: {item.Value.Item1} for technology: {item.Key}", LogType.Verbose);
								}
								if (ReportSettingsInfo.AutoLimitDescriptor)
								{
									if (techToLimitDescMapping.ContainsKey(""))
									{
										WriteLog("Using user specified limit descriptor", LogType.Verbose);
										techToLimitDescMapping[item.Key] = techToLimitDescMapping[""];
									}
									else if (!techToLimitDescMapping.ContainsKey(item.Key) && AddLimitDescriptor(item.Value.Item2, item.Key))
									{
										WriteLog($"Grabbed Limit descriptor: {item.Value.Item2} for technology: {item.Key}", LogType.Verbose);
									}
								}
							}
							foreach (string key in dictionary2.Keys)
							{
								if (dictionary.ContainsKey(key))
								{
									FileSystemItemsGroupingCollection fileSystemItemsGroupingCollection = dictionary[key];
									FileSystemItemsGroup fileSystemItemsGroup = fileSystemItemsGroupingCollection.FileSystemItemsGroupList.Find(delegate(FileSystemItemsGroup group)
									{
										string groupName = group.GroupName;
										KeyValuePair<string, string> keyValuePair8 = fileGroupInfoPair;
										return groupName == keyValuePair8.Value;
									});
									if (fileSystemItemsGroup != null)
									{
										List<FileSystemItem> fileSystemItemsList = fileSystemItemsGroup.FileSystemItemsList;
										FileSystemItem fileSystemItem = new FileSystemItem();
										KeyValuePair<string, string> keyValuePair3 = fileGroupInfoPair;
										fileSystemItem.FullPath = keyValuePair3.Key;
										fileSystemItemsList.Add(fileSystemItem);
										continue;
									}
									FileSystemItemsGroup fileSystemItemsGroup2 = new FileSystemItemsGroup();
									KeyValuePair<string, string> keyValuePair4 = fileGroupInfoPair;
									fileSystemItemsGroup2.GroupName = keyValuePair4.Value;
									FileSystemItemsGroup fileSystemItemsGroup3 = fileSystemItemsGroup2;
									List<FileSystemItem> fileSystemItemsList2 = fileSystemItemsGroup3.FileSystemItemsList;
									FileSystemItem fileSystemItem2 = new FileSystemItem();
									KeyValuePair<string, string> keyValuePair5 = fileGroupInfoPair;
									fileSystemItem2.FullPath = keyValuePair5.Key;
									fileSystemItemsList2.Add(fileSystemItem2);
									fileSystemItemsGroupingCollection.FileSystemItemsGroupList.Add(fileSystemItemsGroup3);
								}
								else
								{
									FileSystemItemsGroupingCollection fileSystemItemsGroupingCollection2 = new FileSystemItemsGroupingCollection();
									FileSystemItemsGroup fileSystemItemsGroup4 = new FileSystemItemsGroup();
									KeyValuePair<string, string> keyValuePair6 = fileGroupInfoPair;
									fileSystemItemsGroup4.GroupName = keyValuePair6.Value;
									FileSystemItemsGroup fileSystemItemsGroup5 = fileSystemItemsGroup4;
									List<FileSystemItem> fileSystemItemsList3 = fileSystemItemsGroup5.FileSystemItemsList;
									FileSystemItem fileSystemItem3 = new FileSystemItem();
									KeyValuePair<string, string> keyValuePair7 = fileGroupInfoPair;
									fileSystemItem3.FullPath = keyValuePair7.Key;
									fileSystemItemsList3.Add(fileSystemItem3);
									fileSystemItemsGroupingCollection2.FileSystemItemsGroupList.Add(fileSystemItemsGroup5);
									dictionary.Add(key, fileSystemItemsGroupingCollection2);
								}
							}
						}
						else
						{
							WriteLog("No QSPR dllname found in given data file. Auto format descriptor works only when QSPR dllNames are present", LogType.Warning);
						}
					}
					{
						foreach (KeyValuePair<string, FileSystemItemsGroupingCollection> item2 in dictionary)
						{
							LimitDescriptorCollection limitDescColl = ((reportSettingsInfo.AutoLimitDescriptor && techToLimitDescMapping.ContainsKey(item2.Key)) ? techToLimitDescMapping[item2.Key] : ((!techToLimitDescMapping.ContainsKey("")) ? null : techToLimitDescMapping[""]));
							if (techToFormatDescMapping.ContainsKey(item2.Key))
							{
								FormatDescriptorCollection formatDescColl = techToFormatDescMapping[item2.Key];
								ApplyGrouping(item2.Key, fileGroupingColl);
								ApplyPrefixGrouping(item2.Key);
								inputPlugin2.ReportSettingsInfo = ReportSettingsInfo;
								techToInputDataMapping[item2.Key] = inputPlugin2.GetInputData(item2.Value, formatDescColl, limitDescColl, isGetAllParams);
							}
						}
						return;
					}
				}
				WriteLog("No auto descriptor plugins loaded", LogType.Error);
			}
			else if (techToFormatDescMapping.ContainsKey(""))
			{
				FormatDescriptorCollection formatDescColl2 = techToFormatDescMapping[""];
				LimitDescriptorCollection limitDescColl2 = ((!techToLimitDescMapping.ContainsKey("")) ? null : techToLimitDescMapping[""]);
				if (fileGroupingColl != null)
				{
					ApplyGrouping("", fileGroupingColl);
				}
				else
				{
					ApplyDataGrouping("", dataGrpColl);
				}
				ApplyPrefixGrouping();
				inputPlugin2.ReportSettingsInfo = ReportSettingsInfo;
				techToInputDataMapping[""] = inputPlugin2.GetInputData(fileGroupingColl, formatDescColl2, limitDescColl2, isGetAllParams);
			}
			else
			{
				WriteLog("No format descriptor loaded to process source data", LogType.Error);
			}
		}
		else
		{
			WriteLog("No input plugin loaded to parse source data", LogType.Error);
		}
	}

	public void LoadSourceData(InputData inputData)
	{
		if (inputData != null)
		{
			ApplyPrefixGrouping();
			techToInputDataMapping[""] = inputData;
		}
	}

	private void ApplyPrefixGrouping(string technology = "")
	{
		if (techToFormatDescMapping.ContainsKey(technology))
		{
			techToFormatDescMapping[technology].FormatDescriptors.ForEach(delegate(FormatDescriptor fd)
			{
				fd.ApplyPrefixGrouping(reportSettingsInfo);
			});
		}
	}

	public void LoadSourceData(List<string> filePathsList)
	{
		FileSystemItemsGroupingCollection fileGroupingColl = FileSystemItemsGroupingCollection.CreateDefaultGroupCollection(filePathsList);
		LoadSourceData(fileGroupingColl);
	}

	public void LoadLimitDescriptor(string limitFilePath)
	{
		AddLimitDescriptor(limitFilePath);
	}

	public LimitDefinition GetLimitDefinitionDataStructure(string limitFilePath)
	{
		LimitDefinition result = new LimitDefinition();
		if (AddLimitDescriptor(limitFilePath))
		{
			LimitDescriptorCollection limitDescriptorCollection = techToLimitDescMapping[""];
			if (limitDescriptorCollection != null && limitDescriptorCollection.LimitDescriptors != null && limitDescriptorCollection.LimitDescriptors.Count > 0)
			{
				result = limitDescriptorCollection.LimitDescriptors[0];
			}
		}
		return result;
	}

	public InputData GetLimitDescriptorAppliedInputData()
	{
		InputData inputData = new InputData();
		LimitDefinition limitDefinition = new LimitDefinition();
		LimitDescriptorCollection limitDescriptorCollection = techToLimitDescMapping[""];
		if (limitDescriptorCollection != null && limitDescriptorCollection.LimitDescriptors != null && limitDescriptorCollection.LimitDescriptors.Count > 0)
		{
			limitDefinition = limitDescriptorCollection.LimitDescriptors[0];
		}
		if (techToInputDataMapping != null)
		{
			inputData = techToInputDataMapping[""];
			if (inputData != null && limitDefinition != null)
			{
				ApplyLimitDescriptorToInputData(inputData);
			}
		}
		return inputData;
	}

	public List<LimitGroupType> GetAllLimitDescriptorGroupType()
	{
		List<LimitGroupType> result = new List<LimitGroupType>();
		LimitDefinition limitDefinition = new LimitDefinition();
		LimitDescriptorCollection limitDescriptorCollection = techToLimitDescMapping[""];
		if (limitDescriptorCollection != null && limitDescriptorCollection.LimitDescriptors != null && limitDescriptorCollection.LimitDescriptors.Count > 0)
		{
			limitDefinition = limitDescriptorCollection.LimitDescriptors[0];
		}
		if (limitDefinition != null)
		{
			result = limitDefinition.LimitGroupList.ToList();
		}
		return result;
	}

	public void ApplyLimitDescriptorToInputData(InputData inputData)
	{
		LimitDescriptorCollection limitDescriptorCollection = techToLimitDescMapping[""];
		if (limitDescriptorCollection != null && limitDescriptorCollection.LimitDescriptors != null && limitDescriptorCollection.LimitDescriptors.Count > 0 && inputData != null)
		{
			ApplyLimitDescriptors(inputData, limitDescriptorCollection);
		}
	}

	public void LoadAndApplyLimitDescToInputData(InputData inputData, LimitDefinition limitDataStructure)
	{
		AddLimitDescriptor(limitDataStructure);
		LimitDescriptorCollection limitDescriptorCollection = techToLimitDescMapping[""];
		if (inputData != null && limitDescriptorCollection != null && limitDescriptorCollection.LimitDescriptors != null && limitDescriptorCollection.LimitDescriptors.Count > 0)
		{
			ApplyLimitDescriptors(inputData, limitDescriptorCollection);
		}
	}

	public void LoadAndApplyLimitDescToInputData(InputData inputData, string limitFilePath)
	{
		LoadLimitDescriptor(limitFilePath);
		LimitDescriptorCollection limitDescriptorCollection = techToLimitDescMapping[""];
		if (inputData != null && limitDescriptorCollection != null && limitDescriptorCollection.LimitDescriptors != null && limitDescriptorCollection.LimitDescriptors.Count > 0)
		{
			ApplyLimitDescriptors(inputData, limitDescriptorCollection);
		}
	}

	public void EnableChartTypes(List<string> chartTypesToEnable)
	{
		enabledCharts = chartTypesToEnable;
	}

	public Dictionary<string, DescriptorAppliedData> GenerateOutputData(bool isCallerDataminer = false)
	{
		Dictionary<string, DescriptorAppliedData> dictionary = new Dictionary<string, DescriptorAppliedData>();
		foreach (KeyValuePair<string, InputData> item in techToInputDataMapping)
		{
			if (item.Key != "")
			{
				WriteLog($"Generating outputdata for technology: {item.Key}", LogType.Verbose);
			}
			if (!techToFormatDescMapping.ContainsKey(item.Key))
			{
				continue;
			}
			InputData value = item.Value;
			FormatDescriptorCollection formatDescColl = techToFormatDescMapping[item.Key];
			LimitDescriptorCollection limitDescriptorCollection = ((reportSettingsInfo.AutoLimitDescriptor && techToLimitDescMapping.ContainsKey(item.Key)) ? techToLimitDescMapping[item.Key] : ((!techToLimitDescMapping.ContainsKey("")) ? null : techToLimitDescMapping[""]));
			DescriptorAppliedData descriptorAppliedData = null;
			if (value.TestInfoDict.Count > 0)
			{
				if (limitDescriptorCollection != null && limitDescriptorCollection.LimitDescriptors != null && limitDescriptorCollection.LimitDescriptors.Count > 0)
				{
					ApplyLimitDescriptors(value, limitDescriptorCollection);
				}
				QC.CTDS.DM.DataProcessor.DataProcessor dataProcessor = new QC.CTDS.DM.DataProcessor.DataProcessor();
				dataProcessor.OnWriteLog = WriteLog;
				dataProcessor.EnabledCharts = enabledCharts;
				descriptorAppliedData = dataProcessor.TransformData(value, ReportSettingsInfo, formatDescColl);
				if (descriptorAppliedData != null && descriptorAppliedData.OutputGroupSetList.Count > 0)
				{
					descriptorAppliedData.ReportEnviornment = ReportEnviornment;
					descriptorAppliedData.HiddenReportCommandForReprocessing = HiddenReportCommandForReprocessing;
					descriptorAppliedData.FormatDescriptorContent = preGroupingAppliedFormatDescString;
					descriptorAppliedData.Version = ServicePluginVersion;
					if (isCallerDataminer)
					{
						Task.Factory.StartNew(delegate
						{
							CleanUp();
						});
					}
				}
				else
				{
					WriteLog("Data files don't contain data for selected format descriptor charts", LogType.Error);
				}
			}
			else
			{
				WriteLog("No matching source data found for the provided format descriptor", LogType.Error);
			}
			dictionary[item.Key] = descriptorAppliedData;
		}
		return dictionary;
	}

	public Dictionary<string, DescriptorAppliedData> GenerateOutputDataAfterPluginProcessing(string outputType)
	{
		Dictionary<string, DescriptorAppliedData> dictionary = GenerateOutputData();
		OutputPlugin outputPlugin = pluginManager.OutputPluginsList.Find((OutputPlugin w) => w.PluginName == outputType);
		if (outputPlugin != null)
		{
			foreach (KeyValuePair<string, DescriptorAppliedData> item in dictionary)
			{
				outputPlugin.GenerateOutputDataAfterPluginProcessing(item.Value, ReportSettingsInfo);
			}
		}
		return dictionary;
	}

	public void GenerateReport(string outputType, string outputFilePath, bool IsCallerDataminer = false)
	{
		if (!string.IsNullOrEmpty(outputType))
		{
			OutputPlugin outputPlugin = pluginManager.OutputPluginsList.Find((OutputPlugin w) => w.PluginName == outputType);
			if (outputPlugin != null)
			{
				if (techToInputDataMapping.Count > 0)
				{
					foreach (KeyValuePair<string, InputData> techToInputDataPair in techToInputDataMapping)
					{
						Dictionary<string, FormatDescriptorCollection> dictionary = techToFormatDescMapping;
						KeyValuePair<string, InputData> keyValuePair = techToInputDataPair;
						if (!dictionary.ContainsKey(keyValuePair.Key))
						{
							WriteLog("No matching format descriptor found", LogType.Error);
							continue;
						}
						KeyValuePair<string, InputData> keyValuePair2 = techToInputDataPair;
						if (keyValuePair2.Key != "")
						{
							KeyValuePair<string, InputData> keyValuePair3 = techToInputDataPair;
							WriteLog($"Generating report for technology: {keyValuePair3.Key}", LogType.Verbose);
						}
						Dictionary<string, FormatDescriptorCollection> dictionary2 = techToFormatDescMapping;
						KeyValuePair<string, InputData> keyValuePair4 = techToInputDataPair;
						FormatDescriptorCollection formatDescColl = dictionary2[keyValuePair4.Key];
						LimitDescriptorCollection limitDescriptorCollection;
						if (reportSettingsInfo.AutoLimitDescriptor)
						{
							Dictionary<string, LimitDescriptorCollection> dictionary3 = techToLimitDescMapping;
							KeyValuePair<string, InputData> keyValuePair5 = techToInputDataPair;
							if (dictionary3.ContainsKey(keyValuePair5.Key))
							{
								Dictionary<string, LimitDescriptorCollection> dictionary4 = techToLimitDescMapping;
								KeyValuePair<string, InputData> keyValuePair6 = techToInputDataPair;
								limitDescriptorCollection = dictionary4[keyValuePair6.Key];
								goto IL_0183;
							}
						}
						limitDescriptorCollection = ((!techToLimitDescMapping.ContainsKey("")) ? null : techToLimitDescMapping[""]);
						goto IL_0183;
						IL_0183:
						KeyValuePair<string, InputData> keyValuePair7 = techToInputDataPair;
						InputData inputData = keyValuePair7.Value;
						if (!string.IsNullOrEmpty(reportSettingsInfo.PreTransformExpressions))
						{
							PreDataTransformationPlugin preDataTransformationPlugin = LoadSelectedPreTransformationPlugin();
							if (preDataTransformationPlugin != null)
							{
								inputData = preDataTransformationPlugin.ApplyPreTransformCalculations(inputData, reportSettingsInfo.PreTransformExpressions);
							}
							else
							{
								WriteLog("There was an error loading pre data transform plugin", LogType.Error);
							}
						}
						if (inputData != null && inputData.TestInfoDict.Count > 0)
						{
							if (limitDescriptorCollection != null && limitDescriptorCollection.LimitDescriptors != null && limitDescriptorCollection.LimitDescriptors.Count > 0)
							{
								ApplyLimitDescriptors(inputData, limitDescriptorCollection);
							}
							QC.CTDS.DM.DataProcessor.DataProcessor dataProcessor = new QC.CTDS.DM.DataProcessor.DataProcessor();
							dataProcessor.OnWriteLog = WriteLog;
							dataProcessor.EnabledCharts = enabledCharts;
							DescriptorAppliedData descriptorAppliedData = dataProcessor.TransformData(inputData, ReportSettingsInfo, formatDescColl);
							if (descriptorAppliedData != null && descriptorAppliedData.OutputGroupSetList.Count > 0)
							{
								descriptorAppliedData.ReportEnviornment = ReportEnviornment;
								descriptorAppliedData.HiddenReportCommandForReprocessing = HiddenReportCommandForReprocessing;
								descriptorAppliedData.Version = ServicePluginVersion;
								descriptorAppliedData.FormatDescriptorContent = preGroupingAppliedFormatDescString;
								if (IsCallerDataminer)
								{
									Task.Factory.StartNew(delegate
									{
										ReportGenerator reportGenerator = this;
										KeyValuePair<string, InputData> keyValuePair10 = techToInputDataPair;
										reportGenerator.CleanUp(keyValuePair10.Key);
									});
								}
								KeyValuePair<string, InputData> keyValuePair8 = techToInputDataPair;
								if (keyValuePair8.Key == "")
								{
									outputPlugin.OutputPath = outputFilePath;
								}
								else if (!string.IsNullOrEmpty(outputFilePath))
								{
									KeyValuePair<string, InputData> keyValuePair9 = techToInputDataPair;
									outputPlugin.OutputPath = AddTechToOutputFile(keyValuePair9.Key, outputFilePath);
								}
								else
								{
									outputPlugin.OutputPath = null;
								}
								outputPlugin.GenerateReport(descriptorAppliedData, ReportSettingsInfo);
							}
							else
							{
								WriteLog("Data files don't contain data for selected format descriptor charts", LogType.Error);
							}
						}
						else
						{
							WriteLog("No matching source data found for the provided format descriptor", LogType.Error);
						}
					}
					return;
				}
				WriteLog("No technology to input mapping found nothing to process", LogType.Warning);
			}
			else
			{
				WriteLog("No matching filtered plugin found", LogType.Error);
			}
		}
		else
		{
			WriteLog("No outputtype specified", LogType.Error);
		}
	}

	private string AddTechToOutputFile(string technology, string outputFilePath)
	{
		string text = Path.GetFileNameWithoutExtension(outputFilePath) + technology;
		return Path.Combine(Path.GetDirectoryName(outputFilePath), text + Path.GetExtension(outputFilePath));
	}

	public Dictionary<string, Tuple<double, double>> GetCustomLimits(string testName, Dictionary<string, ParamInfo> inputParams, List<string> outputParamNames, string limitIndex)
	{
		Dictionary<string, Tuple<double, double>> dictionary = new Dictionary<string, Tuple<double, double>>();
		if (techToLimitDescMapping.ContainsKey(""))
		{
			TestRunInfo testRunInfo = new TestRunInfo();
			testRunInfo.TestName = testName;
			testRunInfo.ParamsDict.Merge(inputParams);
			foreach (string outputParamName in outputParamNames)
			{
				testRunInfo.ParamsDict[outputParamName] = new OutputParamInfo();
			}
			TestInfo testInfo = new TestInfo();
			testInfo.TestName = testName;
			testInfo.TestRunsList.Add(testRunInfo);
			InputData inputData = new InputData();
			inputData.TestInfoDict.Add(testName, testInfo);
			ApplyLimitDescriptors(inputData, techToLimitDescMapping[""]);
			foreach (string outputParamName2 in outputParamNames)
			{
				if (!(testRunInfo.ParamsDict[outputParamName2] is OutputParamInfo { CustomLimits: not null } outputParamInfo))
				{
					continue;
				}
				double result = double.NaN;
				double result2 = double.NaN;
				if (outputParamInfo.CustomLimits.HighLimit != null && outputParamInfo.CustomLimits.HighLimit.Count > 0)
				{
					Limit limit = outputParamInfo.CustomLimits.HighLimit.FirstOrDefault((Limit lim) => lim.Index == limitIndex);
					if (limit != null)
					{
						double.TryParse(limit.Val, out result2);
					}
				}
				if (outputParamInfo.CustomLimits.LowLimit != null && outputParamInfo.CustomLimits.LowLimit.Count > 0)
				{
					Limit limit2 = outputParamInfo.CustomLimits.LowLimit.FirstOrDefault((Limit lim) => lim.Index == limitIndex);
					if (limit2 != null)
					{
						double.TryParse(limit2.Val, out result);
					}
				}
				dictionary[outputParamName2] = new Tuple<double, double>(result, result2);
			}
		}
		return dictionary;
	}

	private void ApplyLimitDescriptors(InputData inputData, LimitDescriptorCollection ldColl)
	{
		Stopwatch stopwatch = new Stopwatch();
		stopwatch.Start();
		WriteLog("Processing Limit Descriptors: ", LogType.Status);
		if (ldColl != null && ldColl.LimitDescriptors != null && ldColl.LimitDescriptors.Count > 0)
		{
			LimitDefinition ld = ldColl.LimitDescriptors[0];
			reportSettingsInfo.CustomLimitTypes = ld.LimitGroupList.ToList();
			GetLimitDescriptorType();
			List<TestRunInfo> matchingTestRuns = new List<TestRunInfo>();
			List<DiscGroup>[] discGroupArray = new List<DiscGroup>[ld.OutputGroupLimitDescriptorSet.Count];
			List<OutputGroupLimitDescriptorResult>[] outputResult = new List<OutputGroupLimitDescriptorResult>[ld.OutputGroupLimitDescriptorSet.Count];
			CommonFunctions.RunLoop(reportSettingsInfo.RunInSequentialMode, 0, ld.OutputGroupLimitDescriptorSet.Count, delegate(int i)
			{
				matchingTestRuns = DataProcessorUtils.GetTestFilteredSourceData(ld.OutputGroupLimitDescriptorSet[i].Result, inputData);
				List<DiscGroup> filteredSourceData = DataProcessorUtils.GetFilteredSourceData(new DiscriminatorElement
				{
					Filter = ld.OutputGroupLimitDescriptorSet[i].Filter
				}, matchingTestRuns);
				List<TestRunInfo> resultSetRuns = new List<TestRunInfo>();
				filteredSourceData.ForEach(delegate(DiscGroup d)
				{
					resultSetRuns.AddRange(d.TestItems);
				});
				discGroupArray[i] = new List<DiscGroup>();
				outputResult[i] = new List<OutputGroupLimitDescriptorResult>();
				for (int m = 0; m < ld.OutputGroupLimitDescriptorSet[i].Result.Count; m++)
				{
					List<DiscGroup> filteredSourceData2 = DataProcessorUtils.GetFilteredSourceData(new DiscriminatorElement
					{
						Filter = ld.OutputGroupLimitDescriptorSet[i].Result[m].Filter
					}, resultSetRuns);
					if (filteredSourceData2 != null && filteredSourceData2.Count > 0)
					{
						discGroupArray[i].AddRange(filteredSourceData2);
						outputResult[i].Add(ld.OutputGroupLimitDescriptorSet[i].Result[m]);
					}
				}
			});
			if (discGroupArray != null && discGroupArray.Count() > 0)
			{
				for (int j = 0; j < discGroupArray.Count(); j++)
				{
					if (discGroupArray[j] == null || discGroupArray[j].Count <= 0)
					{
						continue;
					}
					for (int k = 0; k < discGroupArray[j].Count; k++)
					{
						if (discGroupArray[j][k].TestItems == null || discGroupArray[j][k].TestItems.Count <= 0)
						{
							continue;
						}
						for (int l = 0; l < discGroupArray[j][k].TestItems.Count; l++)
						{
							if (discGroupArray[j][k].TestItems[l].ContainsParam(outputResult[j][k].resID) && discGroupArray[j][k].TestItems[l].TestName == outputResult[j][k].testID && discGroupArray[j][k].TestItems[l].GetParamValue(outputResult[j][k].resID) is OutputParamInfo)
							{
								OutputParamInfo outputParamInfo = (OutputParamInfo)discGroupArray[j][k].TestItems[l].GetParamValue(outputResult[j][k].resID);
								if (reportSettingsInfo.CustomLimitTypes.Count != ld.LimitGroupList.Count())
								{
									FilterLimitsAsPerLimitTypes(outputResult[j][k].Limits);
								}
								outputParamInfo.CustomLimits = outputResult[j][k].Limits;
							}
						}
					}
				}
			}
		}
		stopwatch.Stop();
		WriteLog("Time taken to process Limit Descriptors: " + stopwatch.Elapsed.ToString(), LogType.Status);
	}

	private void CleanUp(string technology = "")
	{
		if (techToInputDataMapping.ContainsKey(technology))
		{
			techToInputDataMapping[technology].Clear();
		}
		if (techToFormatDescMapping.ContainsKey(technology))
		{
			techToFormatDescMapping[technology].Clear();
		}
		GC.Collect();
	}

	private bool AddFormatDescriptor(string filePath, string technology = "")
	{
		bool result = false;
		try
		{
			FormatDescriptor formatDescriptor = FormatDescriptor.ReadFormatDescriptor(filePath);
			if (formatDescriptor != null)
			{
				AddFormatDescriptor(formatDescriptor, technology);
				result = true;
			}
		}
		catch (Exception ex)
		{
			WriteLog(ex.Message, LogType.Verbose);
		}
		return result;
	}

	private void AddFormatDescriptor(FormatDescriptor fd, string technology = "")
	{
		if (techToFormatDescMapping.ContainsKey(technology))
		{
			FormatDescriptorCollection formatDescriptorCollection = techToFormatDescMapping[technology];
			if (!formatDescriptorCollection.FormatDescriptors.Contains(fd))
			{
				formatDescriptorCollection.FormatDescriptors.Add(fd);
			}
		}
		else
		{
			FormatDescriptorCollection formatDescriptorCollection2 = new FormatDescriptorCollection();
			formatDescriptorCollection2.FormatDescriptors.Add(fd);
			techToFormatDescMapping.Add(technology, formatDescriptorCollection2);
		}
	}

	private bool AddLimitDescriptor(string descFilePath, string technology = "")
	{
		bool result = false;
		try
		{
			LimitDefinition limitDefinition = LimitDefinition.ReadLimitDescriptor(descFilePath);
			if (limitDefinition != null)
			{
				AddLimitDescriptor(limitDefinition, technology);
				result = true;
			}
		}
		catch (Exception ex)
		{
			WriteLog(ex.Message, LogType.Verbose);
		}
		return result;
	}

	private void AddLimitDescriptor(LimitDefinition ld, string technology = "")
	{
		if (techToLimitDescMapping.ContainsKey(technology))
		{
			LimitDescriptorCollection limitDescriptorCollection = techToLimitDescMapping[technology];
			if (!limitDescriptorCollection.LimitDescriptors.Contains(ld))
			{
				limitDescriptorCollection.LimitDescriptors.Add(ld);
			}
		}
		else
		{
			LimitDescriptorCollection limitDescriptorCollection2 = new LimitDescriptorCollection();
			limitDescriptorCollection2.LimitDescriptors.Add(ld);
			techToLimitDescMapping.Add(technology, limitDescriptorCollection2);
		}
	}

	private void ApplyGrouping(string technology, FileSystemItemsGroupingCollection groupingCollection)
	{
		if (techToFormatDescMapping.ContainsKey(technology))
		{
			SavePreGroupingAppliedFD(techToFormatDescMapping[technology], technology);
			techToFormatDescMapping[technology].FormatDescriptors.ForEach(delegate(FormatDescriptor fd)
			{
				fd.ApplyFileGrouping(groupingCollection);
			});
		}
		if (techToLimitDescMapping.ContainsKey(technology))
		{
			techToLimitDescMapping[technology].LimitDescriptors.ForEach(delegate(LimitDefinition ld)
			{
				ld.ApplyFileGrouping(groupingCollection);
			});
		}
	}

	private void ApplyDataGrouping(string technology, List<Tuple<string, List<string>>> groupingCollection)
	{
		if (techToFormatDescMapping.ContainsKey(technology))
		{
			SavePreGroupingAppliedFD(techToFormatDescMapping[technology], technology);
			techToFormatDescMapping[technology].FormatDescriptors.ForEach(delegate(FormatDescriptor fd)
			{
				fd.ApplyDataGrouping(groupingCollection);
			});
		}
		if (techToLimitDescMapping.ContainsKey(technology))
		{
			techToLimitDescMapping[technology].LimitDescriptors.ForEach(delegate(LimitDefinition ld)
			{
				ld.ApplyDataGrouping(groupingCollection);
			});
		}
	}

	private void SavePreGroupingAppliedFD(FormatDescriptorCollection fdCollection, string technology)
	{
		if (fdCollection != null && fdCollection.FormatDescriptors != null && fdCollection.FormatDescriptors.Count > 0)
		{
			preGroupingAppliedFormatDescString = fdCollection.FormatDescriptors[0].GetFormatDescriptorString();
		}
	}

	private AutoDescriptorPlugin GetSelectedAutoDescriptorPlugin()
	{
		if (pluginManager.AutoDescriptorPluginsList.Count > 0)
		{
			AutoDescriptorPlugin autoDescriptorPlugin = pluginManager.AutoDescriptorPluginsList.Find((AutoDescriptorPlugin plugin) => plugin.CanUsePlugin());
			if (autoDescriptorPlugin != null)
			{
				return autoDescriptorPlugin;
			}
			return null;
		}
		return null;
	}

	public void LoadAutoSourceData()
	{
		if (!string.IsNullOrEmpty(ReportSettingsInfo.SonarSql))
		{
			AutoDescriptorPlugin selectedAutoDescriptorPlugin = GetSelectedAutoDescriptorPlugin();
			if (selectedAutoDescriptorPlugin != null)
			{
				WriteLog("Loading source data automatically", LogType.Verbose);
				List<string> dataFiles = selectedAutoDescriptorPlugin.GetDataFiles(ReportSettingsInfo.SonarSql);
				if (dataFiles.Count > 0)
				{
					LoadSourceData(dataFiles);
				}
			}
			else
			{
				WriteLog("No auto descriptor plugins loaded to load source data automatically", LogType.Error);
			}
		}
		else
		{
			WriteLog("No auto source sql specified", LogType.Verbose);
		}
	}

	public Dictionary<string, InputData> LoadSourceDataWithAllParameters(List<string> filePathsList)
	{
		FileSystemItemsGroupingCollection fileGroupingColl = FileSystemItemsGroupingCollection.CreateDefaultGroupCollection(filePathsList);
		LoadSourceData(fileGroupingColl, isGetAllParams: true);
		return techToInputDataMapping;
	}

	private void GetLimitDescriptorType()
	{
		try
		{
			if (string.IsNullOrEmpty(reportSettingsInfo.LimitTypes))
			{
				return;
			}
			string[] array = reportSettingsInfo.LimitTypes.Split(',');
			List<string> matchingLimitTypes = new List<string>();
			if (array == null || array.Count() <= 0)
			{
				return;
			}
			string[] array2 = array;
			foreach (string text in array2)
			{
				foreach (LimitGroupType customLimitType in reportSettingsInfo.CustomLimitTypes)
				{
					if (customLimitType.Name.Trim().Equals(text.Trim(), StringComparison.OrdinalIgnoreCase))
					{
						matchingLimitTypes.Add(customLimitType.Name);
					}
				}
			}
			List<LimitGroupType> list = reportSettingsInfo.CustomLimitTypes.FindAll((LimitGroupType cl) => matchingLimitTypes.Contains(cl.Name));
			if (list != null && list.Count > 0)
			{
				reportSettingsInfo.CustomLimitTypes = list;
			}
		}
		catch (Exception ex)
		{
			WriteLog("Error Parsing Limit types, please enter comma separated limit indicies(Eg.\"Func,Std\")" + ex.Message, LogType.Error);
		}
	}

	private void FilterLimitsAsPerLimitTypes(Limits outputResultLimits)
	{
		if (reportSettingsInfo.CustomLimitTypes == null || reportSettingsInfo.CustomLimitTypes.Count <= 0)
		{
			return;
		}
		IEnumerable<string> limitIndicies = reportSettingsInfo.CustomLimitTypes.Select((LimitGroupType lim) => lim.Index);
		if (limitIndicies == null || outputResultLimits == null)
		{
			return;
		}
		if (outputResultLimits.HighLimit != null && outputResultLimits.HighLimit.Count > 0)
		{
			IEnumerable<Limit> enumerable = outputResultLimits.HighLimit.Where((Limit hLim) => limitIndicies.Contains(hLim.Index));
			if (enumerable != null)
			{
				outputResultLimits.HighLimit = new ObservableCollection<Limit>();
				enumerable.ForEach(delegate(Limit highL)
				{
					outputResultLimits.HighLimit.Add(new Limit
					{
						Index = highL.Index,
						Val = highL.Val
					});
				});
			}
		}
		if (outputResultLimits.LowLimit == null || outputResultLimits.LowLimit.Count <= 0)
		{
			return;
		}
		IEnumerable<Limit> enumerable2 = outputResultLimits.LowLimit.Where((Limit lLim) => limitIndicies.Contains(lLim.Index));
		if (enumerable2 != null)
		{
			outputResultLimits.LowLimit = new ObservableCollection<Limit>();
			enumerable2.ForEach(delegate(Limit lowL)
			{
				outputResultLimits.LowLimit.Add(new Limit
				{
					Index = lowL.Index,
					Val = lowL.Val
				});
			});
		}
	}

	private PreDataTransformationPlugin LoadSelectedPreTransformationPlugin()
	{
		if (pluginManager.PreDatatransformationPluginList.Count > 0)
		{
			PreDataTransformationPlugin preDataTransformationPlugin = pluginManager.PreDatatransformationPluginList.Find((PreDataTransformationPlugin plugin) => plugin.CanUsePlugin(reportSettingsInfo.PreTransformExpressions));
			if (preDataTransformationPlugin != null)
			{
				return preDataTransformationPlugin;
			}
			return null;
		}
		return null;
	}
}
