using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.InteropServices;
using System.Threading;

namespace QCRPG.Framework;

public abstract class ConnectionUsbBase : ConnectionBase
{
	protected const uint GENERIC_READ = 2147483648u;

	protected const uint GENERIC_WRITE = 1073741824u;

	protected const uint FILE_ATTRIBUTE_NORMAL = 128u;

	protected const uint FILE_FLAG_OVERLAPPED = 1073741824u;

	protected const int ERROR_IO_PENDING = 997;

	protected const int ERROR_NOT_FOUND = 1168;

	protected const uint WAIT_TIMEOUT = 258u;

	protected const uint WAIT_FAILED = uint.MaxValue;

	protected IntPtr InvalidHandle = new IntPtr(-1);

	protected bool enableReceiveModeSwitchNotifications;

	public bool EnableReceiveModeSwitchNotifications
	{
		get
		{
			return enableReceiveModeSwitchNotifications;
		}
		set
		{
			enableReceiveModeSwitchNotifications = value;
		}
	}

	[DllImport("kernel32.dll", BestFitMapping = false, CharSet = CharSet.Auto, SetLastError = true)]
	protected static extern IntPtr CreateFile(string lpFileName, uint dwDesiredAccess, FileShare dwShareMode, IntPtr securityAttrs, FileMode dwCreationDisposition, uint dwFlagsAndAttributes, IntPtr hTemplateFile);

	[DllImport("kernel32.dll", SetLastError = true)]
	protected unsafe static extern bool ReadFile(IntPtr handle, byte* bytes, int numBytesToRead, int* lpNumberOfBytesRead, NativeOverlapped* overlapped);

	[DllImport("kernel32.dll", SetLastError = true)]
	protected unsafe static extern bool WriteFile(IntPtr handle, byte* bytes, int numBytesToWrite, int* numBytesWritten, NativeOverlapped* lpOverlapped);

	[DllImport("kernel32.dll", SetLastError = true)]
	protected unsafe static extern bool CancelIoEx(IntPtr handle, NativeOverlapped* lpOverlapped);

	[DllImport("kernel32.dll", SetLastError = true)]
	protected static extern bool CancelIoEx(IntPtr handle, IntPtr mustBeZero);

	[DllImport("kernel32.dll", SetLastError = true)]
	protected unsafe static extern bool DeviceIoControl(IntPtr fileHandle, uint ioControlCode, IntPtr inBuffer, int cbInBuffer, IntPtr outBuffer, int cbOutBuffer, int* cbBytesReturned, NativeOverlapped* overlapped);

	[DllImport("kernel32.dll", SetLastError = true)]
	protected unsafe static extern bool DeviceIoControl(IntPtr fileHandle, uint ioControlCode, byte* inBuffer, int cbInBuffer, IntPtr outBuffer, int cbOutBuffer, int* cbBytesReturned, NativeOverlapped* overlapped);

	[DllImport("kernel32.dll", SetLastError = true)]
	protected unsafe static extern bool DeviceIoControl(IntPtr fileHandle, uint ioControlCode, IntPtr inBuffer, int cbInBuffer, byte* outBuffer, int cbOutBuffer, int* cbBytesReturned, NativeOverlapped* overlapped);

	[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
	protected unsafe static extern bool GetOverlappedResult(IntPtr hFile, NativeOverlapped* lpOverlapped, int* numberOfBytesTransferred, bool bWait);

	[DllImport("kernel32.dll", BestFitMapping = false, CharSet = CharSet.Auto, SetLastError = true)]
	protected static extern IntPtr CreateEvent(IntPtr lpEventAttributes, bool bManualReset, bool bInitialState, string lpName);

	[DllImport("kernel32.dll", SetLastError = true)]
	protected static extern bool ResetEvent(IntPtr hEvent);

	[DllImport("kernel32.dll", CharSet = CharSet.Auto, ExactSpelling = true, SetLastError = true)]
	public static extern uint WaitForSingleObject([In] IntPtr hHandle, [In] int dwMilliseconds);

	[DllImport("kernel32.dll", SetLastError = true)]
	protected static extern bool CloseHandle(IntPtr hHandle);

	public abstract List<UsbDeviceInfo> FindDevices();

	public abstract void Open(UsbDeviceInfo deviceInfo);

	protected bool IsHandleValid(IntPtr handle)
	{
		return handle != InvalidHandle;
	}
}
