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

namespace QCRPG.TSL.BT.Packets;

public class ProdTestTxcOnly : PacketBase
{
	public class UserFieldsWrapper
	{
		public enum SubopcodeEnum
		{
			PROD_TEST_TXC_ONLY,
			InvalidSubopcodeValue
		}

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

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

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

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

		public enum TransmitTypeEnum
		{
			BREDR_Test_Modes,
			BLE_Test_Modes,
			QHS_Test_Modes,
			carrier_CW_only,
			ONE_PRBS9_GFSK_pseudo_random_binary_sequence,
			ONE_PRBS15_GFSK_pseudorandom_binary_sequence,
			ONE_pattern_GFSK_as_specified_in_the_fields_shown_in_the_Pattern_Length_field_offset_7,
			TWO_PRBS9_π_4_DQPSK,
			TWO_PRBS15_π_4_DQPSK,
			TWO_Pattern_π_4_DQPSK,
			THREE_PRBS9_8DPSK,
			THREE_PRBS15_8DPSK,
			THREE_Pattern_8DPSK,
			Carrier_CW_only,
			LE1M_PRBS9_GMSK,
			LE1M_PRBS15_GMSK,
			LE1M_Pattern_GMSK,
			LE2M_PRBS9,
			LE2M_PRBS15,
			LE2M_Pattern,
			QHS_P2_PRBS9_π_4_QPSK,
			QHS_P2_PRBS15_π_4_QPSK,
			QHS_P2_Pattern_π_4_QPSK,
			QHS_P3_PRBS9_π_4_QPSK,
			QHS_P3_PRBS15_π_4_QPSK,
			QHS_P3_Pattern_π_4_QPSK,
			QHS_P4_PRBS9_π_4_DQPSK,
			QHS_P4_PRBS15_π_4_DQPSK,
			QHS_P4_Pattern_π_4_DQPSK,
			QHS_P5_PRBS9_8PSK,
			QHS_P5_PRBS15_8PSK,
			QHS_P5_Pattern_8PSK,
			QHS_P6_PRBS9_8DPSK,
			QHS_P6_PRBS15_8DPSK,
			QHS_P6_Pattern_8DPSK,
			InvalidTransmitTypeValue
		}

		public static class TransmitTypeInfo
		{
			public static TransmitTypeEnum ValueToTransmitType(uint value)
			{
				if (value >= 4 && value <= 13)
				{
					return TransmitTypeEnum.BREDR_Test_Modes;
				}
				if (value >= 36 && value <= 42)
				{
					return TransmitTypeEnum.BLE_Test_Modes;
				}
				if (value >= 43 && value <= 57)
				{
					return TransmitTypeEnum.QHS_Test_Modes;
				}
				return value switch
				{
					4u => TransmitTypeEnum.carrier_CW_only, 
					5u => TransmitTypeEnum.ONE_PRBS9_GFSK_pseudo_random_binary_sequence, 
					6u => TransmitTypeEnum.ONE_PRBS15_GFSK_pseudorandom_binary_sequence, 
					7u => TransmitTypeEnum.ONE_pattern_GFSK_as_specified_in_the_fields_shown_in_the_Pattern_Length_field_offset_7, 
					8u => TransmitTypeEnum.TWO_PRBS9_π_4_DQPSK, 
					9u => TransmitTypeEnum.TWO_PRBS15_π_4_DQPSK, 
					10u => TransmitTypeEnum.TWO_Pattern_π_4_DQPSK, 
					11u => TransmitTypeEnum.THREE_PRBS9_8DPSK, 
					12u => TransmitTypeEnum.THREE_PRBS15_8DPSK, 
					13u => TransmitTypeEnum.THREE_Pattern_8DPSK, 
					36u => TransmitTypeEnum.Carrier_CW_only, 
					37u => TransmitTypeEnum.LE1M_PRBS9_GMSK, 
					38u => TransmitTypeEnum.LE1M_PRBS15_GMSK, 
					39u => TransmitTypeEnum.LE1M_Pattern_GMSK, 
					40u => TransmitTypeEnum.LE2M_PRBS9, 
					41u => TransmitTypeEnum.LE2M_PRBS15, 
					42u => TransmitTypeEnum.LE2M_Pattern, 
					43u => TransmitTypeEnum.QHS_P2_PRBS9_π_4_QPSK, 
					44u => TransmitTypeEnum.QHS_P2_PRBS15_π_4_QPSK, 
					45u => TransmitTypeEnum.QHS_P2_Pattern_π_4_QPSK, 
					46u => TransmitTypeEnum.QHS_P3_PRBS9_π_4_QPSK, 
					47u => TransmitTypeEnum.QHS_P3_PRBS15_π_4_QPSK, 
					48u => TransmitTypeEnum.QHS_P3_Pattern_π_4_QPSK, 
					49u => TransmitTypeEnum.QHS_P4_PRBS9_π_4_DQPSK, 
					50u => TransmitTypeEnum.QHS_P4_PRBS15_π_4_DQPSK, 
					51u => TransmitTypeEnum.QHS_P4_Pattern_π_4_DQPSK, 
					52u => TransmitTypeEnum.QHS_P5_PRBS9_8PSK, 
					53u => TransmitTypeEnum.QHS_P5_PRBS15_8PSK, 
					54u => TransmitTypeEnum.QHS_P5_Pattern_8PSK, 
					55u => TransmitTypeEnum.QHS_P6_PRBS9_8DPSK, 
					56u => TransmitTypeEnum.QHS_P6_PRBS15_8DPSK, 
					57u => TransmitTypeEnum.QHS_P6_Pattern_8DPSK, 
					_ => TransmitTypeEnum.InvalidTransmitTypeValue, 
				};
			}

