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

namespace QCRPG.TSL.ZigBee.Packets;

public class VsDutRxTestRequest : PacketBase
{
	public class UserFieldsWrapper
	{
		public enum FlagsEnum
		{
			PHR_NO_CRC,
			NO_PHR_NO_CRC,
			PHR_CRC,
			CRC_NO_PHR,
			InvalidFlagsValue
		}

		public static class FlagsInfo
		{
			public static FlagsEnum ValueToFlags(uint value)
			{
				return value switch
				{
					0u => FlagsEnum.PHR_NO_CRC, 
					1u => FlagsEnum.NO_PHR_NO_CRC, 
					2u => FlagsEnum.PHR_CRC, 
					3u => FlagsEnum.CRC_NO_PHR, 
					_ => FlagsEnum.InvalidFlagsValue, 
				};
			}

			public static uint FlagsToValue(FlagsEnum enumItem)
			{
				return enumItem switch
				{
					FlagsEnum.PHR_NO_CRC => 0u, 
					FlagsEnum.NO_PHR_NO_CRC => 1u, 
					FlagsEnum.PHR_CRC => 2u, 
					FlagsEnum.CRC_NO_PHR => 3u, 
					_ => uint.MaxValue, 
				};
			}

			public static string FlagsToString(FlagsEnum enumItem)
			{
				return enumItem switch
				{
					FlagsEnum.PHR_NO_CRC => "PHR_NO_CRC", 
					FlagsEnum.NO_PHR_NO_CRC => "NO_PHR_NO_CRC", 
					FlagsEnum.PHR_CRC => "PHR_CRC", 
					FlagsEnum.CRC_NO_PHR => "CRC_NO_PHR", 
					_ => "Invalid Flags Value", 
				};
			}

			public static string FlagsToDescription()
			{
				StringBuilder stringBuilder = new StringBuilder();
				stringBuilder.AppendLine("0x0 = PHR_NO_CRC");
				stringBuilder.AppendLine("0x1 = NO_PHR_NO_CRC");
				stringBuilder.AppendLine("0x2 = PHR_CRC");
				stringBuilder.AppendLine("0x3 = CRC_NO_PHR");
				return stringBuilder.ToString();
			}
		}

		public enum ModeEnum
		{
			CONT_CARRIER_ONLY,
			CONT_MODULATED_DATA,
			BURST_MODULATED_DATA,
			InvalidModeValue
		}

		public static class ModeInfo
		{
			public static ModeEnum ValueToMode(uint value)
			{
				return value switch
				{
					0u => ModeEnum.CONT_CARRIER_ONLY, 
					1u => ModeEnum.CONT_MODULATED_DATA, 
					2u => ModeEnum.BURST_MODULATED_DATA, 
					_ => ModeEnum.InvalidModeValue, 
				};
			}

			public static uint ModeToValue(ModeEnum enumItem)
			{
				return enumItem switch
				{
					ModeEnum.CONT_CARRIER_ONLY => 0u, 
					ModeEnum.CONT_MODULATED_DATA => 1u, 
					ModeEnum.BURST_MODULATED_DATA => 2u, 
					_ => uint.MaxValue, 
				};
			}

			public static string ModeToString(ModeEnum enumItem)
			{
				return enumItem switch
				{
					ModeEnum.CONT_CARRIER_ONLY => "CONT_CARRIER_ONLY", 
					ModeEnum.CONT_MODULATED_DATA => "CONT_MODULATED_DATA", 
					ModeEnum.BURST_MODULATED_DATA => "BURST_MODULATED_DATA", 
					_ => "Invalid Mode Value", 
				};
			}

			public static string ModeToDescription()
			{
				StringBuilder stringBuilder = new StringBuilder();
				stringBuilder.AppendLine("0x0 = CONT_CARRIER_ONLY");
				stringBuilder.AppendLine("0x1 = CONT_MODULATED_DATA");
				stringBuilder.AppendLine("0x2 = BURST_MODULATED_DATA");
				return stringBuilder.ToString();
			}
		}

		private uint _Flags;

		private uint _Mode;

		private uint _Page;

		private uint _Channel = 11u;

		private uint _Payloadlength;

		private uint _Packettype;

		private uint _Gap;

		private uint _Rssiperiod;

		public uint Flags
		{
			get
			{
				return _Flags;
			}
			set
			{
				_Flags = value;
			}
		}

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

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

