using System;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Reflection;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Xml.Serialization;

namespace QC.CTDS.DM.SharedLibrary;

public static class CommonFunctions
{
	public interface IXmlSerializationCallback
	{
		void OnXmlDeserialization();
	}

	public enum SerializationTypes
	{
		Xml,
		Binary
	}

	public static void Serialize<T>(string filePath, T obj, SerializationTypes serialzationType = SerializationTypes.Xml) where T : class
	{
		using FileStream fileStream = new FileStream(filePath, FileMode.Create);
		switch (serialzationType)
		{
		case SerializationTypes.Xml:
		{
			XmlSerializer xmlSerializer = new XmlSerializer(obj.GetType());
			xmlSerializer.Serialize(fileStream, obj);
			break;
		}
		case SerializationTypes.Binary:
		{
			IFormatter formatter = new BinaryFormatter();
			formatter.Serialize(fileStream, obj);
			break;
		}
		}
		fileStream.Close();
	}

	public static T Deserialize<T>(string filePath, SerializationTypes serialzationType = SerializationTypes.Xml) where T : class
	{
		T val = null;
		if (File.Exists(filePath))
		{
			using FileStream fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read);
			object obj = null;
			switch (serialzationType)
			{
			case SerializationTypes.Xml:
			{
				XmlSerializer xmlSerializer = new XmlSerializer(typeof(T));
				obj = xmlSerializer.Deserialize(fileStream);
				break;
			}
			case SerializationTypes.Binary:
			{
				IFormatter formatter = new BinaryFormatter();
				obj = formatter.Deserialize(fileStream);
				break;
			}
			}
			fileStream.Close();
			val = obj as T;
			if (val != null && val is IXmlSerializationCallback xmlSerializationCallback)
			{
				xmlSerializationCallback.OnXmlDeserialization();
			}
		}
		return val;
	}

	public static object Deserialize(string filePath, Type dataType)
	{
		object obj = null;
		try
		{
			if (File.Exists(filePath))
			{
				using (StreamReader streamReader = new StreamReader(filePath))
				{
					XmlSerializer xmlSerializer = new XmlSerializer(dataType);
					obj = xmlSerializer.Deserialize(streamReader);
					streamReader.Close();
				}
				if (obj != null && obj is IXmlSerializationCallback xmlSerializationCallback)
				{
					xmlSerializationCallback.OnXmlDeserialization();
				}
			}
		}
		catch
		{
			obj = null;
		}
		return obj;
	}

	public static T DeserializeString<T>(string stringToDeserialize) where T : class
	{
		T val = null;
		using (StringReader stringReader = new StringReader(stringToDeserialize))
		{
			XmlSerializer xmlSerializer = new XmlSerializer(typeof(T));
			object obj = xmlSerializer.Deserialize(stringReader);
			stringReader.Close();
			val = obj as T;
			if (val != null && val is IXmlSerializationCallback xmlSerializationCallback)
			{
				xmlSerializationCallback.OnXmlDeserialization();
			}
		}
		return val;
	}

	public static string SerializeToString<T>(T obj) where T : class
	{
		string text = null;
		using StringWriter stringWriter = new StringWriter();
		XmlSerializer xmlSerializer = new XmlSerializer(typeof(T));
		xmlSerializer.Serialize(stringWriter, obj);
		stringWriter.Close();
		return stringWriter.ToString();
	}

	public static bool IsBaseConversionValid(string baseIndicator)
	{
		if (baseIndicator != "16" && baseIndicator != "2" && baseIndicator != "10" && baseIndicator != "8")
		{
			return false;
		}
		if (string.IsNullOrEmpty(baseIndicator))
		{
			return false;
		}
		return true;
	}

	public static bool HasText(string filePath, string text, int bufferSizeToSearch = 1024)
	{
		using StreamReader streamReader = new StreamReader(filePath);
		try
		{
			char[] array = new char[bufferSizeToSearch];
			streamReader.ReadBlock(array, 0, bufferSizeToSearch);
			string text2 = new string(array);
			if (text2.ToLower().Contains(text.ToLower()))
			{
				return true;
			}
			return false;
		}
		catch
		{
			return false;
		}
	}

	public static List<string> GetFiles(string dirPath, bool includeSubFolders, string filter)
	{
		if (includeSubFolders)
		{
			return (from file in new DirectoryInfo(dirPath).GetFiles(filter, SearchOption.AllDirectories)
				select file.FullName).ToList();
		}
		return (from file in new DirectoryInfo(dirPath).GetFiles(filter, SearchOption.TopDirectoryOnly)
			select file.FullName).ToList();
	}

	public static string GetTempOutputDirectoryPath()
	{
		string text = "QMine_Dir_Temp";
		string text2 = "c:\\Qualcomm\\QMine\\Temp";
		try
		{
			if (!Directory.Exists(text2))
			{
				Directory.CreateDirectory(text2);
			}
			int num = 0;
			string empty = string.Empty;
			int num2 = 1000;
			do
			{
				empty = Path.Combine(text2, text + "_" + num++);
			}
			while (Directory.Exists(empty) && num < num2);
			if (num >= num2)
			{
				throw new Exception("Number of temporary folders exceeded in data path: " + text2);
			}
			return empty;
		}
		catch (Exception)
		{
			return null;
		}
	}

	public static void MergeTables(DataTable table1, DataTable table2)
	{
		if (table2 == null || table2.Rows.Count <= 0)
		{
			return;
		}
		if (table1 == null)
		{
			table1 = new DataTable();
		}
		for (int i = 0; i < table2.Columns.Count; i++)
		{
			if (!table1.Columns.Contains(table2.Columns[i].ColumnName))
			{
				table1.Columns.Add(table2.Columns[i]);
			}
		}
		for (int j = 0; j < table2.Rows.Count; j++)
		{
			DataRow dataRow = table1.NewRow();
			for (int k = 0; k < table2.Columns.Count; k++)
			{
				dataRow[table2.Columns[k].ColumnName] = table2.Rows[j][k];
			}
			table1.Rows.Add(dataRow);
		}
	}

	public static double NormalDistribution(double x, double mean, double std, bool cumulative)
	{
		if (cumulative)
		{
			return Phi(x, mean, std);
		}
		double num = 1.0 / (Math.Sqrt(Math.PI * 2.0) * std);
		return num * Math.Exp(-0.5 * Math.Pow((x - mean) / std, 2.0));
	}

	private static double erf(double z)
	{
		double num = 1.0 / (1.0 + 0.5 * Math.Abs(z));
		double num2 = 1.0 - num * Math.Exp((0.0 - z) * z - 1.26551223 + num * (1.00002368 + num * (0.37409196 + num * (0.09678418 + num * (-0.18628806 + num * (0.27886807 + num * (-1.13520398 + num * (1.48851587 + num * (-0.82215223 + num * 0.17087277)))))))));
		if (z >= 0.0)
		{
			return num2;
		}
		return 0.0 - num2;
	}

	private static double Phi(double z)
	{
		return 0.5 * (1.0 + erf(z / Math.Sqrt(2.0)));
	}

	private static double Phi(double z, double mu, double sigma)
	{
		return Phi((z - mu) / sigma);
	}

	public static void RoundSmart(ref double minVal, ref double maxVal, bool forceRes, int maxResPwrOfTen)
	{
		if (double.IsNaN(minVal) || double.IsNaN(maxVal))
		{
			return;
		}
		minVal -= 0.1 * (maxVal - minVal);
		maxVal += 0.1 * (maxVal - minVal);
		if (forceRes)
		{
			double num = Math.Pow(10.0, maxResPwrOfTen);
			if (maxResPwrOfTen < 0)
			{
				minVal = RoundDouble(minVal - num / 1.000001, Math.Abs(maxResPwrOfTen));
				maxVal = RoundDouble(maxVal + num / 1.000001, Math.Abs(maxResPwrOfTen));
				return;
			}
			double num2 = 0.0;
			double num3 = 0.0;
			if (minVal < 0.0)
			{
				num2 = num;
			}
			if (maxVal > 0.0)
			{
				num3 = num;
			}
			minVal = (double)(int)((minVal - num2) / Math.Pow(10.0, maxResPwrOfTen)) * Math.Pow(10.0, maxResPwrOfTen);
			maxVal = (double)(int)((maxVal + num3) / Math.Pow(10.0, maxResPwrOfTen)) * Math.Pow(10.0, maxResPwrOfTen);
			return;
		}
		double num4 = maxVal - minVal;
		if (num4 < 0.0005)
		{
			minVal = RoundDouble(minVal - 5E-06, 4);
			maxVal = RoundDouble(maxVal + 5E-06, 4);
			if (minVal == maxVal)
			{
				minVal -= 0.0005;
				maxVal += 0.0005;
			}
		}
		else if (num4 < 0.005)
		{
			minVal = RoundDouble(minVal - 5E-05, 3);
			maxVal = RoundDouble(maxVal + 5E-05, 3);
		}
		else if (num4 < 0.05)
		{
			minVal = RoundDouble(minVal - 0.0005, 3);
			maxVal = RoundDouble(maxVal + 0.0005, 3);
		}
		else if (num4 < 0.5)
		{
			minVal = RoundDouble(minVal - 0.005, 2);
			maxVal = RoundDouble(maxVal + 0.005, 2);
		}
		else if (num4 < 5.0)
		{
			minVal = RoundDouble(minVal - 0.05, 1);
			maxVal = RoundDouble(maxVal + 0.05, 1);
		}
		else if (num4 < 50.0)
		{
			minVal = (int)minVal - 1;
			maxVal = (int)maxVal + 1;
		}
		else if (num4 < 500.0)
		{
			minVal = (int)(minVal / 10.0 - 1.0) * 10;
			maxVal = (int)(maxVal / 10.0 + 1.0) * 10;
		}
		else if (num4 < 5000.0)
		{
			minVal = (int)(minVal / 100.0 - 1.0) * 100;
			maxVal = (int)(maxVal / 100.0 + 1.0) * 100;
		}
		else if (num4 < 50000.0)
		{
			minVal = (int)(minVal / 1000.0 - 1.0) * 1000;
			maxVal = (int)(maxVal / 1000.0 + 1.0) * 1000;
		}
		else
		{
			minVal = (int)(minVal / 10000.0 - 1.0) * 10000;
			maxVal = (int)(maxVal / 10000.0 + 1.0) * 10000;
		}
	}

	public static double RoundDouble(double doValue, int nPrecision)
	{
		double num = 10.0;
		double num2 = 0.0;
		double num3 = doValue * Math.Pow(num, nPrecision + 1);
		num3 = ((!(doValue < 0.0)) ? (num3 + 5.0) : (num3 - 5.0));
		num3 /= num;
		num2 = Math.Truncate(num3);
		return num2 / Math.Pow(num, nPrecision);
	}

	public static void ModF(double number, ref double y)
	{
		double num = Math.Floor(number);
		y = number - num;
	}

	internal static T GetAssemblyAttribute<T>(Assembly assembly) where T : class
	{
		object[] customAttributes = assembly.GetCustomAttributes(typeof(T), inherit: false);
		if (customAttributes.Length == 1)
		{
			return customAttributes[0] as T;
		}
		return null;
	}

	public static string GetAssemblyVersion(Assembly assembly)
	{
		AssemblyInformationalVersionAttribute assemblyAttribute = GetAssemblyAttribute<AssemblyInformationalVersionAttribute>(assembly);
		if (assemblyAttribute != null)
		{
			return assemblyAttribute.InformationalVersion;
		}
		return string.Empty;
	}

	public static string GetTempOutputFilePath(string ext)
	{
		string text = "QMine_Temp";
		string text2 = "c:\\Qualcomm\\QMine\\Temp";
		try
		{
			if (!Directory.Exists(text2))
			{
				Directory.CreateDirectory(text2);
				return text2 + "\\" + text + "0." + ext;
			}
			string[] files = Directory.GetFiles(text2, text + "*." + ext);
			int num = 0;
			int length = (text2 + "\\" + text).Length;
			string[] array = files;
			foreach (string text3 in array)
			{
				int result = 0;
				if (int.TryParse(text3.Substring(length, text3.Length - (length + ext.Length + 1)), out result))
				{
					num = ((result > num) ? result : num);
				}
			}
			return text2 + "\\" + text + (num + 1) + "." + ext;
		}
		catch (Exception)
		{
			return null;
		}
	}

	public static string CreateCellLocator(DataTable dataTable, DataRow row, string columnName)
	{
		return dataTable.Rows.IndexOf(row) + "__" + dataTable.Columns.IndexOf(columnName);
	}

	public static string CreateCellLocatorUsingColumnName(DataTable dataTable, DataRow row, string columnName)
	{
		return dataTable.Rows.IndexOf(row) + "__" + columnName;
	}

	public static string CreateCellLocator(DataTable dataTable, DataRow row, int columnIndex)
	{
		return dataTable.Rows.IndexOf(row) + "__" + columnIndex;
	}

	public static string CreateCellLocator(int rowIndex, int colmunIndex)
	{
		return rowIndex + "__" + colmunIndex;
	}

	public static bool IsViolatingLimits(double val, double min, double max)
	{
		if (double.IsNaN(val))
		{
			return false;
		}
		if (!double.IsNaN(min) && !double.IsNaN(max))
		{
			if (val >= min && val <= max)
			{
				return false;
			}
			return true;
		}
		if (!double.IsNaN(min))
		{
			if (val >= min)
			{
				return false;
			}
			return true;
		}
		if (!double.IsNaN(max))
		{
			if (val <= max)
			{
				return false;
			}
			return true;
		}
		return false;
	}

	public static bool IsAnyDataPointViolatingLimits(IEnumerable<double> vals, double min, double max)
	{
		if (vals.Any((double val) => IsViolatingLimits(val, min, max)))
		{
			return true;
		}
		return false;
	}

	public static void RunLoop(bool runInSequence, int startIndex, int endIndex, Action<int> loopBlock)
	{
		if (runInSequence && loopBlock != null)
		{
			for (int i = startIndex; i < endIndex; i++)
			{
				loopBlock(i);
			}
		}
		else
		{
			Parallel.For(startIndex, endIndex, loopBlock);
		}
	}

	public static void RunLoop(bool runInSequence, long startIndex, long endIndex, Action<long> loopBlock)
	{
		if (runInSequence && loopBlock != null)
		{
			for (long num = startIndex; num < endIndex; num++)
			{
				loopBlock(num);
			}
		}
		else
		{
			Parallel.For(startIndex, endIndex, loopBlock);
		}
	}

	public static void RunForEachLoop<T>(bool runInSequence, IEnumerable<T> source, Action<T> loopBlock)
	{
		if (runInSequence && loopBlock != null)
		{
			foreach (T item in source)
			{
				loopBlock(item);
			}
			return;
		}
		Parallel.ForEach(source, loopBlock);
	}

	public static string GetCommandLineValue(int currentPosition, List<string> cmdLineArgsList)
	{
		string result = string.Empty;
		int num = currentPosition + 1;
		if (num < cmdLineArgsList.Count)
		{
			result = cmdLineArgsList[num];
		}
		return result;
	}

	public static string ResolvePath(string pathToResolve)
	{
		string text = pathToResolve.ToLower();
		if (text.Contains("[programfiles]"))
		{
			text = text.Replace("[programfiles]", GetProgramFilesPath());
		}
		return text;
	}

	public static string RemoveInvalidPathCharactersFromFileName(string fileName)
	{
		string str = new string(Path.GetInvalidFileNameChars()) + new string(Path.GetInvalidPathChars());
		Regex regex = new Regex($"[{Regex.Escape(str)}]");
		return regex.Replace(fileName, "");
	}

	public static string GetProgramFilesPath()
	{
		string folderPath = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86);
		if (string.IsNullOrEmpty(folderPath))
		{
			folderPath = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles);
		}
		return folderPath;
	}

	public static void DecompressCXML(FileInfo compressedFile, string FileName)
	{
		FileStream stream = compressedFile.OpenRead();
		using FileStream destination = new FileStream(FileName, FileMode.Create);
		using GZipStream gZipStream = new GZipStream(stream, CompressionMode.Decompress);
		gZipStream.CopyTo(destination);
	}

	public static string DecompressCXML(string CxmlFilePath)
	{
		FileInfo compressedFile = new FileInfo(CxmlFilePath);
		string text = Path.GetTempPath() + Path.GetFileNameWithoutExtension(CxmlFilePath) + ".xml";
		DecompressCXML(compressedFile, text);
		return text;
	}

	private static int FindAndKill(string name, bool kill = false)
	{
		int num = 0;
		int num2 = 0;
		int num3 = 0;
		Process[] processes = Process.GetProcesses();
		foreach (Process process in processes)
		{
			if (!process.ProcessName.StartsWith(name))
			{
				continue;
			}
			num++;
			if (kill)
			{
				try
				{
					process.Kill();
					num3++;
				}
				catch (Exception)
				{
					num2++;
				}
			}
		}
		return num;
	}

	public static void KillAll()
	{
		string[] array = new string[2] { "EXCEL", "POWERPNT" };
		string[] array2 = array;
		foreach (string name in array2)
		{
			KillProcess(name);
		}
	}

	public static void KillProcess(string name)
	{
		FindAndKill(name, kill: true);
	}
}
