using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Data.SqlTypes;
using System.Xml;

namespace QC.QTMTreeXMLHandler;

public class QTMTreeXMLRegistration
{
	private const string ST_PROC_TREE_INSERT = "qryInsertTreeV3";

	private const string ST_PROC_NODE_INSERT = "qryInsertNodeV3";

	private const string ST_PROC_PARAM_INSERT = "qryInsertParamV3";

	private const string ST_PROC_PARAMARRAY_INSERT = "qryInsertParamArrayV3";

	private const string ST_PROC_SCENARIO_INSERT = "qryInsertScenarioConditionsV3";

	private const string ST_PROC_INSERT_TREE_XML = "uspInsertTreeXml";

	private const string ST_PROC_GET_REGISTRATION_INFO = "uspGetDatabaseProperties";

	private const string COL_SIMPLE_REGISTRATION = "SimpleRegistration";

	private const string COL_STORE_XML_FILE = "StoreXmlFile";

	public const int TREE_ALREADY_REGISTERED = 0;

	public const string LOCAL_MACHINE = "Local Machine";

	public const string NO_DB = "No DB";

	private string treeXml = "";

	private SqlConnection sqlConnection;

	private QTMTreeHandler treeHandler;

	private long treeID = -1L;

	private string treeStringID = "-1";

	private int currentID;

	private bool cancel;

	public string TreeXml
	{
		get
		{
			if (treeHandler != null)
			{
				return treeHandler.XmlDoc.OuterXml;
			}
			return "";
		}
		set
		{
			treeXml = value;
		}
	}

	public SqlConnection Connection
	{
		get
		{
			return sqlConnection;
		}
		set
		{
			sqlConnection = value;
		}
	}

	public long TreeID => treeID;

	public string TreeStringID => treeStringID;

	public bool Cancel
	{
		get
		{
			return cancel;
		}
		set
		{
			cancel = value;
		}
	}

	public event RegisteringNodeChangedEventHandler RegisteringNodeChanged;

	private void OnRegisteringNodeChanged(string nodeName)
	{
		try
		{
			if (this.RegisteringNodeChanged != null)
			{
				this.RegisteringNodeChanged(this, new RegisteringNodeChangedEventArgs(nodeName));
			}
		}
		catch
		{
		}
	}

	public QTMTreeXMLRegistration()
	{
	}

	public QTMTreeXMLRegistration(SqlConnection sqlConnection, string treeXml)
	{
		this.sqlConnection = sqlConnection;
		this.treeXml = treeXml;
	}

	private bool RunQuery(string queryString)
	{
		try
		{
			SqlCommand sqlCommand = new SqlCommand(queryString, sqlConnection);
			sqlCommand.CommandType = CommandType.Text;
			SqlDataReader sqlDataReader = sqlCommand.ExecuteReader();
			sqlDataReader.Close();
			return true;
		}
		catch (Exception ex)
		{
			throw new Exception(ex.Message);
		}
	}

	private long RunStoredProc(string StProcName, string Arg1Name, string Arg1Value)
	{
		long result = -1L;
		SqlDataReader sqlDataReader = null;
		try
		{
			SqlCommand sqlCommand = new SqlCommand(StProcName, sqlConnection);
			sqlCommand.CommandType = CommandType.StoredProcedure;
			sqlCommand.Parameters.Add(Arg1Name, SqlDbType.VarChar);
			sqlCommand.Parameters[Arg1Name].Value = Arg1Value;
			sqlDataReader = sqlCommand.ExecuteReader();
			if (sqlDataReader.Read())
			{
				result = long.Parse(sqlDataReader["Identity"].ToString());
			}
			sqlDataReader.Close();
			return result;
		}
		catch (Exception ex)
		{
			sqlDataReader?.Close();
			throw new Exception(ex.Message);
		}
	}

	private bool RunStoredProc(string StProcName, List<SqlParameter> inSqlParameter)
	{
		SqlDataReader sqlDataReader = null;
		try
		{
			SqlCommand sqlCommand = new SqlCommand(StProcName, sqlConnection);
			sqlCommand.CommandType = CommandType.StoredProcedure;
			foreach (SqlParameter item in inSqlParameter)
			{
				sqlCommand.Parameters.Add(item);
			}
			sqlDataReader = sqlCommand.ExecuteReader();
			sqlDataReader.Close();
			return true;
		}
		catch (Exception ex)
		{
			sqlDataReader?.Close();
			throw new Exception(ex.Message);
		}
		finally
		{
			sqlDataReader?.Close();
		}
	}

