using System;
using System.Collections;
using System.Linq;
using System.Reflection;
using System.Windows.Forms;
using QC.QTMDotNetKernel.Handlers;
using QC.QTMDotNetKernelInterface;
using QC.QTMDotNetKernelInterface.Environment;
using QC.QTMInterface;

namespace QC.QTMDotNetKernel.Registry;

public class TestMethod : MarshalByRefObject
{
	private const string RETURN_PARAM_NAME = "ReturnValue";

	private string name;

	private string description = "";

	private string errorCode = "";

	private bool isTestMethod;

	private bool selected;

	private MethodInfo info;

	private Hashtable parameters = new Hashtable();

	private bool isSystemMethod;

	private bool isStatic;

	private bool isPropertyMethod;

	private TestClass parent;

	private bool canAddToTestPlan;

	private bool isSetupTest;

	private bool isTearDownTest;

	private bool isManual;

	public string Name
	{
		get
		{
			return name;
		}
		set
		{
			name = value;
		}
	}

	public string Description
	{
		get
		{
			return description;
		}
		set
		{
			description = value;
		}
	}

	public string ErrorCode
	{
		get
		{
			return errorCode;
		}
		set
		{
			errorCode = value;
		}
	}

	public bool CanAddToTestPlan
	{
		get
		{
			return canAddToTestPlan;
		}
		set
		{
			canAddToTestPlan = value;
		}
	}

	public bool IsSetupTest
	{
		get
		{
			return isSetupTest;
		}
		set
		{
			isSetupTest = value;
		}
	}

	public bool IsTearDownTest
	{
		get
		{
			return isTearDownTest;
		}
		set
		{
			isTearDownTest = value;
		}
	}

	public bool IsManual
	{
		get
		{
			return isManual;
		}
		set
		{
			isManual = value;
		}
	}

	public Hashtable Parameters
	{
		get
		{
			return parameters;
		}
		set
		{
			parameters = value;
		}
	}

	public MethodInfo Info
	{
		get
		{
			return info;
		}
		set
		{
			info = value;
		}
	}

	public bool IsSystemMethod
	{
		get
		{
			return isSystemMethod;
		}
		set
		{
			isSystemMethod = value;
		}
	}

	public TestClass Parent
	{
		get
		{
			return parent;
		}
		set
		{
			parent = value;
		}
	}

	public QSPREnvironment Environment
	{
		get
		{
			return Parent.Environment;
		}
		set
		{
			Parent.Environment = value;
		}
	}

	public bool IsTestMethod
	{
		get
		{
			return isTestMethod;
		}
		set
		{
			isTestMethod = value;
		}
	}

	public bool Selected
	{
		get
		{
			return selected;
		}
		set
		{
			selected = value;
		}
	}

	public Hashtable CheckedParameters
	{
		get
		{
			Hashtable hashtable = new Hashtable();
			foreach (TestParameter value in Parameters.Values)
			{
				if (value.CheckedState == CheckState.Checked || value.HasAttributes)
				{
					hashtable.Add(value.Name, value);
				}
			}
			return hashtable;
		}
	}

	public ArrayList CheckedParametersSortedList
	{
		get
		{
			Hashtable hashtable = new Hashtable();
			foreach (TestParameter value2 in Parameters.Values)
			{
				if (value2.CheckedState == CheckState.Checked || value2.HasAttributes)
				{
					hashtable.Add(value2.Name, value2);
				}
			}
			ArrayList arrayList = new ArrayList();
			ParameterInfo[] array = info.GetParameters();
			foreach (ParameterInfo parameterInfo in array)
			{
				if (parameterInfo.ParameterType.IsByRef)
				{
					if (hashtable.ContainsKey(parameterInfo.Name + "REF"))
					{
						arrayList.Add(hashtable[parameterInfo.Name + "REF"]);
						hashtable.Remove(parameterInfo.Name + "REF");
					}
					if (hashtable.ContainsKey(parameterInfo.Name))
					{
						arrayList.Add(hashtable[parameterInfo.Name]);
						hashtable.Remove(parameterInfo.Name);
					}
				}
				else if (hashtable.ContainsKey(parameterInfo.Name))
				{
					arrayList.Add(hashtable[parameterInfo.Name]);
					hashtable.Remove(parameterInfo.Name);
				}
			}
			ArrayList arrayList2 = new ArrayList();
			foreach (string key2 in hashtable.Keys)
			{
				arrayList2.Add(key2);
			}
			arrayList2.Sort();
			foreach (string item in arrayList2)
			{
				arrayList.Add(hashtable[item]);
			}
			return arrayList;
		}
	}

