using System;
using System.IO;
using System.Runtime.ExceptionServices;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using SubSysRFCalibration_ServerLib;

namespace RFCalibration_CSharp;

internal class RFCalServer
{
	public enum RFCalServerMode
	{
		COM,
		DLL
	}

	public struct stm_assembly_info
	{
		private int index;

		[MarshalAs(UnmanagedType.ByValArray, SizeConst = 512)]
		private char[] name;

		[MarshalAs(UnmanagedType.ByValArray, SizeConst = 512)]
		private char[] fileAndPath;
	}

	[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
	public delegate void evt_handler(IntPtr context, int type, [MarshalAs(UnmanagedType.LPStr)] string msg);

	private const string cRFCalAppName = "RFCal";

	public string sRFCalAppPath = "C:\\HTE\\tools\\SUITE-3G-EV\\Bin\\SubSysRFCalibration_Server.dll";

	private RFCalServerMode m_mode;

	private ServerEvent m_serverEvent;

	private RFCalibration m_RFCalCOM;

	private IntPtr m_iSTM;

	private stm_assembly_info m_assemblyInfo;

	private evt_handler m_evt_handler;

	public RFCalServer(RFCalServerMode mode, string sRFCalAppName, string sServerDLLPath)
	{
		m_mode = mode;
		switch (mode)
		{
		case RFCalServerMode.COM:
			m_RFCalCOM = (RFCalibration)Activator.CreateInstance(Type.GetTypeFromCLSID(new Guid("17137611-1156-4B4E-8BFF-FD771A4B6219")));
			break;
		case RFCalServerMode.DLL:
		{
			string directoryName = Path.GetDirectoryName(sServerDLLPath);
			Environment.SetEnvironmentVariable("PATH", Environment.GetEnvironmentVariable("PATH") + ";" + directoryName);
			m_iSTM = stm_create_suite_manager_interface();
			if (stm_add_reference_assembly(m_iSTM, sRFCalAppName, sServerDLLPath) == 0)
			{
				throw new Exception("Failed to load: " + sRFCalAppPath);
			}
			if (stm_create_application(m_iSTM, sRFCalAppName, ref m_assemblyInfo) == 0)
			{
				throw new Exception("Failed to load: " + sRFCalAppPath);
			}
			break;
		}
		}
		m_serverEvent = new ServerEvent();
		m_evt_handler = EventHandler;
	}

	~RFCalServer()
	{
		switch (m_mode)
		{
		case RFCalServerMode.DLL:
			stm_clear_test_db(m_iSTM, ref m_assemblyInfo);
			stm_clear_assembly_tbl(m_iSTM);
			stm_release_suite_manager_interface(ref m_iSTM);
			break;
		case RFCalServerMode.COM:
			break;
		}
	}

	public void SetEnvironmentVar(string name, string value)
	{
		if (m_mode == RFCalServerMode.DLL)
		{
			stm_set_environment_var(m_iSTM, ref m_assemblyInfo, name, value);
		}
	}

	public void SetLogFilename(string logFileName)
	{
		switch (m_mode)
		{
		case RFCalServerMode.COM:
			m_RFCalCOM.SetLogFilename(logFileName);
			break;
		case RFCalServerMode.DLL:
			stm_set_log_filename(m_iSTM, ref m_assemblyInfo, logFileName);
			break;
		}
	}

	public void RegisterCallbacks(MainForm form, int iDUT_Index)
	{
		m_serverEvent.form = form;
		m_serverEvent.iDUT_Index = iDUT_Index;
		switch (m_mode)
		{
		case RFCalServerMode.COM:
			new ComAwareEventInfo(typeof(_ICommonSuiteServerEvents_Event), "ReceiveMessageLog").AddEventHandler(m_RFCalCOM, new _ICommonSuiteServerEvents_ReceiveMessageLogEventHandler(m_serverEvent.ReceiveMessageLog));
			new ComAwareEventInfo(typeof(_ICommonSuiteServerEvents_Event), "ReceiveMessageDebug").AddEventHandler(m_RFCalCOM, new _ICommonSuiteServerEvents_ReceiveMessageDebugEventHandler(m_serverEvent.ReceiveMessageDebug));
			new ComAwareEventInfo(typeof(_ICommonSuiteServerEvents_Event), "ReceiveMessageError").AddEventHandler(m_RFCalCOM, new _ICommonSuiteServerEvents_ReceiveMessageErrorEventHandler(m_serverEvent.ReceiveMessageError));
			new ComAwareEventInfo(typeof(_ICommonSuiteServerEvents_Event), "ReceiveMessageTPL3").AddEventHandler(m_RFCalCOM, new _ICommonSuiteServerEvents_ReceiveMessageTPL3EventHandler(m_serverEvent.ReceiveMessageTPL3));
			new ComAwareEventInfo(typeof(_ICommonSuiteServerEvents_Event), "ReceiveMessageHTML").AddEventHandler(m_RFCalCOM, new _ICommonSuiteServerEvents_ReceiveMessageHTMLEventHandler(m_serverEvent.ReceiveMessageHTML));
			break;
		case RFCalServerMode.DLL:
		{
			GCHandle value = GCHandle.Alloc(this, GCHandleType.Normal);
			IntPtr context = GCHandle.ToIntPtr(value);
			stm_register_system_event_handler(m_iSTM, ref m_assemblyInfo, context, m_evt_handler);
			break;
		}
		}
	}

	public int AddTest(string name, string realName)
	{
		int result = 0;
		switch (m_mode)
		{
		case RFCalServerMode.COM:
			result = m_RFCalCOM.AddTest(name, realName);
			break;
		case RFCalServerMode.DLL:
			result = stm_add_test(m_iSTM, ref m_assemblyInfo, name, realName);
			break;
		}
		return result;
	}

	public void AddParameter(int testID, string paramName, string paramValue, string paramUpperLimit, string paramLowerLimit, string paramMode)
	{
		switch (m_mode)
		{
		case RFCalServerMode.COM:
			m_RFCalCOM.AddParameter(testID, paramName, paramValue, paramUpperLimit, paramLowerLimit, paramMode);
			break;
		case RFCalServerMode.DLL:
			stm_add_parameter(m_iSTM, ref m_assemblyInfo, testID, paramName, paramValue, paramUpperLimit, paramLowerLimit, paramMode);
			break;
		}
	}

	[HandleProcessCorruptedStateExceptions]
	public short ExecuteTestId(int testID)
	{
		short result = 0;
		try
		{
			switch (m_mode)
			{
			case RFCalServerMode.COM:
				result = m_RFCalCOM.ExecuteTestId(testID);
				break;
			case RFCalServerMode.DLL:
				result = (short)stm_execute_test_id(m_iSTM, ref m_assemblyInfo, testID);
				break;
			}
		}
		catch (Exception ex)
		{
			MessageBox.Show(ex.Message);
		}
		return result;
	}

	private static void EventHandler(IntPtr context, int type, string msg)
	{
		RFCalServer rFCalServer = (RFCalServer)GCHandle.FromIntPtr(context).Target;
		switch (type)
		{
		case 1:
			rFCalServer.m_serverEvent.ReceiveMessageDebug(msg);
			break;
		case 2:
			rFCalServer.m_serverEvent.ReceiveMessageLog(msg);
			break;
		case 3:
			rFCalServer.m_serverEvent.ReceiveMessageError(msg);
			break;
		case 4:
			rFCalServer.m_serverEvent.ReceiveMessageTPL3(msg);
			break;
		case 5:
			rFCalServer.m_serverEvent.ReceiveMessageHTML(msg);
			break;
		}
	}

	[DllImport("SuiteTestManager.dll", CallingConvention = CallingConvention.Cdecl)]
	public static extern IntPtr stm_create_suite_manager_interface();

	[DllImport("SuiteTestManager.dll", CallingConvention = CallingConvention.Cdecl)]
	public static extern void stm_release_suite_manager_interface(ref IntPtr iface);

	[DllImport("SuiteTestManager.dll", CallingConvention = CallingConvention.Cdecl)]
	public static extern int stm_add_reference_assembly(IntPtr iface, [MarshalAs(UnmanagedType.LPStr)] string name, [MarshalAs(UnmanagedType.LPStr)] string fileAndPath);

	[DllImport("SuiteTestManager.dll", CallingConvention = CallingConvention.Cdecl)]
	public static extern int stm_create_application(IntPtr iface, [MarshalAs(UnmanagedType.LPStr)] string name, ref stm_assembly_info info);

	[DllImport("SuiteTestManager.dll", CallingConvention = CallingConvention.Cdecl)]
	public static extern void stm_clear_assembly_tbl(IntPtr iface);

	[DllImport("SuiteTestManager.dll", CallingConvention = CallingConvention.Cdecl)]
	public static extern void stm_add_station_config_item(IntPtr iface, ref stm_assembly_info asmInfo, int itemGroup, [MarshalAs(UnmanagedType.LPStr)] string name, [MarshalAs(UnmanagedType.LPStr)] string value);

	[DllImport("SuiteTestManager.dll", CallingConvention = CallingConvention.Cdecl)]
	public static extern void stm_clear_station_config(IntPtr iface, ref stm_assembly_info asmInfo);

	[DllImport("SuiteTestManager.dll", CallingConvention = CallingConvention.Cdecl)]
	public static extern void stm_add_gpib_equip_config_item(IntPtr iface, ref stm_assembly_info asmInfo, [MarshalAs(UnmanagedType.LPStr)] string identifier, [MarshalAs(UnmanagedType.LPStr)] string name, [MarshalAs(UnmanagedType.LPStr)] string type, [MarshalAs(UnmanagedType.LPStr)] string pad, [MarshalAs(UnmanagedType.LPStr)] string sad, [MarshalAs(UnmanagedType.LPStr)] string options);

	[DllImport("SuiteTestManager.dll", CallingConvention = CallingConvention.Cdecl)]
	public static extern void stm_add_visa_equip_config_item(IntPtr iface, ref stm_assembly_info asmInfo, [MarshalAs(UnmanagedType.LPStr)] string identifier, [MarshalAs(UnmanagedType.LPStr)] string name, [MarshalAs(UnmanagedType.LPStr)] string type, [MarshalAs(UnmanagedType.LPStr)] string address, [MarshalAs(UnmanagedType.LPStr)] string options);

	[DllImport("SuiteTestManager.dll", CallingConvention = CallingConvention.Cdecl)]
	public static extern void stm_add_ip_equip_config_item(IntPtr iface, ref stm_assembly_info asmInfo, [MarshalAs(UnmanagedType.LPStr)] string identifier, [MarshalAs(UnmanagedType.LPStr)] string name, [MarshalAs(UnmanagedType.LPStr)] string type, [MarshalAs(UnmanagedType.LPStr)] string instrument, [MarshalAs(UnmanagedType.LPStr)] string address, [MarshalAs(UnmanagedType.LPStr)] string options);

	[DllImport("SuiteTestManager.dll", CallingConvention = CallingConvention.Cdecl)]
	public static extern void stm_add_rs232_equip_config_item(IntPtr iface, ref stm_assembly_info asmInfo, [MarshalAs(UnmanagedType.LPStr)] string identifier, [MarshalAs(UnmanagedType.LPStr)] string name, [MarshalAs(UnmanagedType.LPStr)] string type, [MarshalAs(UnmanagedType.LPStr)] string comport, [MarshalAs(UnmanagedType.LPStr)] string options);

	[DllImport("SuiteTestManager.dll", CallingConvention = CallingConvention.Cdecl)]
	public static extern void stm_clear_equip_config(IntPtr iface, ref stm_assembly_info asmInfo);

	[DllImport("SuiteTestManager.dll", CallingConvention = CallingConvention.Cdecl)]
	public static extern void stm_request_single_test_log(IntPtr iface, ref stm_assembly_info asmInfo, int mode, [MarshalAs(UnmanagedType.LPStr)] ref string value);

	[DllImport("SuiteTestManager.dll", CallingConvention = CallingConvention.Cdecl)]
	public static extern void stm_request_test_log_id(IntPtr iface, ref stm_assembly_info asmInfo, int mode, int testId, [MarshalAs(UnmanagedType.LPStr)] ref string value);

	[DllImport("SuiteTestManager.dll", CallingConvention = CallingConvention.Cdecl)]
	public static extern void stm_request_test_log_name(IntPtr iface, ref stm_assembly_info asmInfo, int mode, [MarshalAs(UnmanagedType.LPStr)] string testName, [MarshalAs(UnmanagedType.LPStr)] ref string value);

	[DllImport("SuiteTestManager.dll", CallingConvention = CallingConvention.Cdecl)]
	public static extern void stm_request_complete_test_log(IntPtr iface, ref stm_assembly_info asmInfo, int mode, [MarshalAs(UnmanagedType.LPStr)] ref string value);

	[DllImport("SuiteTestManager.dll", CallingConvention = CallingConvention.Cdecl)]
	public static extern void stm_load_single_rf_net_loss(IntPtr iface, ref stm_assembly_info asmInfo, double freqMhz, double lossDb);

	[DllImport("SuiteTestManager.dll", CallingConvention = CallingConvention.Cdecl)]
	public static extern void stm_load_multiple_rf_net_loss(IntPtr iface, ref stm_assembly_info asmInfo, int path, double freqMhz, double lossDb);

	[DllImport("SuiteTestManager.dll", CallingConvention = CallingConvention.Cdecl)]
	public static extern void stm_clear_rf_net_loss(IntPtr iface, ref stm_assembly_info asmInfo);

	[DllImport("SuiteTestManager.dll", CallingConvention = CallingConvention.Cdecl)]
	public static extern void stm_set_log_filename(IntPtr iface, ref stm_assembly_info asmInfo, [MarshalAs(UnmanagedType.LPStr)] string name);

	[DllImport("SuiteTestManager.dll", CallingConvention = CallingConvention.Cdecl)]
	public static extern void stm_set_environment_var(IntPtr iface, ref stm_assembly_info asmInfo, [MarshalAs(UnmanagedType.LPStr)] string key, [MarshalAs(UnmanagedType.LPStr)] string value);

	[DllImport("SuiteTestManager.dll", CallingConvention = CallingConvention.Cdecl)]
	public static extern IntPtr stm_get_environment_var(IntPtr iface, ref stm_assembly_info asmInfo, [MarshalAs(UnmanagedType.LPStr)] string key);

	[DllImport("SuiteTestManager.dll", CallingConvention = CallingConvention.Cdecl)]
	public static extern void stm_register_system_event_handler(IntPtr iface, ref stm_assembly_info asmInfo, IntPtr context, [MarshalAs(UnmanagedType.FunctionPtr)] evt_handler functionCallback);

	[DllImport("SuiteTestManager.dll", CallingConvention = CallingConvention.Cdecl)]
	public static extern int stm_execute(IntPtr iface, ref stm_assembly_info asmInfo, [MarshalAs(UnmanagedType.LPStr)] string testname, [MarshalAs(UnmanagedType.LPStr)] string realname, [MarshalAs(UnmanagedType.LPStr)] ref string arrParamKeys, int keysCount, [MarshalAs(UnmanagedType.LPStr)] ref string arrParamValues, int valuesCount);

	[DllImport("SuiteTestManager.dll", CallingConvention = CallingConvention.Cdecl)]
	public static extern void stm_clear_test_db(IntPtr iface, ref stm_assembly_info asmInfo);

	[DllImport("SuiteTestManager.dll", CallingConvention = CallingConvention.Cdecl)]
	public static extern int stm_add_test(IntPtr iface, ref stm_assembly_info asmInfo, [MarshalAs(UnmanagedType.LPStr)] string testName, [MarshalAs(UnmanagedType.LPStr)] string realName);

	[DllImport("SuiteTestManager.dll", CallingConvention = CallingConvention.Cdecl)]
	public static extern void stm_add_parameter(IntPtr iface, ref stm_assembly_info asmInfo, int testId, [MarshalAs(UnmanagedType.LPStr)] string parameterName, [MarshalAs(UnmanagedType.LPStr)] string parameterValue, [MarshalAs(UnmanagedType.LPStr)] string upperlimit, [MarshalAs(UnmanagedType.LPStr)] string lowerlimit, [MarshalAs(UnmanagedType.LPStr)] string paramMode);

	[DllImport("SuiteTestManager.dll", CallingConvention = CallingConvention.Cdecl)]
	public static extern void stm_get_test_list(IntPtr iface, ref stm_assembly_info asmInfo, int verbose, [MarshalAs(UnmanagedType.LPStr)] ref string arrTestList, ref int count);

	[DllImport("SuiteTestManager.dll", CallingConvention = CallingConvention.Cdecl)]
	public static extern int stm_execute_test_id(IntPtr iface, ref stm_assembly_info asmInfo, int testId);

	[DllImport("SuiteTestManager.dll", CallingConvention = CallingConvention.Cdecl)]
	public static extern int stm_execute_all(IntPtr iface, ref stm_assembly_info asmInfo);

	[DllImport("SuiteTestManager.dll", CallingConvention = CallingConvention.Cdecl)]
	public static extern int stm_execute_test_name(IntPtr iface, ref stm_assembly_info asmInfo, [MarshalAs(UnmanagedType.LPStr)] string testName);
}