	public long RunStoredProc(string StProcName, string Arg1Name, string Arg1Value, string Arg2Name, long iRID, out string treeStringID, out string WarningString)
	{
		long result = -1L;
		WarningString = "";
		treeStringID = "";
		SqlDataReader sqlDataReader = null;
		try
		{
			SqlCommand sqlCommand = new SqlCommand(StProcName, sqlConnection);
			sqlCommand.CommandType = CommandType.StoredProcedure;
			sqlCommand.Parameters.Add(Arg1Name, SqlDbType.VarChar);
			sqlCommand.Parameters[Arg1Name].Value = Arg1Value;
			if (iRID != -1)
			{
				sqlCommand.Parameters.Add(Arg2Name, SqlDbType.BigInt);
				sqlCommand.Parameters[Arg2Name].Value = iRID;
			}
			sqlDataReader = sqlCommand.ExecuteReader();
			if (sqlDataReader.Read())
			{
				result = long.Parse(sqlDataReader["Identity"].ToString());
				try
				{
					treeStringID = sqlDataReader["TreeStringID"].ToString();
				}
				catch
				{
					treeStringID = result.ToString();
				}
			}
		}
		catch (Exception ex)
		{
			WarningString = ex.Message;
		}
		finally
		{
			sqlDataReader?.Close();
		}
		return result;
	}

	private bool RunStoredProcParameter(string StProcName, string mainQry, string Arg1Name, out long Arg1Value, string Arg2Name, out long Arg2Value)
	{
		Arg1Value = -1L;
		Arg2Value = -1L;
		SqlDataReader sqlDataReader = null;
		try
		{
			SqlCommand sqlCommand = new SqlCommand(StProcName, sqlConnection);
			sqlCommand.CommandType = CommandType.StoredProcedure;
			sqlCommand.Parameters.Add("@XmlInput", SqlDbType.VarChar);
			sqlCommand.Parameters["@XmlInput"].Value = mainQry;
			sqlCommand.Parameters.Add(Arg1Name, SqlDbType.BigInt);
			sqlCommand.Parameters[Arg1Name].Value = Arg1Value;
			sqlCommand.Parameters.Add(Arg2Name, SqlDbType.BigInt);
			sqlCommand.Parameters[Arg2Name].Value = Arg2Value;
			sqlCommand.Parameters[Arg1Name].Direction = ParameterDirection.Output;
			sqlCommand.Parameters[Arg2Name].Direction = ParameterDirection.Output;
			sqlDataReader = sqlCommand.ExecuteReader();
			try
			{
				Arg1Value = (long)sqlCommand.Parameters[Arg1Name].Value;
			}
			catch
			{
			}
			try
			{
				Arg2Value = (long)sqlCommand.Parameters[Arg2Name].Value;
			}
			catch
			{
			}
			sqlDataReader.Close();
		}
		catch (Exception ex)
		{
			sqlDataReader?.Close();
			throw new Exception(ex.Message);
		}
		return true;
	}

	public DataTable RunStoredProcedure(string storedProcedureName)
	{
		if (storedProcedureName.Length <= 1)
		{
			return null;
		}
		DataSet dataSet = new DataSet();
		try
		{
			SqlCommand sqlCommand = new SqlCommand(storedProcedureName, sqlConnection);
			sqlCommand.CommandType = CommandType.StoredProcedure;
			SqlDataAdapter sqlDataAdapter = new SqlDataAdapter(sqlCommand);
			sqlDataAdapter.Fill(dataSet);
		}
		catch (Exception ex)
		{
			Console.WriteLine("RunStoredProcedure, " + storedProcedureName + " failed.");
			Console.WriteLine(ex.ToString());
			throw ex;
		}
		return dataSet.Tables[0];
	}

	public bool RegisterTree()
	{
		string errorString;
		return RegisterTree("", "", out errorString);
	}

	public bool RegisterTree(out string errorString)
	{
		return RegisterTree("", "", out errorString);
	}

	public bool RegisterTree(SqlConnection sqlConnection, string treeXml)
	{
		return RegisterTree(sqlConnection, treeXml, "", "");
	}

	public bool RegisterTree(SqlConnection sqlConnection, string treeXml, out string errorString)
	{
		return RegisterTree(sqlConnection, treeXml, "", "", out errorString);
	}

	public bool RegisterTree(SqlConnection sqlConnection, string treeXml, string comment, string createdBy)
	{
		string errorString;
		return RegisterTree(sqlConnection, treeXml, comment, createdBy, out errorString);
	}

