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

namespace QC.QDM.Libraries.DataAccessLibrary;

public class DataAccess
{
	private const string DEFAULT_SERVER_NAME = "cte-sql-dev";

	private const string DEFAULT_DATABASE_NAME = "play";

	private const string DEFAULT_USERNAME = "QTMAppUser";

	private const string DEFAULT_PASSWORD = "$1234Qual";

	private const int DEFAULT_CONNECTION_TIMEOUT = 60;

	private string serverName;

	private string databaseName;

	private string userName;

	private string password;

	private string connectionString;

	private int connectionTimeout;

	private int commandTimeout;

	private SqlCommand currentCommand;

	public string UserName
	{
		get
		{
			return userName;
		}
		set
		{
			userName = value;
		}
	}

	public string Password
	{
		get
		{
			return password;
		}
		set
		{
			password = value;
		}
	}

	public string ServerName
	{
		get
		{
			return serverName;
		}
		set
		{
			serverName = value;
		}
	}

	public string DatabaseName
	{
		get
		{
			return databaseName;
		}
		set
		{
			databaseName = value;
		}
	}

	public int ConnectionTimeout
	{
		get
		{
			return connectionTimeout;
		}
		set
		{
			connectionTimeout = value;
		}
	}

	public int CommandTimeout
	{
		get
		{
			return commandTimeout;
		}
		set
		{
			commandTimeout = value;
		}
	}

	public string ConnectionString
	{
		get
		{
			if (string.IsNullOrEmpty(connectionString))
			{
				connectionString = CreateConnectionString();
			}
			return connectionString;
		}
		set
		{
			connectionString = value;
		}
	}

	public DataAccess()
		: this("cte-sql-dev", "play")
	{
	}

	public DataAccess(string serverName_extrnl, string databaseName_extrnl, string userName_extrnl, string password_extrnl, int timeOut_extrnl)
		: this(serverName_extrnl, databaseName_extrnl, userName_extrnl, password_extrnl, timeOut_extrnl, timeOut_extrnl)
	{
	}

	public DataAccess(string serverName_extrnl, string databaseName_extrnl, string userName_extrnl, string password_extrnl)
		: this(serverName_extrnl, databaseName_extrnl, userName_extrnl, password_extrnl, 60)
	{
	}

	public DataAccess(string serverName_extrnl, string databaseName_extrnl)
		: this(serverName_extrnl, databaseName_extrnl, 60)
	{
	}

	public DataAccess(string serverName_extrnl, string databaseName_extrnl, int timeOut_extrnl)
		: this(serverName_extrnl, databaseName_extrnl, "QTMAppUser", "$1234Qual", timeOut_extrnl)
	{
	}

	public DataAccess(string serverName_extrnl, string databaseName_extrnl, string userName_extrnl, string password_extrnl, int timeOut_extrnl, int commandTimeout_extrnl)
	{
		ServerName = serverName_extrnl;
		DatabaseName = databaseName_extrnl;
		UserName = userName_extrnl;
		Password = password_extrnl;
		ConnectionTimeout = timeOut_extrnl;
		CommandTimeout = commandTimeout_extrnl;
	}

	protected virtual string CreateConnectionString()
	{
		return "Data Source=" + ServerName + "; Initial Catalog=" + DatabaseName + "; User Id=" + UserName + "; Password=" + Password + "; Connection Timeout=" + ConnectionTimeout;
	}

	public void CancelQuery()
	{
		try
		{
			currentCommand.Cancel();
			Console.WriteLine("Query Cancelled!");
		}
		catch (Exception ex)
		{
			Console.WriteLine("DataAccessLibrary.DataAccess.CancelQuery() is causing exception.");
			throw ex;
		}
	}

	public int GetScalarValue(string query)
	{
		if (query.Length <= 1)
		{
			return 0;
		}
		SqlConnection sqlConnection = new SqlConnection(ConnectionString);
		new DataSet();
		try
		{
			sqlConnection.Open();
			currentCommand = new SqlCommand();
			currentCommand.CommandTimeout = CommandTimeout;
			currentCommand.CommandText = query;
			currentCommand.Connection = sqlConnection;
			return (int)currentCommand.ExecuteScalar();
		}
		catch (Exception ex)
		{
			throw new Exception("GetScalarValue failed, " + ex.Message);
		}
		finally
		{
			if (sqlConnection != null)
			{
				sqlConnection.Close();
				sqlConnection.Dispose();
			}
		}
	}

	public DataSet RunQuery(string query)
	{
		if (query.Length <= 1)
		{
			return null;
		}
		SqlConnection sqlConnection = new SqlConnection(ConnectionString);
		DataSet dataSet = new DataSet();
		try
		{
			sqlConnection.Open();
			currentCommand = new SqlCommand(query, sqlConnection);
			currentCommand.CommandTimeout = CommandTimeout;
			SqlDataAdapter sqlDataAdapter = new SqlDataAdapter(currentCommand);
			sqlDataAdapter.Fill(dataSet);
			return dataSet;
		}
		catch (Exception ex)
		{
			Console.WriteLine("DataAccessLibrary.DataAccess.RunQuery(String) is causing exception." + ex.Message);
			throw ex;
		}
		finally
		{
			if (sqlConnection != null)
			{
				sqlConnection.Close();
				sqlConnection.Dispose();
			}
		}
	}

