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

namespace QCRPG.TSL.BT.Packets;

public class ProdTestLeTxBurst : PacketBase
{
	public class UserFieldsWrapper
	{
		public enum SubopcodeEnum
		{
			PROD_TEST_LE_TX_BURST,
			InvalidSubopcodeValue
		}

		public static class SubopcodeInfo
		{
			public static SubopcodeEnum ValueToSubopcode(uint value)
			{
				if (value == 28)
				{
					return SubopcodeEnum.PROD_TEST_LE_TX_BURST;
				}
				return SubopcodeEnum.InvalidSubopcodeValue;
			}

			public static uint SubopcodeToValue(SubopcodeEnum enumItem)
			{
				if (enumItem == SubopcodeEnum.PROD_TEST_LE_TX_BURST)
				{
					return 28u;
				}
				return uint.MaxValue;
			}

			public static string SubopcodeToString(SubopcodeEnum enumItem)
			{
				if (enumItem == SubopcodeEnum.PROD_TEST_LE_TX_BURST)
				{
					return "PROD_TEST_LE_TX_BURST";
				}
				return "Invalid Subopcode Value";
			}

			public static string SubopcodeToDescription()
			{
				StringBuilder stringBuilder = new StringBuilder();
				stringBuilder.AppendLine("0x1C = PROD_TEST_LE_TX_BURST");
				return stringBuilder.ToString();
			}
		}

		public enum PayloadTypeEnum
		{
			Pseudo_random_bit_sequence_9,
			Alternate_Nibbles_11110000,
			Alternate_Bits_10101010,
			Pseudo_random_bit_sequence_15,
			All_1,
			All_0,
			Alternate_Bits_00001111,
			Alternate_Bits_01010101,
			Reserved,
			InvalidPayloadTypeValue
		}

		public static class PayloadTypeInfo
		{
			public static PayloadTypeEnum ValueToPayloadType(uint value)
			{
				switch (value)
				{
				case 0u:
					return PayloadTypeEnum.Pseudo_random_bit_sequence_9;
				case 1u:
					return PayloadTypeEnum.Alternate_Nibbles_11110000;
				case 2u:
					return PayloadTypeEnum.Alternate_Bits_10101010;
				case 3u:
					return PayloadTypeEnum.Pseudo_random_bit_sequence_15;
				case 4u:
					return PayloadTypeEnum.All_1;
				case 5u:
					return PayloadTypeEnum.All_0;
				case 6u:
					return PayloadTypeEnum.Alternate_Bits_00001111;
				case 7u:
					return PayloadTypeEnum.Alternate_Bits_01010101;
				default:
					if (value >= 8 && value <= 255)
					{
						return PayloadTypeEnum.Reserved;
					}
					return PayloadTypeEnum.InvalidPayloadTypeValue;
				}
			}

			public static uint PayloadTypeToValue(PayloadTypeEnum enumItem)
			{
				return enumItem switch
				{
					PayloadTypeEnum.Pseudo_random_bit_sequence_9 => 0u, 
					PayloadTypeEnum.Alternate_Nibbles_11110000 => 1u, 
					PayloadTypeEnum.Alternate_Bits_10101010 => 2u, 
					PayloadTypeEnum.Pseudo_random_bit_sequence_15 => 3u, 
					PayloadTypeEnum.All_1 => 4u, 
					PayloadTypeEnum.All_0 => 5u, 
					PayloadTypeEnum.Alternate_Bits_00001111 => 6u, 
					PayloadTypeEnum.Alternate_Bits_01010101 => 7u, 
					PayloadTypeEnum.Reserved => 8u, 
					_ => uint.MaxValue, 
				};
			}

			public static string PayloadTypeToString(PayloadTypeEnum enumItem)
			{
				return enumItem switch
				{
					PayloadTypeEnum.Pseudo_random_bit_sequence_9 => "PRBS9", 
					PayloadTypeEnum.Alternate_Nibbles_11110000 => "Alternate Nibbles'11110000'", 
					PayloadTypeEnum.Alternate_Bits_10101010 => "Alternate Bits '10101010'", 
					PayloadTypeEnum.Pseudo_random_bit_sequence_15 => "PRBS15", 
					PayloadTypeEnum.All_1 => "All 1", 
					PayloadTypeEnum.All_0 => "All_0", 
					PayloadTypeEnum.Alternate_Bits_00001111 => "Alternate Bits '00001111'", 
					PayloadTypeEnum.Alternate_Bits_01010101 => "Alternate Bits '01010101'", 
					PayloadTypeEnum.Reserved => "Reserved", 
					_ => "Invalid PayloadType Value", 
				};
			}

			public static string PayloadTypeToDescription()
			{
				StringBuilder stringBuilder = new StringBuilder();
				stringBuilder.AppendLine("0x0 = PRBS9");
				stringBuilder.AppendLine("0x1 = Alternate Nibbles'11110000'");
				stringBuilder.AppendLine("0x2 = Alternate Bits '10101010'");
				stringBuilder.AppendLine("0x3 = PRBS15");
				stringBuilder.AppendLine("0x4 = All 1");
				stringBuilder.AppendLine("0x5 = All_0");
				stringBuilder.AppendLine("0x6 = Alternate Bits '00001111'");
				stringBuilder.AppendLine("0x7 = Alternate Bits '01010101'");
				stringBuilder.AppendLine("0x8-0xFF = Reserved");
				return stringBuilder.ToString();
			}
		}