	public bool RegisterTree(SqlConnection sqlConnection, string treeXml, string comment, string createdBy, out string errorString)
	{
		this.sqlConnection = sqlConnection;
		this.treeXml = treeXml;
		return RegisterTree(comment, createdBy, out errorString);
	}

	public bool RegisterTree(string comment, string createdBy, out string errorString)
	{
		errorString = "";
		cancel = false;
		bool result = false;
		bool result2 = false;
		try
		{
			if (sqlConnection != null && treeXml != "")
			{
				if (sqlConnection.State == ConnectionState.Closed)
				{
					sqlConnection.Open();
				}
				treeHandler = new QTMTreeHandler(treeXml);
				int leftID = 1;
				treeID = -1L;
				currentID = 1;
				string rootProperties = treeHandler.GetRootProperties(comment, createdBy);
				treeID = RunStoredProc("qryInsertTreeV3", "@XmlInput", rootProperties, "", -1L, out treeStringID, out errorString);
				if (errorString.Trim().Length > 0)
				{
					return false;
				}
				if (treeID == 0)
				{
					return true;
				}
				treeHandler.UpdateTreeRID(treeID, treeStringID);
				treeHandler.UpdateTreeRegistrationInformation(sqlConnection.DataSource, sqlConnection.Database);
				try
				{
					DataTable dataTable = RunStoredProcedure("uspGetDatabaseProperties");
					if (dataTable != null && dataTable.Rows.Count > 0)
					{
						foreach (DataRow row in dataTable.Rows)
						{
							if (row["Name"].ToString() == "SimpleRegistration")
							{
								bool.TryParse(row["Value"].ToString(), out result);
							}
							if (row["Name"].ToString() == "StoreXmlFile")
							{
								bool.TryParse(row["Value"].ToString(), out result2);
							}
						}
					}
				}
				catch
				{
				}
				if (!result)
				{
					leftID = RegisterNodes(leftID);
				}
				if (result2)
				{
					List<SqlParameter> list = new List<SqlParameter>();
					SqlParameter sqlParameter = new SqlParameter("@XmlInput", SqlDbType.Xml);
					sqlParameter.Value = new SqlXml(new XmlTextReader(treeHandler.XmlDoc.InnerXml, XmlNodeType.Document, null));
					list.Add(sqlParameter);
					new SqlParameter("@XmlInput", SqlDbType.Xml);
					list.Add(new SqlParameter("@TreeRID", treeID));
					RunStoredProc("uspInsertTreeXml", list);
				}
				if (cancel)
				{
					try
					{
						if (treeID != -1)
						{
							RunQuery("delete from tblTree where treeRID=" + treeID);
						}
						if (sqlConnection.State == ConnectionState.Open)
						{
							sqlConnection.Close();
						}
					}
					catch
					{
					}
					return false;
				}
				try
				{
					if (sqlConnection.State == ConnectionState.Open)
					{
						sqlConnection.Close();
					}
				}
				catch
				{
				}
				return true;
			}
			treeHandler = new QTMTreeHandler(treeXml);
			treeHandler.GetRootProperties(comment, createdBy);
			byte[] array = Guid.NewGuid().ToByteArray();
			treeID = BitConverter.ToInt64(array, 0);
			treeStringID = array[0].ToString();
			treeHandler.UpdateTreeRID(TreeID, treeStringID);
			treeHandler.UpdateTreeRegistrationInformation("Local Machine", "No DB");
			return true;
		}
		catch (Exception ex)
		{
			errorString = ex.Message;
			try
			{
				if (sqlConnection != null)
				{
					if (treeID != -1)
					{
						RunQuery("delete from tblTree where treeRID=" + treeID);
					}
					if (sqlConnection.State == ConnectionState.Open)
					{
						sqlConnection.Close();
					}
				}
			}
			catch
			{
			}
		}
		finally
		{
			if (sqlConnection != null && sqlConnection.State == ConnectionState.Open)
			{
				sqlConnection.Close();
			}
		}
		return false;
	}

