using System;
using System.Collections.Generic;
using System.Text;
using QCRPG.Framework;

namespace QCRPG.TSL.NFC.Packets;

public class RfDiscoverCmd : PacketBase
{
	public class UserFieldsWrapper
	{
		private uint _NumberOfConfigurations;

		private List<ConfigurationSubField> _ConfigurationList = new List<ConfigurationSubField>();

		public uint NumberOfConfigurations
		{
			get
			{
				return _NumberOfConfigurations;
			}
			set
			{
				if (value > 255)
				{
					throw new Exception("Maximum possible value for NumberOfConfigurations is 0xFF");
				}
				_NumberOfConfigurations = value;
				while (_ConfigurationList.Count < _NumberOfConfigurations)
				{
					_ConfigurationList.Add(new ConfigurationSubField());
				}
				while (_ConfigurationList.Count > _NumberOfConfigurations)
				{
					_ConfigurationList.RemoveAt(_ConfigurationList.Count - 1);
				}
			}
		}

		public List<ConfigurationSubField> ConfigurationList => _ConfigurationList;
	}

	public class ConfigurationSubField
	{
		public enum DiscoveryFrequencyEnum
		{
			RFU,
			EVERY_PERIOD,
			EVERY_2_PERIODS,
			EVERY_3_PERIODS,
			EVERY_4_PERIODS,
			EVERY_5_PERIODS,
			EVERY_6_PERIODS,
			EVERY_7_PERIODS,
			EVERY_8_PERIODS,
			EVERY_9_PERIODS,
			EVERY_10_PERIODS,
			InvalidDiscoveryFrequencyValue
		}

		public static class DiscoveryFrequencyInfo
		{
			public static DiscoveryFrequencyEnum ValueToDiscoveryFrequency(uint value)
			{
				switch (value)
				{
				case 0u:
					return DiscoveryFrequencyEnum.RFU;
				case 1u:
					return DiscoveryFrequencyEnum.EVERY_PERIOD;
				case 2u:
					return DiscoveryFrequencyEnum.EVERY_2_PERIODS;
				case 3u:
					return DiscoveryFrequencyEnum.EVERY_3_PERIODS;
				case 4u:
					return DiscoveryFrequencyEnum.EVERY_4_PERIODS;
				case 5u:
					return DiscoveryFrequencyEnum.EVERY_5_PERIODS;
				case 6u:
					return DiscoveryFrequencyEnum.EVERY_6_PERIODS;
				case 7u:
					return DiscoveryFrequencyEnum.EVERY_7_PERIODS;
				case 8u:
					return DiscoveryFrequencyEnum.EVERY_8_PERIODS;
				case 9u:
					return DiscoveryFrequencyEnum.EVERY_9_PERIODS;
				case 10u:
					return DiscoveryFrequencyEnum.EVERY_10_PERIODS;
				default:
					if (value >= 11 && value <= 255)
					{
						return DiscoveryFrequencyEnum.RFU;
					}
					return DiscoveryFrequencyEnum.InvalidDiscoveryFrequencyValue;
				}
			}

			public static uint DiscoveryFrequencyToValue(DiscoveryFrequencyEnum enumItem)
			{
				switch (enumItem)
				{
				case DiscoveryFrequencyEnum.RFU:
					return 0u;
				case DiscoveryFrequencyEnum.EVERY_PERIOD:
					return 1u;
				case DiscoveryFrequencyEnum.EVERY_2_PERIODS:
					return 2u;
				case DiscoveryFrequencyEnum.EVERY_3_PERIODS:
					return 3u;
				case DiscoveryFrequencyEnum.EVERY_4_PERIODS:
					return 4u;
				case DiscoveryFrequencyEnum.EVERY_5_PERIODS:
					return 5u;
				case DiscoveryFrequencyEnum.EVERY_6_PERIODS:
					return 6u;
				case DiscoveryFrequencyEnum.EVERY_7_PERIODS:
					return 7u;
				case DiscoveryFrequencyEnum.EVERY_8_PERIODS:
					return 8u;
				case DiscoveryFrequencyEnum.EVERY_9_PERIODS:
					return 9u;
				case DiscoveryFrequencyEnum.EVERY_10_PERIODS:
					return 10u;
				default:
					if (enumItem == DiscoveryFrequencyEnum.RFU)
					{
						return 11u;
					}
					return uint.MaxValue;
				}
			}