			public static uint TransmitTypeToValue(TransmitTypeEnum enumItem)
			{
				return enumItem switch
				{
					TransmitTypeEnum.BREDR_Test_Modes => 4u, 
					TransmitTypeEnum.BLE_Test_Modes => 36u, 
					TransmitTypeEnum.QHS_Test_Modes => 43u, 
					TransmitTypeEnum.carrier_CW_only => 4u, 
					TransmitTypeEnum.ONE_PRBS9_GFSK_pseudo_random_binary_sequence => 5u, 
					TransmitTypeEnum.ONE_PRBS15_GFSK_pseudorandom_binary_sequence => 6u, 
					TransmitTypeEnum.ONE_pattern_GFSK_as_specified_in_the_fields_shown_in_the_Pattern_Length_field_offset_7 => 7u, 
					TransmitTypeEnum.TWO_PRBS9_π_4_DQPSK => 8u, 
					TransmitTypeEnum.TWO_PRBS15_π_4_DQPSK => 9u, 
					TransmitTypeEnum.TWO_Pattern_π_4_DQPSK => 10u, 
					TransmitTypeEnum.THREE_PRBS9_8DPSK => 11u, 
					TransmitTypeEnum.THREE_PRBS15_8DPSK => 12u, 
					TransmitTypeEnum.THREE_Pattern_8DPSK => 13u, 
					TransmitTypeEnum.Carrier_CW_only => 36u, 
					TransmitTypeEnum.LE1M_PRBS9_GMSK => 37u, 
					TransmitTypeEnum.LE1M_PRBS15_GMSK => 38u, 
					TransmitTypeEnum.LE1M_Pattern_GMSK => 39u, 
					TransmitTypeEnum.LE2M_PRBS9 => 40u, 
					TransmitTypeEnum.LE2M_PRBS15 => 41u, 
					TransmitTypeEnum.LE2M_Pattern => 42u, 
					TransmitTypeEnum.QHS_P2_PRBS9_π_4_QPSK => 43u, 
					TransmitTypeEnum.QHS_P2_PRBS15_π_4_QPSK => 44u, 
					TransmitTypeEnum.QHS_P2_Pattern_π_4_QPSK => 45u, 
					TransmitTypeEnum.QHS_P3_PRBS9_π_4_QPSK => 46u, 
					TransmitTypeEnum.QHS_P3_PRBS15_π_4_QPSK => 47u, 
					TransmitTypeEnum.QHS_P3_Pattern_π_4_QPSK => 48u, 
					TransmitTypeEnum.QHS_P4_PRBS9_π_4_DQPSK => 49u, 
					TransmitTypeEnum.QHS_P4_PRBS15_π_4_DQPSK => 50u, 
					TransmitTypeEnum.QHS_P4_Pattern_π_4_DQPSK => 51u, 
					TransmitTypeEnum.QHS_P5_PRBS9_8PSK => 52u, 
					TransmitTypeEnum.QHS_P5_PRBS15_8PSK => 53u, 
					TransmitTypeEnum.QHS_P5_Pattern_8PSK => 54u, 
					TransmitTypeEnum.QHS_P6_PRBS9_8DPSK => 55u, 
					TransmitTypeEnum.QHS_P6_PRBS15_8DPSK => 56u, 
					TransmitTypeEnum.QHS_P6_Pattern_8DPSK => 57u, 
					_ => uint.MaxValue, 
				};
			}

