using System;
using System.Windows.Forms;

namespace QCRPG.Framework;

public class DUTSpecificGooier : GooierBase, IConfigurable
{
	protected const string menuTextSleepMode = "Sleep Mode";

	protected const string menuTextSetSleepModeNone = "Sleep Mode: None";

	protected const string menuTextSetSleepModeInBandNormal = "Sleep Mode: In Band, Normal";

	protected const string menuTextSetSleepModeInBandAlwaysAwake = "Sleep Mode: In Band, Always Awake";

	protected const string menuTextEnableSnoopLogs = "Enable Snoop Logs";

	protected const string menuTextSaveSnoopLogs = "Save Snoop Logs";

	protected const string menuTextClearSnoopLogs = "Reset/Clear Snoop Logs";

	protected const string menuTextStaticSnoopLogs = "Log to file";

	protected const string menuTextLiveImport = "Live Import";

	protected const string menuTextSnoopLiveLoggingConfig = "Snoop Live Import Config...";

	protected const string menuTextEnableSnoopLiveLogging = "Enable Snoop Live Logs";

	protected const string menuTextSnoopLogs = "BT Snoop Logs";

	private Configurer configurer;

	private DUTSpecificAPI dutSpecificAPI;

	private CommonConfigSettings commonConfigSettings;

	protected ToolStripItem setSleepModeNoneItem;

	protected ToolStripItem setSleepModeInBandNormalItem;

	protected ToolStripItem setSleepModeInBandAlwaysAwakeItem;

	protected readonly ToolStripMenuItem sleepModeMenu = new ToolStripMenuItem("Sleep Mode");

	protected string BTSnoopLiveImportDllFileName = "";

	protected string BTSnoopLiveImportIniFileName = "";

	private SnoopLiveLoggingConfig snoopLiveLoggingConfig;

	protected ToolStripItem setBTSnoopEnable;

	protected ToolStripItem setBTSnoopLiveEnable;

	protected readonly ToolStripMenuItem snoopStaticLogsMenu = new ToolStripMenuItem("Log to file");

	protected readonly ToolStripMenuItem snoopLiveImportMenu = new ToolStripMenuItem("Live Import");

	protected readonly ToolStripMenuItem snoopLogsMenu = new ToolStripMenuItem("BT Snoop Logs");

	private new string technologyName;

	public DUTSpecificGooier(string technologyName, Logger logger, Configurer configurer, DUTSpecificAPI dutSpecificAPI, CommonConfigSettings commonConfigSettings)
		: base(technologyName, logger)
	{
		this.configurer = configurer;
		this.dutSpecificAPI = dutSpecificAPI;
		this.commonConfigSettings = commonConfigSettings;
	}

	protected override void BuildDropDownMenu()
	{
		dropDownMenu.Text = "Config";
		AddDropDownMenuItems();
	}

	protected void AddDropDownMenuItems()
	{
		setSleepModeNoneItem = sleepModeMenu.DropDownItems.Add("Sleep Mode: None", null, SleepModeNoneHandler);
		((ToolStripMenuItem)setSleepModeNoneItem).Checked = true;
		setSleepModeInBandAlwaysAwakeItem = sleepModeMenu.DropDownItems.Add("Sleep Mode: In Band, Always Awake", null, SleepModeInBandAlwaysAwakeHandler);
		setSleepModeInBandNormalItem = sleepModeMenu.DropDownItems.Add("Sleep Mode: In Band, Normal", null, SleepModeInBandNormalHandler);
		dropDownMenu.DropDownItems.Add(sleepModeMenu);
		setBTSnoopEnable = snoopStaticLogsMenu.DropDownItems.Add("Enable Snoop Logs", null, EnableSnoopLogging);
		((ToolStripMenuItem)setBTSnoopEnable).Checked = false;
		snoopStaticLogsMenu.DropDownItems.Add("Save Snoop Logs", null, SaveSnoopLogs);
		snoopStaticLogsMenu.DropDownItems.Add("Reset/Clear Snoop Logs", null, ClearSnoopLogs);
		snoopLogsMenu.DropDownItems.Add(snoopStaticLogsMenu);
		dropDownMenu.DropDownItems.Add(new ToolStripSeparator());
		snoopLiveImportMenu.DropDownItems.Add("Snoop Live Import Config...", null, SnoopLiveLoggingConfig);
		setBTSnoopLiveEnable = snoopLiveImportMenu.DropDownItems.Add("Enable Snoop Live Logs", null, EnableLiveLogging);
		((ToolStripMenuItem)setBTSnoopLiveEnable).Checked = false;
		snoopLogsMenu.DropDownItems.Add(snoopLiveImportMenu);
		dropDownMenu.DropDownItems.Add(snoopLogsMenu);
	}