		public uint Channel
		{
			get
			{
				return _Channel;
			}
			set
			{
				if (value > 255)
				{
					throw new Exception("Maximum possible value for Channel is 0xFF");
				}
				_Channel = 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 Packettype
		{
			get
			{
				return _Packettype;
			}
			set
			{
				if (value > 255)
				{
					throw new Exception("Maximum possible value for Packettype is 0xFF");
				}
				_Packettype = value;
			}
		}

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

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

		public FlagsEnum GetFlagsAsFlagsEnum()
		{
			return FlagsInfo.ValueToFlags(_Flags);
		}

		public void SetFlagsAsFlagsEnum(FlagsEnum enumItem)
		{
			Flags = FlagsInfo.FlagsToValue(enumItem);
		}

		public ModeEnum GetModeAsModeEnum()
		{
			return ModeInfo.ValueToMode(_Mode);
		}

		public void SetModeAsModeEnum(ModeEnum enumItem)
		{
			Mode = ModeInfo.ModeToValue(enumItem);
		}

		public TestPacketTypeEnum GetPackettypeAsTestPacketTypeEnum()
		{
			return TestPacketTypeInfo.ValueToTestPacketType(_Packettype);
		}

		public void SetPackettypeAsTestPacketTypeEnum(TestPacketTypeEnum enumItem)
		{
			Packettype = TestPacketTypeInfo.TestPacketTypeToValue(enumItem);
		}
	}

	private const uint _Packetcode = 130u;

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

	private PacketInfoBase info;

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

	public uint Packetcode => 130u;

	public UserFieldsWrapper UserFields => _UserFields;

	public override void SetDefaultValues()
	{
		UserFields.Flags = 2u;
		UserFields.Mode = 2u;
		UserFields.Channel = 11u;
		UserFields.Packettype = 1u;
		UserFields.Gap = 1000u;
	}

	protected override bool FromBitBuilder(ref BitBuilder bitBuilder)
	{
		if (bitBuilder.RemoveBitsAsUintLittleEndian(8) != Packetcode)
		{
			return false;
		}
		UserFields.Flags = bitBuilder.RemoveBitsAsUintLittleEndian(32);
		UserFields.Mode = bitBuilder.RemoveBitsAsUint(8);
		UserFields.Page = bitBuilder.RemoveBitsAsUint(8);
		UserFields.Channel = bitBuilder.RemoveBitsAsUint(8);
		UserFields.Payloadlength = bitBuilder.RemoveBitsAsUintLittleEndian(16);
		UserFields.Packettype = bitBuilder.RemoveBitsAsUint(8);
		UserFields.Gap = bitBuilder.RemoveBitsAsUintLittleEndian(16);
		UserFields.Rssiperiod = bitBuilder.RemoveBitsAsUintLittleEndian(16);
		if (bitBuilder.GetNumberOfBits() > 7)
		{
			return false;
		}
		return true;
	}

	public override string ToBitString()
	{
		BitBuilder bitBuilder = new BitBuilder();
		bitBuilder.AddBitsAsUintLittleEndian(Packetcode, 8);
		bitBuilder.AddBitsAsUintLittleEndian(UserFields.Flags, 32);
		bitBuilder.AddBitsAsUint(UserFields.Mode, 8);
		bitBuilder.AddBitsAsUint(UserFields.Page, 8);
		bitBuilder.AddBitsAsUint(UserFields.Channel, 8);
		bitBuilder.AddBitsAsUintLittleEndian(UserFields.Payloadlength, 16);
		bitBuilder.AddBitsAsUint(UserFields.Packettype, 8);
		bitBuilder.AddBitsAsUintLittleEndian(UserFields.Gap, 16);
		bitBuilder.AddBitsAsUintLittleEndian(UserFields.Rssiperiod, 16);
		return bitBuilder.ToString();
	}

	public override List<string> GetWarnings()
	{
		List<string> list = new List<string>();
		if (UserFields.Flags < 0)
		{
			list.Add("Minimum allowed value for Flags is 0x0");
		}
		if (UserFields.Flags > 3)
		{
			list.Add("Maximum allowed value for Flags is 0x3");
		}
		if (UserFields.Mode < 0)
		{
			list.Add("Minimum allowed value for Mode is 0x0");
		}
		if (UserFields.Mode > 2)
		{
			list.Add("Maximum allowed value for Mode is 0x2");
		}
		if (UserFields.Channel < 11)
		{
			list.Add("Minimum allowed value for Channel is 0xB");
		}
		if (UserFields.Channel > 26)
		{
			list.Add("Maximum allowed value for Channel is 0x1A");
		}
		return list;
	}
}