			public static string TransmitTypeToString(TransmitTypeEnum enumItem)
			{
				return enumItem switch
				{
					TransmitTypeEnum.BREDR_Test_Modes => "BREDR Test Modes", 
					TransmitTypeEnum.BLE_Test_Modes => "BLE Test Modes", 
					TransmitTypeEnum.QHS_Test_Modes => "QHS Test Modes ", 
					TransmitTypeEnum.carrier_CW_only => "carrier CW only", 
					TransmitTypeEnum.ONE_PRBS9_GFSK_pseudo_random_binary_sequence => "1-PRBS9 (GFSK) pseudo-random binary sequence", 
					TransmitTypeEnum.ONE_PRBS15_GFSK_pseudorandom_binary_sequence => "1-PRBS15 (GFSK) pseudorandom binary sequence", 
					TransmitTypeEnum.ONE_pattern_GFSK_as_specified_in_the_fields_shown_in_the_Pattern_Length_field_offset_7 => "1-pattern (GFSK) as specified in the fields shown in the Pattern Length field (offset 7)", 
					TransmitTypeEnum.TWO_PRBS9_π_4_DQPSK => " 2-PRBS9 (π/4-DQPSK)", 
					TransmitTypeEnum.TWO_PRBS15_π_4_DQPSK => "2-PRBS15 (π/4-DQPSK)", 
					TransmitTypeEnum.TWO_Pattern_π_4_DQPSK => "2-Pattern (π/4-DQPSK)", 
					TransmitTypeEnum.THREE_PRBS9_8DPSK => "3-PRBS9 (8DPSK)", 
					TransmitTypeEnum.THREE_PRBS15_8DPSK => "3-PRBS15 (8DPSK)", 
					TransmitTypeEnum.THREE_Pattern_8DPSK => "3-Pattern (8DPSK)", 
					TransmitTypeEnum.Carrier_CW_only => "Carrier (CW) only", 
					TransmitTypeEnum.LE1M_PRBS9_GMSK => " LE1M-PRBS9 (GMSK)", 
					TransmitTypeEnum.LE1M_PRBS15_GMSK => "LE1M-PRBS15 (GMSK)", 
					TransmitTypeEnum.LE1M_Pattern_GMSK => " LE1M-Pattern (GMSK)", 
					TransmitTypeEnum.LE2M_PRBS9 => "LE2M-PRBS9", 
					TransmitTypeEnum.LE2M_PRBS15 => "LE2M-PRBS15", 
					TransmitTypeEnum.LE2M_Pattern => "LE2M-Pattern", 
					TransmitTypeEnum.QHS_P2_PRBS9_π_4_QPSK => "QHS-P2-PRBS9 (π/4-QPSK)", 
					TransmitTypeEnum.QHS_P2_PRBS15_π_4_QPSK => " QHS-P2-PRBS15 (π/4-QPSK)", 
					TransmitTypeEnum.QHS_P2_Pattern_π_4_QPSK => "QHS-P2-Pattern (π/4-QPSK)", 
					TransmitTypeEnum.QHS_P3_PRBS9_π_4_QPSK => "QHS-P3-PRBS9 (π/4-QPSK)", 
					TransmitTypeEnum.QHS_P3_PRBS15_π_4_QPSK => " QHS-P3-PRBS15 (π/4-QPSK)", 
					TransmitTypeEnum.QHS_P3_Pattern_π_4_QPSK => " QHS-P3-Pattern (π/4-QPSK)", 
					TransmitTypeEnum.QHS_P4_PRBS9_π_4_DQPSK => "QHS-P4-PRBS9 (π/4-DQPSK)", 
					TransmitTypeEnum.QHS_P4_PRBS15_π_4_DQPSK => " QHS-P4-PRBS15 (π/4-DQPSK)", 
					TransmitTypeEnum.QHS_P4_Pattern_π_4_DQPSK => " QHS-P4-Pattern (π/4-DQPSK)", 
					TransmitTypeEnum.QHS_P5_PRBS9_8PSK => " QHS-P5-PRBS9 (8PSK)", 
					TransmitTypeEnum.QHS_P5_PRBS15_8PSK => " QHS-P5-PRBS15 (8PSK)", 
					TransmitTypeEnum.QHS_P5_Pattern_8PSK => "QHS-P5-Pattern (8PSK)", 
					TransmitTypeEnum.QHS_P6_PRBS9_8DPSK => "QHS-P6-PRBS9 (8DPSK)", 
					TransmitTypeEnum.QHS_P6_PRBS15_8DPSK => "QHS-P6-PRBS15 (8DPSK)", 
					TransmitTypeEnum.QHS_P6_Pattern_8DPSK => "QHS-P6-Pattern (8DPSK)", 
					_ => "Invalid TransmitType Value", 
				};
			}