	private int RegisterNodes(int leftID)
	{
		bool flag = treeHandler.GetFirstCatagory;
		string text = "";
		while (flag)
		{
			text = treeHandler.CurrentCatDetails;
			if (text.Trim() == "")
			{
				break;
			}
			text = treeHandler.AddXmlStringChildNode(text, "NodeID", currentID.ToString());
			currentID++;
			text = treeHandler.AddXmlStringChildNode(text, "LeftID", leftID.ToString());
			text = treeHandler.AddXmlStringChildNode(text, "TreeRID", treeID.ToString());
			text = treeHandler.AddXmlStringChildNode(text, "NodeType", "FolderTest");
			long nID = RunStoredProc("qryInsertNodeV3", "@XmlInput", text);
			treeHandler.UpdateNodeID(NodeType.CATEGORY, nID);
			if (treeHandler.GetFirstTestFromCatagory)
			{
				HandleTests(leftID + 1);
			}
			flag = treeHandler.GetNextCatagory;
			int num = int.Parse(treeHandler.GetXmlStringChildValue(text, "NumberOfTests"));
			int num2 = leftID + num * 2 - 1;
			leftID = num2 + 1;
			if (cancel)
			{
				break;
			}
		}
		return leftID;
	}

	private void HandleTests(int leftID)
	{
		for (bool flag = true; flag && !cancel; flag = treeHandler.GetNextTest)
		{
			string currFolderDetails = treeHandler.CurrFolderDetails;
			currFolderDetails = treeHandler.AddXmlStringChildNode(currFolderDetails, "NodeID", currentID.ToString());
			currentID++;
			currFolderDetails = treeHandler.AddXmlStringChildNode(currFolderDetails, "LeftID", leftID.ToString());
			OnRegisteringNodeChanged(treeHandler.CurrentTestName);
			currFolderDetails = treeHandler.AddXmlStringChildNode(currFolderDetails, "TreeRID", treeID.ToString());
			if (treeHandler.TestIsFolder)
			{
				currFolderDetails = treeHandler.AddXmlStringChildNode(currFolderDetails, "NodeType", "FolderTest");
				long num = RunStoredProc("qryInsertNodeV3", "@XmlInput", currFolderDetails);
				treeHandler.UpdateNodeID(NodeType.FOLDER, num);
				HandleScenarios(num);
				if (treeHandler.GetFirstTestFromFolder)
				{
					HandleTests(leftID + 1);
				}
			}
			else
			{
				currFolderDetails = treeHandler.AddXmlStringChildNode(currFolderDetails, "NodeType", treeHandler.CurrentTestType);
				long num2 = RunStoredProc("qryInsertNodeV3", "@XmlInput", currFolderDetails);
				treeHandler.UpdateNodeID(NodeType.TEST, num2);
				HandleParameters(num2);
			}
			int num3 = int.Parse(treeHandler.GetXmlStringChildValue(currFolderDetails, "NumberOfTests"));
			int num4 = leftID + num3 * 2 - 1;
			leftID = num4 + 1;
		}
	}

	private void HandleScenarios(long currentNodeRID)
	{
		if (!cancel && treeHandler.GetScenarioFromFolder)
		{
			string currentScenario = treeHandler.CurrentScenario;
			currentScenario = treeHandler.AddXmlStringSecondChildNodeAll(currentScenario, "NodeRID", currentNodeRID.ToString());
			currentScenario = treeHandler.AddXmlStringSecondChildNodeIncrementedIndex(currentScenario, "ScnChildRID", currentNodeRID + 1);
			long nID = RunStoredProc("qryInsertScenarioConditionsV3", "@XmlInput", currentScenario);
			treeHandler.UpdateNodeID(NodeType.SCENARIOS, nID);
		}
	}

	private void HandleParameters(long currentNodeRID)
	{
		for (bool flag = treeHandler.GetFirstParameterFromTest; flag && !cancel; flag = treeHandler.GetNextParameter)
		{
			string currParameterDetials = treeHandler.CurrParameterDetials;
			if ((currParameterDetials.Contains("<NoOfElements>-1</NoOfElements>") || currParameterDetials.Contains("<IsDynamicArray>true</IsDynamicArray>")) && treeHandler.UpdateDynamicArraySize())
			{
				currParameterDetials = treeHandler.CurrParameterDetials;
			}
			currParameterDetials = treeHandler.AddXmlStringChildNode(currParameterDetials, "NodeRID", currentNodeRID.ToString());
			long Arg1Value = -1L;
			long Arg2Value = -1L;
			RunStoredProcParameter("qryInsertParamV3", currParameterDetials, "@ParamIdentity", out Arg1Value, "@ArrayIdentity", out Arg2Value);
			treeHandler.UpdateNodeID(NodeType.PARAMETER, Arg1Value);
			treeHandler.UpdateNodeID(NodeType.ARRAY_PARAMETER, Arg2Value);
		}
	}
}