		public enum PacketTypeEnum
		{
			LE1M,
			LE2M,
			LE_Coded_125k,
			LE_Coded_500k,
			Value_Used_For_LE1M_And_Coded_Simultaneous_Scan,
			QHS_P2,
			QHS_P3,
			QHS_P4,
			QHS_P5,
			QHS_P6,
			Reserved,
			InvalidPacketTypeValue
		}

		public static class PacketTypeInfo
		{
			public static PacketTypeEnum ValueToPacketType(uint value)
			{
				if (value == 1)
				{
					return PacketTypeEnum.LE1M;
				}
				if (value == 2)
				{
					return PacketTypeEnum.LE2M;
				}
				if (value == 3)
				{
					return PacketTypeEnum.LE_Coded_125k;
				}
				if (value == 4)
				{
					return PacketTypeEnum.LE_Coded_500k;
				}
				if (value == 5)
				{
					return PacketTypeEnum.Value_Used_For_LE1M_And_Coded_Simultaneous_Scan;
				}
				if (value == 6)
				{
					return PacketTypeEnum.QHS_P2;
				}
				if (value == 7)
				{
					return PacketTypeEnum.QHS_P3;
				}
				if (value == 8)
				{
					return PacketTypeEnum.QHS_P4;
				}
				if (value == 9)
				{
					return PacketTypeEnum.QHS_P5;
				}
				if (value == 10)
				{
					return PacketTypeEnum.QHS_P6;
				}
				if (value >= 11 && value <= 255)
				{
					return PacketTypeEnum.Reserved;
				}
				return PacketTypeEnum.InvalidPacketTypeValue;
			}

			public static uint PacketTypeToValue(PacketTypeEnum enumItem)
			{
				return enumItem switch
				{
					PacketTypeEnum.LE1M => 1u, 
					PacketTypeEnum.LE2M => 2u, 
					PacketTypeEnum.LE_Coded_125k => 3u, 
					PacketTypeEnum.LE_Coded_500k => 4u, 
					PacketTypeEnum.Value_Used_For_LE1M_And_Coded_Simultaneous_Scan => 5u, 
					PacketTypeEnum.QHS_P2 => 6u, 
					PacketTypeEnum.QHS_P3 => 7u, 
					PacketTypeEnum.QHS_P4 => 8u, 
					PacketTypeEnum.QHS_P5 => 9u, 
					PacketTypeEnum.QHS_P6 => 10u, 
					PacketTypeEnum.Reserved => 11u, 
					_ => uint.MaxValue, 
				};
			}

			public static string PacketTypeToString(PacketTypeEnum enumItem)
			{
				return enumItem switch
				{
					PacketTypeEnum.LE1M => "LE1M", 
					PacketTypeEnum.LE2M => "LE2M", 
					PacketTypeEnum.LE_Coded_125k => "LE Coded 125k", 
					PacketTypeEnum.LE_Coded_500k => "LE Coded 500k", 
					PacketTypeEnum.Value_Used_For_LE1M_And_Coded_Simultaneous_Scan => "Value used for LE1M and Coded Simultaneous Scan’", 
					PacketTypeEnum.QHS_P2 => "QHS-P2", 
					PacketTypeEnum.QHS_P3 => "QHS-P3", 
					PacketTypeEnum.QHS_P4 => "QHS-P4", 
					PacketTypeEnum.QHS_P5 => "QHS-P5", 
					PacketTypeEnum.QHS_P6 => "QHS-P6", 
					PacketTypeEnum.Reserved => "Reserved", 
					_ => "Invalid PacketType Value", 
				};
			}

			public static string PacketTypeToDescription()
			{
				StringBuilder stringBuilder = new StringBuilder();
				stringBuilder.AppendLine("0x1 = LE1M");
				stringBuilder.AppendLine("0x2 = LE2M");
				stringBuilder.AppendLine("0x3 = LE Coded 125k");
				stringBuilder.AppendLine("0x4 = LE Coded 500k");
				stringBuilder.AppendLine("0x5 = Value used for LE1M and Coded Simultaneous Scan’");
				stringBuilder.AppendLine("0x6 = QHS-P2");
				stringBuilder.AppendLine("0x7 = QHS-P3");
				stringBuilder.AppendLine("0x8 = QHS-P4");
				stringBuilder.AppendLine("0x9 = QHS-P5");
				stringBuilder.AppendLine("0xA = QHS-P6");
				stringBuilder.AppendLine("0xB-0xFF = Reserved");
				return stringBuilder.ToString();
			}
		}

		private const uint _Subopcode = 28u;

		private uint _HopChannels;

		private uint _PayloadLength;

		private uint _PayloadType;

		private uint _PacketType;

		private uint _TransmitOutputPower;

		public uint Subopcode => 28u;

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