			public static string TransmitTypeToDescription()
			{
				StringBuilder stringBuilder = new StringBuilder();
				stringBuilder.AppendLine("0x4-0xD = BREDR Test Modes");
				stringBuilder.AppendLine("0x24-0x2A = BLE Test Modes");
				stringBuilder.AppendLine("0x2B-0x39 = QHS Test Modes ");
				stringBuilder.AppendLine("0x4 = carrier CW only");
				stringBuilder.AppendLine("0x5 = 1-PRBS9 (GFSK) pseudo-random binary sequence");
				stringBuilder.AppendLine("0x6 = 1-PRBS15 (GFSK) pseudorandom binary sequence");
				stringBuilder.AppendLine("0x7 = 1-pattern (GFSK) as specified in the fields shown in the Pattern Length field (offset 7)");
				stringBuilder.AppendLine("0x8 =  2-PRBS9 (π/4-DQPSK)");
				stringBuilder.AppendLine("0x9 = 2-PRBS15 (π/4-DQPSK)");
				stringBuilder.AppendLine("0xA = 2-Pattern (π/4-DQPSK)");
				stringBuilder.AppendLine("0xB = 3-PRBS9 (8DPSK)");
				stringBuilder.AppendLine("0xC = 3-PRBS15 (8DPSK)");
				stringBuilder.AppendLine("0xD = 3-Pattern (8DPSK)");
				stringBuilder.AppendLine("0x24 = Carrier (CW) only");
				stringBuilder.AppendLine("0x25 =  LE1M-PRBS9 (GMSK)");
				stringBuilder.AppendLine("0x26 = LE1M-PRBS15 (GMSK)");
				stringBuilder.AppendLine("0x27 =  LE1M-Pattern (GMSK)");
				stringBuilder.AppendLine("0x28 = LE2M-PRBS9");
				stringBuilder.AppendLine("0x29 = LE2M-PRBS15");
				stringBuilder.AppendLine("0x2A = LE2M-Pattern");
				stringBuilder.AppendLine("0x2B = QHS-P2-PRBS9 (π/4-QPSK)");
				stringBuilder.AppendLine("0x2C =  QHS-P2-PRBS15 (π/4-QPSK)");
				stringBuilder.AppendLine("0x2D = QHS-P2-Pattern (π/4-QPSK)");
				stringBuilder.AppendLine("0x2E = QHS-P3-PRBS9 (π/4-QPSK)");
				stringBuilder.AppendLine("0x2F =  QHS-P3-PRBS15 (π/4-QPSK)");
				stringBuilder.AppendLine("0x30 =  QHS-P3-Pattern (π/4-QPSK)");
				stringBuilder.AppendLine("0x31 = QHS-P4-PRBS9 (π/4-DQPSK)");
				stringBuilder.AppendLine("0x32 =  QHS-P4-PRBS15 (π/4-DQPSK)");
				stringBuilder.AppendLine("0x33 =  QHS-P4-Pattern (π/4-DQPSK)");
				stringBuilder.AppendLine("0x34 =  QHS-P5-PRBS9 (8PSK)");
				stringBuilder.AppendLine("0x35 =  QHS-P5-PRBS15 (8PSK)");
				stringBuilder.AppendLine("0x36 = QHS-P5-Pattern (8PSK)");
				stringBuilder.AppendLine("0x37 = QHS-P6-PRBS9 (8DPSK)");
				stringBuilder.AppendLine("0x38 = QHS-P6-PRBS15 (8DPSK)");
				stringBuilder.AppendLine("0x39 = QHS-P6-Pattern (8DPSK)");
				return stringBuilder.ToString();
			}
		}