	public bool Static
	{
		get
		{
			return isStatic;
		}
		set
		{
			isStatic = value;
		}
	}

	public bool PropertyMethod
	{
		get
		{
			return isPropertyMethod;
		}
		set
		{
			isPropertyMethod = value;
		}
	}

	public TestMethod()
	{
	}

	public TestMethod(MethodInfo info, out bool created)
	{
		created = true;
		name = info.Name;
		this.info = info;
		isSystemMethod = SystemMethod(info);
		object[] customAttributes = info.GetCustomAttributes(typeof(QTMTest), inherit: false);
		if (customAttributes.Length > 0 && customAttributes[0] is QTMTest)
		{
			QTMTest qTMTest = (QTMTest)customAttributes[0];
			description = qTMTest.Description;
			errorCode = qTMTest.ErrorCode;
			canAddToTestPlan = qTMTest.CanAddToTestPlan;
			isSetupTest = qTMTest.IsSetupTest;
			isTearDownTest = qTMTest.IsTearDownTest;
			isManual = qTMTest.IsManual;
		}
		if (info.IsStatic)
		{
			isStatic = true;
		}
		if (name.StartsWith("get_") || name.StartsWith("set_"))
		{
			isPropertyMethod = true;
		}
		ParameterInfo[] array = info.GetParameters();
		foreach (ParameterInfo parameterInfo in array)
		{
			if (!AddParameter(parameterInfo, IsReturnType: false))
			{
				created = false;
			}
		}
		AddParameter(info.ReturnParameter, IsReturnType: true);
	}

	private bool AddParameter(ParameterInfo parameterInfo, bool IsReturnType)
	{
		try
		{
			TestParameter testParameter = new TestParameter(parameterInfo.Name);
			testParameter.Type = parameterInfo.ParameterType;
			if (IsReturnType && testParameter.DataType == "Boolean")
			{
				return true;
			}
			if (testParameter.Name == null)
			{
				testParameter.Name = "ReturnValue";
			}
			if (parameterInfo.IsOut)
			{
				testParameter.IOType = "Output";
				testParameter.IsRef = false;
			}
			if (testParameter.DataType != null)
			{
				testParameter.Position = parameterInfo.Position;
				testParameter.CheckedState = CheckState.Checked;
				testParameter.Argument = true;
				if (testParameter.IsRef)
				{
					TestParameter testParameter2 = testParameter.Clone();
					testParameter2.IOType = "Output";
					testParameter2.IsVirtual = true;
					if (!parameters.Contains(testParameter2.Name))
					{
						parameters.Add(testParameter2.Name, testParameter2);
					}
					testParameter.Name += "REF";
				}
				if (IsReturnType)
				{
					testParameter.IOType = "Output";
					testParameter.Argument = false;
					testParameter.HasAttributes = true;
					testParameter.ReturnValue = true;
				}
				if (!parameters.Contains(testParameter.Name))
				{
					parameters.Add(testParameter.Name, testParameter);
				}
				return true;
			}
		}
		catch
		{
		}
		return false;
	}

	public bool AddProperty(TestProperty testProperty)
	{
		try
		{
			if (!Static)
			{
				if (PropertyMethod)
				{
					string text = Name.Substring(4, Name.Length - 4);
					if (text.Trim() == testProperty.Name)
					{
						return false;
					}
				}
				if (!Parameters.Contains(testProperty.Parameter.Name))
				{
					parameters.Add(testProperty.Parameter.Name, testProperty.Parameter.Clone());
					return true;
				}
			}
		}
		catch
		{
		}
		return false;
	}

