using System;
using System.Collections.Generic;
using QCRPG.Framework;
using QCRPG.TSL.NFC.Packets;

namespace QCRPG.TSL.NFC;

public class NFCPacketHelper
{
	private NFCPacketList nfcPacketList;

	private Dictionary<uint, List<Type>> opCodeToPacketTypeMap = new Dictionary<uint, List<Type>>();

	public NFCPacketHelper(NFCPacketList nfcPacketList)
	{
		this.nfcPacketList = nfcPacketList;
		BuildOpCodeToPacketTypeMap();
	}

	public List<Type> GetPacketTypesMatchingOpCode(uint opCode)
	{
		if (opCode > 65535)
		{
			throw new Exception("Invalid opCode: 0x" + opCode.ToString("X"));
		}
		try
		{
			return opCodeToPacketTypeMap[opCode];
		}
		catch (KeyNotFoundException)
		{
			if ((opCode & 0xE000) == 0)
			{
				List<Type> list = new List<Type>();
				list.Add(typeof(Data));
				return list;
			}
			if ((opCode & 0xE000) == 8192)
			{
				List<Type> list2 = new List<Type>();
				list2.Add(typeof(GenericCommand));
				return list2;
			}
			if ((opCode & 0xE000) == 16384)
			{
				List<Type> list3 = new List<Type>();
				list3.Add(typeof(GenericResponse));
				return list3;
			}
			if ((opCode & 0xE000) == 24576)
			{
				List<Type> list4 = new List<Type>();
				list4.Add(typeof(GenericNotification));
				return list4;
			}
			throw new Exception($"Op code 0x{opCode:X4} not found");
		}
	}

	private void BuildOpCodeToPacketTypeMap()
	{
		foreach (PacketBase packet in nfcPacketList.Packets)
		{
			if (!(packet is GenericCommand) && !(packet is GenericResponse) && !(packet is GenericNotification) && !(packet is Data) && !(packet is ReadI2c) && !(packet is ReadI2cRegister) && !(packet is WriteI2c) && !(packet is WriteI2cRegister) && !(packet is ReadI2cResponse) && !(packet is RawData))
			{
				byte[] array = packet.ToByteArray();
				uint key = (uint)((array[0] << 8) | array[1]);
				if (!opCodeToPacketTypeMap.ContainsKey(key))
				{
					opCodeToPacketTypeMap.Add(key, new List<Type>());
				}
				opCodeToPacketTypeMap[key].Add(packet.GetType());
			}
		}
	}
}