		public uint PayloadLength
		{
			get
			{
				return _PayloadLength;
			}
			set
			{
				if (value > 65535)
				{
					throw new Exception("Maximum possible value for PayloadLength is 0xFFFF");
				}
				_PayloadLength = value;
			}
		}

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

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

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

		public SubopcodeEnum GetSubopcodeAsSubopcodeEnum()
		{
			return SubopcodeInfo.ValueToSubopcode(28u);
		}

		public PayloadTypeEnum GetPayloadTypeAsPayloadTypeEnum()
		{
			return PayloadTypeInfo.ValueToPayloadType(_PayloadType);
		}

		public void SetPayloadTypeAsPayloadTypeEnum(PayloadTypeEnum enumItem)
		{
			PayloadType = PayloadTypeInfo.PayloadTypeToValue(enumItem);
		}

		public PacketTypeEnum GetPacketTypeAsPacketTypeEnum()
		{
			return PacketTypeInfo.ValueToPacketType(_PacketType);
		}

		public void SetPacketTypeAsPacketTypeEnum(PacketTypeEnum enumItem)
		{
			PacketType = PacketTypeInfo.PacketTypeToValue(enumItem);
		}
	}

	private const uint _Opcode = 64516u;

	private Type[] expectedResponseTypes = new Type[0];

	private PacketInfoBase info;

	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 ProdTestLeTxBurstInfo(this);
			}
			return info;
		}
	}

	public uint Opcode => 64516u;

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

	public UserFieldsWrapper UserFields => _UserFields;

	public override void SetDefaultValues()
	{
		UserFields.HopChannels = 0u;
		UserFields.PayloadLength = 0u;
		UserFields.TransmitOutputPower = 0u;
	}

	protected override bool FromBitBuilder(ref BitBuilder bitBuilder)
	{
		if (bitBuilder.RemoveBitsAsUintLittleEndian(16) != Opcode)
		{
			return false;
		}
		_PayloadLength = bitBuilder.RemoveBitsAsUint(8);
		int numberOfBits = bitBuilder.GetNumberOfBits();
		if (numberOfBits > _PayloadLength * 8 + 7)
		{
			return false;
		}
		if (numberOfBits < _PayloadLength * 8)
		{
			return false;
		}
		if (bitBuilder.RemoveBitsAsUint(8) != UserFields.Subopcode)
		{
			return false;
		}
		UserFields.HopChannels = bitBuilder.RemoveBitsAsUint(8);
		UserFields.PayloadLength = bitBuilder.RemoveBitsAsUint(16);
		UserFields.PayloadType = bitBuilder.RemoveBitsAsUint(8);
		UserFields.PacketType = bitBuilder.RemoveBitsAsUint(8);
		UserFields.TransmitOutputPower = bitBuilder.RemoveBitsAsUint(8);
		if (bitBuilder.GetNumberOfBits() > 7)
		{
			return false;
		}
		return true;
	}

	public override string ToBitString()
	{
		BitBuilder bitBuilder = new BitBuilder();
		bitBuilder.AddBitsAsUintLittleEndian(Opcode, 16);
		int numberOfBits = bitBuilder.GetNumberOfBits();
		bitBuilder.AddBitsAsUint(0u, 8);
		bitBuilder.AddBitsAsUint(UserFields.Subopcode, 8);
		bitBuilder.AddBitsAsUint(UserFields.HopChannels, 8);
		bitBuilder.AddBitsAsUint(UserFields.PayloadLength, 16);
		bitBuilder.AddBitsAsUint(UserFields.PayloadType, 8);
		bitBuilder.AddBitsAsUint(UserFields.PacketType, 8);
		bitBuilder.AddBitsAsUint(UserFields.TransmitOutputPower, 8);
		_PayloadLength = (uint)((bitBuilder.GetNumberOfBits() - numberOfBits - 8) / 8);
		if ((bitBuilder.GetNumberOfBits() - numberOfBits - 8) % 8 != 0)
		{
			_PayloadLength++;
		}
		bitBuilder.ChangeBitsAsUint(numberOfBits, _PayloadLength, 8);
		return bitBuilder.ToString();
	}

	public override List<string> GetWarnings()
	{
		List<string> list = new List<string>();
		if (UserFields.HopChannels < 0)
		{
			list.Add("Minimum allowed value for Hop_Channels is 0x0");
		}
		if (UserFields.HopChannels > 255)
		{
			list.Add("Maximum allowed value for Hop_Channels is 0xFF");
		}
		if (UserFields.PayloadLength < 0)
		{
			list.Add("Minimum allowed value for Payload_Length is 0x0");
		}
		if (UserFields.PayloadLength > 1021)
		{
			list.Add("Maximum allowed value for Payload_Length is 0x3FD");
		}
		if (UserFields.TransmitOutputPower < 0)
		{
			list.Add("Minimum allowed value for Transmit_Output_Power is 0x0");
		}
		if (UserFields.TransmitOutputPower > 255)
		{
			list.Add("Maximum allowed value for Transmit_Output_Power is 0xFF");
		}
		return list;
	}
}