	private bool SystemMethod(MethodInfo methodInfo)
	{
		try
		{
			switch (methodInfo.Name)
			{
			case "GetHashCode":
			case "Equals":
			case "ToString":
			case "GetType":
				return true;
			}
		}
		catch
		{
		}
		return false;
	}

	private void UpdateArgumentParameters(Attribute mAttr)
	{
		try
		{
			QTMParameter qTMParameter = (QTMParameter)mAttr;
			foreach (TestParameter value in Parameters.Values)
			{
				if (value.Name == qTMParameter.ArgumentName)
				{
					if (value.IsArray)
					{
						value.NumberOfElements = qTMParameter.NumberOfElements;
					}
					else
					{
						value.NumberOfElements = 1;
					}
					SetParamAttributes(qTMParameter, value);
					break;
				}
			}
		}
		catch (Exception ex)
		{
			throw new Exception("UpdateArgumentParameters failed, " + ex.Message);
		}
	}

	public static void SetParamAttributes(QTMParameter qParameter, TestParameter parameter)
	{
		if (parameter.Value.Trim().Length == 0)
		{
			for (int i = 0; i < parameter.NumberOfElements; i++)
			{
				string text = qParameter.DefaultValue;
				if (parameter.Type.IsEnum)
				{
					try
					{
						text = ((int)Enum.Parse(parameter.Type, qParameter.DefaultValue)).ToString();
					}
					catch
					{
					}
				}
				if (i == 0)
				{
					parameter.Value = text;
					parameter.UpperLimit = qParameter.UpperLimit;
					parameter.LowerLimit = qParameter.LowerLimit;
				}
				else
				{
					parameter.Value = parameter.Value + "," + text;
					parameter.UpperLimit = parameter.UpperLimit + "," + qParameter.UpperLimit;
					parameter.LowerLimit = parameter.LowerLimit + "," + qParameter.LowerLimit;
				}
			}
		}
		parameter.UnitOfMeasure = qParameter.UnitOfMeasure;
		parameter.Description = qParameter.Description;
		parameter.ParentName = qParameter.ParentName;
		parameter.DisplayName = (string.IsNullOrEmpty(qParameter.DisplayName) ? string.Empty : qParameter.DisplayName);
		parameter.IsEditableInTestPlan = qParameter.IsEditableInTestPlan;
		parameter.CanEditResultValue = qParameter.CanEditResultValue;
		if (!parameter.Type.IsEnum)
		{
			parameter.DisplayHint = qParameter.DisplayHint;
			parameter.Constraints = qParameter.Constraints;
		}
	}