			public static string DiscoveryFrequencyToString(DiscoveryFrequencyEnum enumItem)
			{
				switch (enumItem)
				{
				case DiscoveryFrequencyEnum.RFU:
					return "RFU";
				case DiscoveryFrequencyEnum.EVERY_PERIOD:
					return "EVERY_PERIOD";
				case DiscoveryFrequencyEnum.EVERY_2_PERIODS:
					return "EVERY_2_PERIODS";
				case DiscoveryFrequencyEnum.EVERY_3_PERIODS:
					return "EVERY_3_PERIODS";
				case DiscoveryFrequencyEnum.EVERY_4_PERIODS:
					return "EVERY_4_PERIODS";
				case DiscoveryFrequencyEnum.EVERY_5_PERIODS:
					return "EVERY_5_PERIODS";
				case DiscoveryFrequencyEnum.EVERY_6_PERIODS:
					return "EVERY_6_PERIODS";
				case DiscoveryFrequencyEnum.EVERY_7_PERIODS:
					return "EVERY_7_PERIODS";
				case DiscoveryFrequencyEnum.EVERY_8_PERIODS:
					return "EVERY_8_PERIODS";
				case DiscoveryFrequencyEnum.EVERY_9_PERIODS:
					return "EVERY_9_PERIODS";
				case DiscoveryFrequencyEnum.EVERY_10_PERIODS:
					return "EVERY_10_PERIODS";
				default:
					if (enumItem == DiscoveryFrequencyEnum.RFU)
					{
						return "RFU";
					}
					return "Invalid DiscoveryFrequency Value";
				}
			}

			public static string DiscoveryFrequencyToDescription()
			{
				StringBuilder stringBuilder = new StringBuilder();
				stringBuilder.AppendLine("0x0 = RFU");
				stringBuilder.AppendLine("0x1 = EVERY_PERIOD");
				stringBuilder.AppendLine("0x2 = EVERY_2_PERIODS");
				stringBuilder.AppendLine("0x3 = EVERY_3_PERIODS");
				stringBuilder.AppendLine("0x4 = EVERY_4_PERIODS");
				stringBuilder.AppendLine("0x5 = EVERY_5_PERIODS");
				stringBuilder.AppendLine("0x6 = EVERY_6_PERIODS");
				stringBuilder.AppendLine("0x7 = EVERY_7_PERIODS");
				stringBuilder.AppendLine("0x8 = EVERY_8_PERIODS");
				stringBuilder.AppendLine("0x9 = EVERY_9_PERIODS");
				stringBuilder.AppendLine("0xA = EVERY_10_PERIODS");
				stringBuilder.AppendLine("0xB-0xFF = RFU");
				return stringBuilder.ToString();
			}
		}

		private uint _RfTechnologyAndMode;

		private uint _DiscoveryFrequency;

		public uint RfTechnologyAndMode
		{
			get
			{
				return _RfTechnologyAndMode;
			}
			set
			{
				if (value > 255)
				{
					throw new Exception("Maximum possible value for RfTechnologyAndMode is 0xFF");
				}
				_RfTechnologyAndMode = value;
			}
		}

		public uint DiscoveryFrequency
		{
			get
			{
				return _DiscoveryFrequency;
			}
			set
			{
				if (value > 255)
				{
					throw new Exception("Maximum possible value for DiscoveryFrequency is 0xFF");
				}
				_DiscoveryFrequency = value;
			}
		}

		public RfTechnologyAndModeEnum GetRfTechnologyAndModeAsRfTechnologyAndModeEnum()
		{
			return RfTechnologyAndModeInfo.ValueToRfTechnologyAndMode(_RfTechnologyAndMode);
		}

		public void SetRfTechnologyAndModeAsRfTechnologyAndModeEnum(RfTechnologyAndModeEnum enumItem)
		{
			RfTechnologyAndMode = RfTechnologyAndModeInfo.RfTechnologyAndModeToValue(enumItem);
		}

		public DiscoveryFrequencyEnum GetDiscoveryFrequencyAsDiscoveryFrequencyEnum()
		{
			return DiscoveryFrequencyInfo.ValueToDiscoveryFrequency(_DiscoveryFrequency);
		}

		public void SetDiscoveryFrequencyAsDiscoveryFrequencyEnum(DiscoveryFrequencyEnum enumItem)
		{
			DiscoveryFrequency = DiscoveryFrequencyInfo.DiscoveryFrequencyToValue(enumItem);
		}