		private const uint _Subopcode = 5u;

		private uint _ChannelNumber;

		private uint _TransmitOutputPower;

		private uint _TransmitType;

		private uint _PacketLength = 1u;

		private uint _BitPattern = 1u;

		public uint Subopcode => 5u;

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

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

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

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

		public uint BitPattern
		{
			get
			{
				return _BitPattern;
			}
			set
			{
				_BitPattern = value;
			}
		}

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

		public TransmitTypeEnum GetTransmitTypeAsTransmitTypeEnum()
		{
			return TransmitTypeInfo.ValueToTransmitType(_TransmitType);
		}

		public void SetTransmitTypeAsTransmitTypeEnum(TransmitTypeEnum enumItem)
		{
			TransmitType = TransmitTypeInfo.TransmitTypeToValue(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 ProdTestTxcOnlyInfo(this);
			}
			return info;
		}
	}

	public uint Opcode => 64516u;

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

	public UserFieldsWrapper UserFields => _UserFields;

	public override void SetDefaultValues()
	{
		UserFields.ChannelNumber = 0u;
		UserFields.TransmitOutputPower = 0u;
		UserFields.PacketLength = 1u;
		UserFields.BitPattern = 1u;
	}

	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.ChannelNumber = bitBuilder.RemoveBitsAsUint(8);
		UserFields.TransmitOutputPower = bitBuilder.RemoveBitsAsUint(8);
		UserFields.TransmitType = bitBuilder.RemoveBitsAsUint(8);
		UserFields.PacketLength = bitBuilder.RemoveBitsAsUint(8);
		UserFields.BitPattern = bitBuilder.RemoveBitsAsUint(32);
		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.ChannelNumber, 8);
		bitBuilder.AddBitsAsUint(UserFields.TransmitOutputPower, 8);
		bitBuilder.AddBitsAsUint(UserFields.TransmitType, 8);
		bitBuilder.AddBitsAsUint(UserFields.PacketLength, 8);
		bitBuilder.AddBitsAsUint(UserFields.BitPattern, 32);
		_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.ChannelNumber < 0)
		{
			list.Add("Minimum allowed value for Channel Number is 0x0");
		}
		if (UserFields.ChannelNumber > 78)
		{
			list.Add("Maximum allowed value for Channel Number is 0x4E");
		}
		if (UserFields.TransmitOutputPower < 0)
		{
			list.Add("Minimum allowed value for Transmit_Output_Power is 0x0");
		}
		if (UserFields.TransmitOutputPower > 9)
		{
			list.Add("Maximum allowed value for Transmit_Output_Power is 0x9");
		}
		if (UserFields.PacketLength < 1)
		{
			list.Add("Minimum allowed value for Packet_Length is 0x1");
		}
		if (UserFields.PacketLength > 32)
		{
			list.Add("Maximum allowed value for Packet_Length is 0x20");
		}
		if (UserFields.BitPattern < 1)
		{
			list.Add("Minimum allowed value for Bit_Pattern is 0x1");
		}
		if (UserFields.BitPattern > uint.MaxValue)
		{
			list.Add("Maximum allowed value for Bit_Pattern is 0xFFFFFFFF");
		}
		return list;
	}
}