	public void ApplyAttributes()
	{
		try
		{
			if (Parent.IsTestClass && !PropertyMethod)
			{
				isTestMethod = true;
				selected = true;
			}
			object[] customAttributes = info.GetCustomAttributes(inherit: false);
			object[] array = customAttributes;
			for (int i = 0; i < array.Length; i++)
			{
				Attribute attribute = (Attribute)array[i];
				if (attribute is QTMTest)
				{
					QTMTest qTMTest = (QTMTest)attribute;
					isTestMethod = qTMTest.IsQTMTest;
					if (qTMTest.IsQTMTest)
					{
						selected = true;
					}
					else
					{
						selected = false;
					}
				}
				else if (attribute is QTMParameter)
				{
					UpdateArgumentParameters(attribute);
				}
			}
			foreach (TestProperty value in Parent.Properties.Values)
			{
				if (!value.IsTestParameter || !Parameters.Contains(value.Name))
				{
					continue;
				}
				TestParameter testParameter = (TestParameter)parameters[value.Name];
				if (testParameter.Position != -1)
				{
					continue;
				}
				testParameter.HasAttributes = true;
				if (value.Contains(Name))
				{
					testParameter.CheckedState = CheckState.Checked;
				}
				testParameter.Value = value.Parameter.Value;
				if (testParameter.IOType != value.Parameter.IOType)
				{
					if (value.Parameter.IOType == "Output")
					{
						if (value.PropertyInfo.CanRead)
						{
							testParameter.IOType = value.Parameter.IOType;
						}
					}
					else if (value.Parameter.IOType == "Input" && value.PropertyInfo.CanWrite)
					{
						testParameter.IOType = value.Parameter.IOType;
					}
				}
				testParameter.Description = value.Parameter.Description;
				testParameter.DisplayHint = value.Parameter.DisplayHint;
				testParameter.Constraints = value.Parameter.Constraints;
				testParameter.UnitOfMeasure = value.Parameter.UnitOfMeasure;
				testParameter.UpperLimit = value.Parameter.UpperLimit;
				testParameter.LowerLimit = value.Parameter.LowerLimit;
				testParameter.NumberOfElements = value.Parameter.NumberOfElements;
				testParameter.ParentName = value.Parameter.ParentName;
				testParameter.DisplayName = (string.IsNullOrEmpty(value.Parameter.DisplayName) ? string.Empty : value.Parameter.DisplayName);
				testParameter.IsEditableInTestPlan = value.Parameter.IsEditableInTestPlan;
				testParameter.CanEditResultValue = value.Parameter.CanEditResultValue;
			}
		}
		catch
		{
		}
	}

	public Hashtable GetArguments(bool virtualAlso)
	{
		try
		{
			Hashtable hashtable = new Hashtable();
			foreach (TestParameter value in Parameters.Values)
			{
				if (value.Argument && !value.IsVirtual)
				{
					hashtable.Add(value.Name, value);
				}
				else if (value.Argument && virtualAlso)
				{
					hashtable.Add(value.Name, value);
				}
			}
			return hashtable;
		}
		catch
		{
		}
		return null;
	}

	public ArrayList GetArgumentsList()
	{
		try
		{
			Hashtable hashtable = new Hashtable();
			foreach (TestParameter value in Parameters.Values)
			{
				if (value.Argument)
				{
					hashtable.Add(value.Name, value);
				}
			}
			ArrayList arrayList = new ArrayList();
			ParameterInfo[] array = info.GetParameters();
			foreach (ParameterInfo parameterInfo in array)
			{
				if (parameterInfo.ParameterType.IsByRef)
				{
					if (hashtable.ContainsKey(parameterInfo.Name + "REF"))
					{
						arrayList.Add(hashtable[parameterInfo.Name + "REF"]);
					}
					if (hashtable.ContainsKey(parameterInfo.Name))
					{
						arrayList.Add(hashtable[parameterInfo.Name]);
					}
				}
				else if (hashtable.ContainsKey(parameterInfo.Name))
				{
					arrayList.Add(hashtable[parameterInfo.Name]);
				}
			}
			return arrayList;
		}
		catch
		{
		}
		return null;
	}

	public Hashtable GetInputProperties()
	{
		try
		{
			Hashtable hashtable = new Hashtable();
			foreach (TestParameter value in Parameters.Values)
			{
				if (!value.Argument && value.CheckedState == CheckState.Checked && value.IOType == "Input")
				{
					hashtable.Add(value.Name, value);
				}
			}
			return hashtable;
		}
		catch
		{
		}
		return null;
	}

	public Hashtable GetOutputProperties()
	{
		try
		{
			Hashtable hashtable = new Hashtable();
			foreach (TestParameter value in Parameters.Values)
			{
				if (!value.Argument && value.CheckedState == CheckState.Checked && value.IOType == "Output")
				{
					hashtable.Add(value.Name, value);
				}
			}
			return hashtable;
		}
		catch
		{
		}
		return null;
	}