		public bool FromBitBuilder(ref BitBuilder bitBuilder)
		{
			RfTechnologyAndMode = bitBuilder.RemoveBitsAsUint(8);
			DiscoveryFrequency = bitBuilder.RemoveBitsAsUint(8);
			return true;
		}

		public string ToBitString()
		{
			BitBuilder bitBuilder = new BitBuilder();
			bitBuilder.AddBitsAsUint(RfTechnologyAndMode, 8);
			bitBuilder.AddBitsAsUint(DiscoveryFrequency, 8);
			return bitBuilder.ToString();
		}
	}

	private const uint _Mt = 1u;

	private const uint _Gid = 1u;

	private const uint _Oid = 3u;

	private Type[] expectedResponseTypes = new Type[1] { typeof(RfDiscoverRsp) };

	private PacketInfoBase info;

	private uint _Pbf;

	private uint _Rfu;

	private uint _PayloadLength;

	public UserFieldsWrapper _UserFields = new UserFieldsWrapper();

	public override PacketType Type => PacketType.Command;

	public override Type[] ExpectedResponseTypes => expectedResponseTypes;

	public override PacketInfoBase Info
	{
		get
		{
			if (info == null)
			{
				info = new RfDiscoverCmdInfo(this);
			}
			return info;
		}
	}

	public uint Mt => 1u;

	public uint Pbf => _Pbf;

	public uint Gid => 1u;

	public uint Rfu => _Rfu;

	public uint Oid => 3u;

	public uint PayloadLength
	{
		get
		{
			ToBitString();
			return _PayloadLength;
		}
	}

	public UserFieldsWrapper UserFields => _UserFields;

	public override void SetDefaultValues()
	{
		UserFields.NumberOfConfigurations = 1u;
	}

	protected override bool FromBitBuilder(ref BitBuilder bitBuilder)
	{
		if (bitBuilder.RemoveBitsAsUint(3) != Mt)
		{
			return false;
		}
		_Pbf = bitBuilder.RemoveBitsAsUint(1);
		if (bitBuilder.RemoveBitsAsUint(4) != Gid)
		{
			return false;
		}
		_Rfu = bitBuilder.RemoveBitsAsUint(2);
		if (bitBuilder.RemoveBitsAsUint(6) != Oid)
		{
			return false;
		}
		_PayloadLength = bitBuilder.RemoveBitsAsUint(8);
		int numberOfBits = bitBuilder.GetNumberOfBits();
		if (numberOfBits > _PayloadLength * 8 + 7)
		{
			return false;
		}
		if (numberOfBits < _PayloadLength * 8)
		{
			return false;
		}
		UserFields.NumberOfConfigurations = bitBuilder.RemoveBitsAsUint(8);
		for (int i = 0; i < UserFields.ConfigurationList.Count; i++)
		{
			UserFields.ConfigurationList[i].FromBitBuilder(ref bitBuilder);
		}
		if (bitBuilder.GetNumberOfBits() > 7)
		{
			return false;
		}
		return true;
	}

	public override string ToBitString()
	{
		BitBuilder bitBuilder = new BitBuilder();
		bitBuilder.AddBitsAsUint(Mt, 3);
		bitBuilder.AddBitsAsUint(Pbf, 1);
		bitBuilder.AddBitsAsUint(Gid, 4);
		bitBuilder.AddBitsAsUint(Rfu, 2);
		bitBuilder.AddBitsAsUint(Oid, 6);
		int numberOfBits = bitBuilder.GetNumberOfBits();
		bitBuilder.AddBitsAsUint(0u, 8);
		bitBuilder.AddBitsAsUint(UserFields.NumberOfConfigurations, 8);
		for (int i = 0; i < UserFields.ConfigurationList.Count; i++)
		{
			bitBuilder.AddBitsAsString(UserFields.ConfigurationList[i].ToBitString());
		}
		_PayloadLength = (uint)((bitBuilder.GetNumberOfBits() - numberOfBits - 8) / 8);
		if ((bitBuilder.GetNumberOfBits() - numberOfBits - 8) % 8 != 0)
		{
			_PayloadLength++;
		}
		bitBuilder.ChangeBitsAsUint(numberOfBits, _PayloadLength, 8);
		return bitBuilder.ToString();
	}
}