	private void SnoopLiveLoggingConfig(object sender, EventArgs e)
	{
		logger.Enqueue(new LogMessage(LogMessageType.Info, "Configure Snoop  live log on host"));
		snoopLiveLoggingConfig = new SnoopLiveLoggingConfig();
		snoopLiveLoggingConfig.LiveImportDllFile = BTSnoopLiveImportDllFileName;
		snoopLiveLoggingConfig.LiveImportIniFile = BTSnoopLiveImportIniFileName;
		snoopLiveLoggingConfig.ShowDialog();
		if (snoopLiveLoggingConfig.DialogResult == DialogResult.OK)
		{
			BTSnoopLiveImportDllFileName = snoopLiveLoggingConfig.LiveImportDllFile;
			BTSnoopLiveImportIniFileName = snoopLiveLoggingConfig.LiveImportIniFile;
		}
	}

	private void EnableLiveLogging(object sender, EventArgs e)
	{
		if (((ToolStripMenuItem)setBTSnoopLiveEnable).Checked)
		{
			try
			{
				dutSpecificAPI.SetSnoopLiveLogMode(enable: false, BTSnoopLiveImportDllFileName, BTSnoopLiveImportIniFileName);
				((ToolStripMenuItem)setBTSnoopLiveEnable).Checked = false;
				logger.NotifyObserver(new LogMessage(LogMessageType.Info, $"BT Snoop Live Logging Disabled"));
				commonConfigSettings.SnoopLiveLog = "false";
				return;
			}
			catch (Exception ex)
			{
				MessageBox.Show("Failed to disable live logging." + ex.Message);
				return;
			}
		}
		try
		{
			dutSpecificAPI.SetSnoopLiveLogMode(enable: true, BTSnoopLiveImportDllFileName, BTSnoopLiveImportIniFileName);
			((ToolStripMenuItem)setBTSnoopLiveEnable).Checked = true;
			logger.NotifyObserver(new LogMessage(LogMessageType.Info, $"BT Snoop Live Logging Enabled"));
			commonConfigSettings.SnoopLiveLog = "true";
		}
		catch (AppNotReadyException ex2)
		{
			MessageBox.Show(ex2.Message, "Warning: Frontline tool not ready", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
		}
		catch (FrontlineOccupiedException ex3)
		{
			MessageBox.Show(ex3.Message, "Warning: Frontline tool already connected to another instance", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
		}
		catch (Exception ex4)
		{
			MessageBox.Show("Failed to start live logging." + ex4.Message, "Warning: Unable to start live logging", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
		}
	}

	private void EnableSnoopLogging(object sender, EventArgs e)
	{
		try
		{
			if (((ToolStripMenuItem)setBTSnoopEnable).Checked)
			{
				logger.Enqueue(new LogMessage(LogMessageType.Info, "Snoop log  disabled on host"));
				((ToolStripMenuItem)setBTSnoopEnable).Checked = false;
				dutSpecificAPI.SetSnoopLogMode(enabled: false);
				commonConfigSettings.SnoopLog = "false";
			}
			else
			{
				((ToolStripMenuItem)setBTSnoopEnable).Checked = true;
				dutSpecificAPI.SetSnoopLogMode(enabled: true);
				commonConfigSettings.SnoopLog = "true";
				MessageBox.Show("This feature is meant to take BT Snoop raw data logs. If a long data transfer is ran then there is a possiblity to overrun memory needs!", "Warning: Enabling BT Snoop log capture", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
				logger.Enqueue(new LogMessage(LogMessageType.Info, "Snoop log  enabled on host"));
			}
		}
		catch (Exception ex)
		{
			logger.Enqueue(new LogMessage(LogMessageType.Error, ex));
			MessageBoxes.ShowErrorBox("Error setting in  Snoop Log");
		}
	}

	private void SaveSnoopLogs(object sender, EventArgs e)
	{
		SaveFileDialog saveFileDialog = new SaveFileDialog();
		saveFileDialog.DefaultExt = "*.cfa";
		saveFileDialog.Filter = "CFA files (*.cfa)|*.cfa|All files (*.*)|*.*";
		DialogResult dialogResult = saveFileDialog.ShowDialog();
		if (dialogResult != DialogResult.OK || string.IsNullOrEmpty(saveFileDialog.FileName))
		{
			return;
		}
		try
		{
			if (dutSpecificAPI.SaveSnooploginfile(saveFileDialog.FileName))
			{
				logger.Enqueue(new LogMessage(LogMessageType.Info, "Snoop log successfully saved"));
			}
			else
			{
				logger.Enqueue(new LogMessage(LogMessageType.Info, "Error in Saving Snoop log"));
			}
		}
		catch (Exception ex)
		{
			logger.Enqueue(new LogMessage(LogMessageType.Error, ex));
			MessageBoxes.ShowErrorBox("Error in saving Snoop Log");
		}
	}

	private void ClearSnoopLogs(object sender, EventArgs e)
	{
		try
		{
			dutSpecificAPI.ClearSnoopLog();
		}
		catch (Exception ex)
		{
			logger.Enqueue(new LogMessage(LogMessageType.Error, ex));
			MessageBoxes.ShowErrorBox("Error in clear Snoop Log");
		}
	}

	private void SleepModeNoneHandler(object sender, EventArgs e)
	{
		try
		{
			logger.Enqueue(new LogMessage(LogMessageType.Info, "Setting sleep mode on host to none"));
			dutSpecificAPI.SetSleepMode(ConnectionSpecificProtocolInfo.SleepModeState.NONE);
			((ToolStripMenuItem)setSleepModeNoneItem).Checked = true;
			((ToolStripMenuItem)setSleepModeInBandAlwaysAwakeItem).Checked = false;
			((ToolStripMenuItem)setSleepModeInBandNormalItem).Checked = false;
			commonConfigSettings.SleepModeOption = "NONE";
		}
		catch (Exception ex)
		{
			logger.Enqueue(new LogMessage(LogMessageType.Error, ex));
			MessageBoxes.ShowErrorBox("Error setting sleep mode");
		}
	}

	private void SleepModeInBandAlwaysAwakeHandler(object sender, EventArgs e)
	{
		try
		{
			logger.Enqueue(new LogMessage(LogMessageType.Info, "Setting sleep mode on host to in band, always awake"));
			dutSpecificAPI.SetSleepMode(ConnectionSpecificProtocolInfo.SleepModeState.IN_BAND_ALWAYS_AWAKE);
			((ToolStripMenuItem)setSleepModeNoneItem).Checked = false;
			((ToolStripMenuItem)setSleepModeInBandAlwaysAwakeItem).Checked = true;
			((ToolStripMenuItem)setSleepModeInBandNormalItem).Checked = false;
			commonConfigSettings.SleepModeOption = "ALWAYS_AWAKE";
		}
		catch (Exception ex)
		{
			logger.Enqueue(new LogMessage(LogMessageType.Error, ex));
			MessageBoxes.ShowErrorBox("Error setting sleep mode");
		}
	}

	private void SleepModeInBandNormalHandler(object sender, EventArgs e)
	{
		try
		{
			logger.Enqueue(new LogMessage(LogMessageType.Info, "Setting sleep mode on host to in band, normal"));
			dutSpecificAPI.SetSleepMode(ConnectionSpecificProtocolInfo.SleepModeState.IN_BAND_NORMAL_HANDLING);
			((ToolStripMenuItem)setSleepModeNoneItem).Checked = false;
			((ToolStripMenuItem)setSleepModeInBandAlwaysAwakeItem).Checked = false;
			((ToolStripMenuItem)setSleepModeInBandNormalItem).Checked = true;
			commonConfigSettings.SleepModeOption = "IN_BAND_SLEEP";
		}
		catch (Exception ex)
		{
			logger.Enqueue(new LogMessage(LogMessageType.Error, ex));
			MessageBoxes.ShowErrorBox("Error setting sleep mode");
		}
	}

	public Configuration GetConfiguration()
	{
		Configuration configuration = new Configuration();
		configuration.SetString("SleepModeOption", commonConfigSettings.SleepModeOption);
		configuration.SetString("BTSnoop_LiveImportDLL", BTSnoopLiveImportDllFileName);
		configuration.SetString("BTSnoop_LiveImportIni", BTSnoopLiveImportIniFileName);
		return configuration;
	}

	public void SetConfiguration(Configuration configuration)
	{
		commonConfigSettings.SleepModeOption = configuration.GetString("SleepModeOption", "NONE");
		if (commonConfigSettings.SleepModeOption == "NONE")
		{
			SleepModeNoneHandler(this, null);
		}
		else if (commonConfigSettings.SleepModeOption == "ALWAYS_AWAKE")
		{
			SleepModeInBandAlwaysAwakeHandler(this, null);
		}
		else if (commonConfigSettings.SleepModeOption == "IN_BAND_SLEEP")
		{
			SleepModeInBandNormalHandler(this, null);
		}
		BTSnoopLiveImportDllFileName = configuration.GetString("BTSnoop_LiveImportDLL", "");
		BTSnoopLiveImportIniFileName = configuration.GetString("BTSnoop_LiveImportIni", "");
	}
}