	public void SetDynamicOutputParameters()
	{
		try
		{
			try
			{
				ArrayList additionalOutputParamaters = Environment.QTMInfo.GetAdditionalOutputParamaters();
				if (additionalOutputParamaters.Count <= 0)
				{
					return;
				}
				foreach (ParamValue item in additionalOutputParamaters)
				{
					TestParameter testParameterFromParamValue = GetTestParameterFromParamValue(item);
					if (!parameters.ContainsKey(testParameterFromParamValue.Name))
					{
						parameters.Add(testParameterFromParamValue.Name, testParameterFromParamValue);
					}
					else
					{
						parameters[testParameterFromParamValue.Name] = testParameterFromParamValue;
					}
				}
			}
			catch
			{
			}
		}
		catch
		{
		}
	}

	private TestParameter GetTestParameterFromParamValue(ParamValue p)
	{
		TestParameter testParameter = new TestParameter();
		testParameter.Name = (string.IsNullOrEmpty(p.RealName) ? p.ParamName : p.RealName);
		testParameter.DataType = "String";
		testParameter.NumberOfElements = p.NumElements;
		if (p.Value != null && p.Value.Count > 0)
		{
			testParameter.Value = string.Join(",", (from o in p.Value.ToArray()
				select o.ToString()).ToArray());
		}
		if (p.DataTableValue != null)
		{
			testParameter.DataTableValue = p.DataTableValue;
		}
		testParameter.IOType = p.IOType.ToString();
		if (p.UL != null && p.UL.Count > 0)
		{
			testParameter.UpperLimit = string.Join(",", (from o in p.UL.ToArray()
				select o.ToString()).ToArray());
		}
		if (p.LL != null && p.LL.Count > 0)
		{
			testParameter.LowerLimit = string.Join(",", (from o in p.LL.ToArray()
				select o.ToString()).ToArray());
		}
		testParameter.UnitOfMeasure = ((p.Unit == null) ? string.Empty : p.Unit);
		testParameter.Description = ((p.Desc == null) ? string.Empty : p.Desc);
		testParameter.Constraints = ((p.Constraint == null) ? string.Empty : p.Constraint);
		testParameter.DisplayHint = (QC.QTMDotNetKernelInterface.DisplayHints)p.DispHint;
		testParameter.CheckedState = CheckState.Checked;
		testParameter.IsNullable = false;
		testParameter.ParentName = ((p.ParentName == null) ? string.Empty : p.ParentName);
		testParameter.DisplayName = (string.IsNullOrEmpty(p.ParamName) ? string.Empty : p.ParamName);
		testParameter.IsArray = p.Value.Count > 1;
		testParameter.NumberOfElements = p.Value.Count;
		testParameter.IsEditableInTestPlan = false;
		return testParameter;
	}

	public Hashtable GetCustomProperties()
	{
		try
		{
			Hashtable hashtable = new Hashtable();
			foreach (TestParameter value in Parameters.Values)
			{
				if (value.HasAttributes)
				{
					hashtable.Add(value.Name, value);
				}
			}
			return hashtable;
		}
		catch
		{
		}
		return null;
	}

	public Hashtable GetNonCustomProperties()
	{
		try
		{
			Hashtable hashtable = new Hashtable();
			foreach (TestParameter value in Parameters.Values)
			{
				if (!value.HasAttributes && !value.Argument)
				{
					hashtable.Add(value.Name, value);
				}
			}
			return hashtable;
		}
		catch
		{
		}
		return null;
	}

	public void Reset()
	{
		try
		{
			foreach (TestParameter value in Parameters.Values)
			{
				value.Reset();
			}
		}
		catch
		{
		}
	}

	public void ClearSelections()
	{
		try
		{
			foreach (TestParameter value in Parameters.Values)
			{
				value.Clear();
			}
		}
		catch
		{
		}
	}

	public void CreateParameterSelections(object qParameter)
	{
		try
		{
			Hashtable hashtable = ParameterHandler.CreateParameters(qParameter);
			foreach (TestParameter value in hashtable.Values)
			{
				if (Parameters.Contains(value.Name))
				{
					TestParameter testParameter2 = (TestParameter)Parameters[value.Name];
					testParameter2.CheckedState = value.CheckedState;
				}
			}
		}
		catch
		{
		}
	}
}