	public SqlDataReader RunQueryWithOpenDataStream(string query)
	{
		SqlConnection sqlConnection = new SqlConnection(ConnectionString);
		try
		{
			currentCommand = new SqlCommand(query, sqlConnection);
			currentCommand.CommandType = CommandType.Text;
			sqlConnection.Open();
			return currentCommand.ExecuteReader(CommandBehavior.CloseConnection);
		}
		catch (Exception innerException)
		{
			if (sqlConnection != null && sqlConnection.State != 0)
			{
				sqlConnection.Close();
			}
			throw new ApplicationException("Error running query", innerException);
		}
	}

	public DataSet RunStoredProcedure(string storedProcedureName, params object[] parameter)
	{
		if (storedProcedureName.Length <= 1)
		{
			return null;
		}
		SqlConnection sqlConnection = new SqlConnection(ConnectionString);
		DataSet dataSet = new DataSet();
		try
		{
			sqlConnection.Open();
			currentCommand = new SqlCommand(storedProcedureName, sqlConnection);
			currentCommand.CommandType = CommandType.StoredProcedure;
			currentCommand.CommandTimeout = CommandTimeout;
			for (int i = 0; i < parameter.Length; i += 2)
			{
				_ = (string)parameter[i];
				SqlParameter value = new SqlParameter((string)parameter[i], parameter[i + 1]);
				currentCommand.Parameters.Add(value);
			}
			SqlDataAdapter sqlDataAdapter = new SqlDataAdapter(currentCommand);
			sqlDataAdapter.Fill(dataSet);
			return dataSet;
		}
		catch (Exception ex)
		{
			Console.WriteLine("DataAccessLibrary.DataAccess.RunStoredProcedure(String, params object []) is causing exception.");
			Console.WriteLine(ex.ToString());
			throw ex;
		}
		finally
		{
			if (sqlConnection != null)
			{
				sqlConnection.Close();
				sqlConnection.Dispose();
			}
		}
	}

	public DataSet RunStoredProcedure(string storedProcedureName, string paramName, object parameter)
	{
		if (storedProcedureName.Length <= 1)
		{
			return null;
		}
		SqlConnection sqlConnection = new SqlConnection(ConnectionString);
		DataSet dataSet = new DataSet();
		try
		{
			sqlConnection.Open();
			currentCommand = new SqlCommand(storedProcedureName, sqlConnection);
			currentCommand.CommandType = CommandType.StoredProcedure;
			currentCommand.CommandTimeout = CommandTimeout;
			currentCommand.Parameters.Add(new SqlParameter(paramName, parameter));
			SqlDataAdapter sqlDataAdapter = new SqlDataAdapter(currentCommand);
			sqlDataAdapter.Fill(dataSet);
			return dataSet;
		}
		catch (Exception ex)
		{
			Console.WriteLine("DataAccessLibrary.DataAccess.RunStoredProcedure(String, String, object) is causing exception.");
			throw ex;
		}
		finally
		{
			if (sqlConnection != null)
			{
				sqlConnection.Close();
				sqlConnection.Dispose();
			}
		}
	}

	public DataSet RunStoredProcedure(string storedProcedureName, string paramName1, object parameter1, string paramName2, object parameter2)
	{
		if (storedProcedureName.Length <= 1)
		{
			return null;
		}
		SqlConnection sqlConnection = new SqlConnection(ConnectionString);
		DataSet dataSet = new DataSet();
		try
		{
			sqlConnection.Open();
			currentCommand = new SqlCommand(storedProcedureName, sqlConnection);
			currentCommand.CommandType = CommandType.StoredProcedure;
			currentCommand.CommandTimeout = CommandTimeout;
			currentCommand.Parameters.Add(new SqlParameter(paramName1, parameter1));
			currentCommand.Parameters.Add(new SqlParameter(paramName2, parameter2));
			SqlDataAdapter sqlDataAdapter = new SqlDataAdapter(currentCommand);
			sqlDataAdapter.Fill(dataSet);
			return dataSet;
		}
		catch (Exception ex)
		{
			Console.WriteLine("DataAccessLibrary.DataAccess.RunStoredProcedure(String, String, object, String, object) is causing exception.");
			throw ex;
		}
		finally
		{
			if (sqlConnection != null)
			{
				sqlConnection.Close();
				sqlConnection.Dispose();
			}
		}
	}

	public DataSet RunStoredProcedure(string storedProcedureName, List<SqlParameter> inSqlParameter, out List<SqlParameter> outSqlParameter)
	{
		outSqlParameter = inSqlParameter;
		if (storedProcedureName.Length <= 1)
		{
			return null;
		}
		SqlConnection sqlConnection = new SqlConnection(ConnectionString);
		DataSet dataSet = new DataSet();
		try
		{
			currentCommand = new SqlCommand(storedProcedureName, sqlConnection);
			currentCommand.CommandType = CommandType.StoredProcedure;
			currentCommand.CommandTimeout = CommandTimeout;
			foreach (SqlParameter item in inSqlParameter)
			{
				currentCommand.Parameters.Add(item);
			}
			SqlDataAdapter sqlDataAdapter = new SqlDataAdapter(currentCommand);
			sqlDataAdapter.Fill(dataSet);
			outSqlParameter = inSqlParameter;
			return dataSet;
		}
		catch (Exception ex)
		{
			Console.WriteLine("DataAccessLibrary.DataAccess.RunStoredProcedure(String, List<SqlParamter>, out List<SqlParamter>) is causing exception.");
			throw ex;
		}
		finally
		{
			if (sqlConnection != null)
			{
				sqlConnection.Close();
				sqlConnection.Dispose();
			}
		}
	}
}
