using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.Threading.Tasks;
using System.Xml.Serialization;
using System.Xml.XPath;

namespace QC.QMine.QMineInterface;

public static class CommonFunctions
{
	public static bool ReportGenerated = false;

	private static string qMineDataPath = "c:\\Qualcomm\\QMine";

	public static string QMineDataPath => qMineDataPath;

	public static string QMineTempDataPath => Path.Combine(QMineDataPath, "Temp");

	public static void CreateQMineDirectories()
	{
		if (!Directory.Exists(Constants.QMineDataPath))
		{
			Directory.CreateDirectory(Constants.QMineDataPath);
		}
		if (!Directory.Exists(Constants.PluginsFolderPath))
		{
			Directory.CreateDirectory(Constants.PluginsFolderPath);
		}
	}

	public static string GetRunReportTemporaryFilePath()
	{
		string qMineTemporaryDirectoryPath = GetQMineTemporaryDirectoryPath();
		return Path.Combine(qMineTemporaryDirectoryPath, "TempCommandLine.xml");
	}

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

	public static void CleanupTemporaryFolder()
	{
		string qMineTempDir = GetQMineTemporaryDirectoryPath();
		Action<string, TimeSpan> cleanupTempFolderAction = CleanupQMineTempFolder;
		TimeSpan cleanUpDuration = default(TimeSpan);
		ref TimeSpan reference = ref cleanUpDuration;
		reference = new TimeSpan(QMineGlobalInformation.QMineTempFolderCleanupDays, 0, 0, 0);
		Task.Factory.StartNew(delegate
		{
			cleanupTempFolderAction(qMineTempDir, cleanUpDuration);
		});
	}

	private static void CleanupQMineTempFolder(string path, TimeSpan duration)
	{
		if (Directory.Exists(path))
		{
			DirectoryInfo directoryInfo = new DirectoryInfo(path);
			(from file in directoryInfo.GetFiles()
				where file.LastWriteTime.Add(duration) < DateTime.Now
				select file).ForEach(delegate(FileInfo file)
			{
				file.Delete();
			});
		}
	}

	public static string GetQMineTemporaryDirectoryPath()
	{
		string text = Path.Combine(QMineDataPath, "Temp");
		if (!Directory.Exists(text))
		{
			Directory.CreateDirectory(text);
		}
		return text;
	}

	public static bool IsFormatDescriptorFile(string sourceFile)
	{
		return HasText(sourceFile, "<FormatDescriptor");
	}

	public static bool IsQtmFile(string sourceFile)
	{
		return HasText(sourceFile, "<ROOT");
	}

	public static bool IsFileTypeSupported(string sourceFile)
	{
		return HasText(sourceFile, "Dataminer.net CSV Format");
	}

	private 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<FileInfo> GetFiles(DirectoryInfo qtmDir, bool includeSubFolders)
	{
		List<FileInfo> list = new List<FileInfo>();
		if (includeSubFolders)
		{
			list.AddRange(qtmDir.EnumerateFiles("*.xml", SearchOption.AllDirectories));
			list.AddRange(qtmDir.EnumerateFiles("*.cxml", SearchOption.AllDirectories));
			return list;
		}
		list.AddRange(qtmDir.EnumerateFiles("*.xml", SearchOption.TopDirectoryOnly));
		list.AddRange(qtmDir.EnumerateFiles("*.cxml", SearchOption.TopDirectoryOnly));
		return list;
	}

	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;
		try
		{
			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();
				}
			}
		}
		catch (Exception)
		{
			val = null;
		}
		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 void KillProcess(string processName)
	{
		Process[] processes = Process.GetProcesses();
		foreach (Process process in processes)
		{
			if (process.ProcessName.ToLower().StartsWith(processName.ToLower()))
			{
				try
				{
					process.Kill();
				}
				catch (Exception)
				{
				}
			}
		}
	}

	[DllImport("shell32.dll")]
	public static extern IntPtr ShellExecute(IntPtr hwnd, string lpOperation, string lpFile, string lpParameters, string lpDirectory, int nShowCmd);

	public static void LaunchEmailClient(string emailAddress)
	{
		ShellExecute(IntPtr.Zero, "open", emailAddress, string.Empty, string.Empty, 4);
	}

	public static List<string> GetValuesFromXQuery(XPathNavigator xNav, string xQuery)
	{
		List<string> list = new List<string>();
		XPathNodeIterator xPathNodeIterator = xNav.Select(xQuery);
		if (xPathNodeIterator.Count > 0)
		{
			while (xPathNodeIterator.MoveNext())
			{
				list.Add(xPathNodeIterator.Current.Value);
			}
		}
		return list;
	}

	[DllImport("kernel32.dll", SetLastError = true)]
	private static extern bool FreeConsole();

	[DllImport("User32.dll")]
	public static extern IntPtr FindWindow(string strClassName, string strWindowName);

	[DllImport("user32.dll", SetLastError = true)]
	public static extern IntPtr SetActiveWindow(IntPtr hWnd);

	public static void CloseQMineInCommandLineMode()
	{
		Console.WriteLine("\nExiting from QMine-Command Line Mode......");
		ReportGenerated = true;
	}

	public static string GetCommandLineValue(string argKey, List<string> cmdLineArgsList, int currentIndex = -1)
	{
		string text = string.Empty;
		int num = -1;
		if (currentIndex == -1)
		{
			if (cmdLineArgsList.Contains(argKey))
			{
				num = cmdLineArgsList.IndexOf(argKey) + 1;
			}
		}
		else
		{
			num = currentIndex + 1;
		}
		if (num > 0 && num < cmdLineArgsList.Count)
		{
			text = cmdLineArgsList[num];
		}
		if (!string.IsNullOrEmpty(text))
		{
			text = text.TrimEnd().TrimStart();
		}
		return text;
	}

	public static string GetCommandLineValueForDataFilters(int argKeyIndex, List<string> cmdLineArgsList, out List<string> filterValueList)
	{
		string result = string.Empty;
		int num = 0;
		filterValueList = null;
		num = argKeyIndex + 1;
		if (num < cmdLineArgsList.Count)
		{
			filterValueList = cmdLineArgsList[num].Split(',').ToList();
			if (filterValueList != null && filterValueList.Count > 0)
			{
				result = filterValueList[0];
				filterValueList.RemoveAt(0);
			}
		}
		return result;
	}
}
