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

namespace QCRPG.TSL.BT.Packets;

public class VsBcaudEnable : PacketBase
{
	public class UserFieldsWrapper
	{
		public enum StreamIdEnum
		{
			Not_Used,
			Valid,
			Reserved,
			Invalid,
			InvalidStreamIdValue
		}

		public static class StreamIdInfo
		{
			public static StreamIdEnum ValueToStreamId(uint value)
			{
				switch (value)
				{
				case 0u:
					return StreamIdEnum.Not_Used;
				case 1u:
					return StreamIdEnum.Valid;
				default:
					if (value >= 2 && value <= 254)
					{
						return StreamIdEnum.Reserved;
					}
					if (value == 255)
					{
						return StreamIdEnum.Invalid;
					}
					return StreamIdEnum.InvalidStreamIdValue;
				}
			}

			public static uint StreamIdToValue(StreamIdEnum enumItem)
			{
				return enumItem switch
				{
					StreamIdEnum.Not_Used => 0u, 
					StreamIdEnum.Valid => 1u, 
					StreamIdEnum.Reserved => 2u, 
					StreamIdEnum.Invalid => 255u, 
					_ => uint.MaxValue, 
				};
			}

			public static string StreamIdToString(StreamIdEnum enumItem)
			{
				return enumItem switch
				{
					StreamIdEnum.Not_Used => "Not used", 
					StreamIdEnum.Valid => "Valid", 
					StreamIdEnum.Reserved => "Reserved", 
					StreamIdEnum.Invalid => "Invalid", 
					_ => "Invalid StreamId Value", 
				};
			}

			public static string StreamIdToDescription()
			{
				StringBuilder stringBuilder = new StringBuilder();
				stringBuilder.AppendLine("0x0 = Not used");
				stringBuilder.AppendLine("0x1 = Valid");
				stringBuilder.AppendLine("0x2-0xFE = Reserved");
				stringBuilder.AppendLine("0xFF = Invalid");
				return stringBuilder.ToString();
			}
		}

		public enum CodecEnum
		{
			CELT_Codec,
			Reserved,
			InvalidCodecValue
		}

		public static class CodecInfo
		{
			public static CodecEnum ValueToCodec(uint value)
			{
				if (value == 0)
				{
					return CodecEnum.CELT_Codec;
				}
				if (value >= 1 && value <= 255)
				{
					return CodecEnum.Reserved;
				}
				return CodecEnum.InvalidCodecValue;
			}

			public static uint CodecToValue(CodecEnum enumItem)
			{
				return enumItem switch
				{
					CodecEnum.CELT_Codec => 0u, 
					CodecEnum.Reserved => 1u, 
					_ => uint.MaxValue, 
				};
			}

			public static string CodecToString(CodecEnum enumItem)
			{
				return enumItem switch
				{
					CodecEnum.CELT_Codec => "CELT Codec", 
					CodecEnum.Reserved => "Reserved", 
					_ => "Invalid Codec Value", 
				};
			}

			public static string CodecToDescription()
			{
				StringBuilder stringBuilder = new StringBuilder();
				stringBuilder.AppendLine("0x0 = CELT Codec");
				stringBuilder.AppendLine("0x1-0xFF = Reserved");
				return stringBuilder.ToString();
			}
		}

		public enum SampleRateEnum
		{
			kHz_44p1,
			kHz_48,
			Reserved,
			InvalidSampleRateValue
		}

		public static class SampleRateInfo
		{
			public static SampleRateEnum ValueToSampleRate(uint value)
			{
				switch (value)
				{
				case 0u:
					return SampleRateEnum.kHz_44p1;
				case 1u:
					return SampleRateEnum.kHz_48;
				default:
					if (value >= 2 && value <= 255)
					{
						return SampleRateEnum.Reserved;
					}
					return SampleRateEnum.InvalidSampleRateValue;
				}
			}

			public static uint SampleRateToValue(SampleRateEnum enumItem)
			{
				return enumItem switch
				{
					SampleRateEnum.kHz_44p1 => 0u, 
					SampleRateEnum.kHz_48 => 1u, 
					SampleRateEnum.Reserved => 2u, 
					_ => uint.MaxValue, 
				};
			}

			public static string SampleRateToString(SampleRateEnum enumItem)
			{
				return enumItem switch
				{
					SampleRateEnum.kHz_44p1 => "44.1 kHz", 
					SampleRateEnum.kHz_48 => "48 kHz", 
					SampleRateEnum.Reserved => "Reserved", 
					_ => "Invalid SampleRate Value", 
				};
			}

			public static string SampleRateToDescription()
			{
				StringBuilder stringBuilder = new StringBuilder();
				stringBuilder.AppendLine("0x0 = 44.1 kHz");
				stringBuilder.AppendLine("0x1 = 48 kHz");
				stringBuilder.AppendLine("0x2-0xFF = Reserved");
				return stringBuilder.ToString();
			}
		}

		public enum EncodingSchemeEnum
		{
			EC2C5,
			Reserved,
			InvalidEncodingSchemeValue
		}

		public static class EncodingSchemeInfo
		{
			public static EncodingSchemeEnum ValueToEncodingScheme(uint value)
			{
				if (value == 0)
				{
					return EncodingSchemeEnum.EC2C5;
				}
				if (value >= 1 && value <= 255)
				{
					return EncodingSchemeEnum.Reserved;
				}
				return EncodingSchemeEnum.InvalidEncodingSchemeValue;
			}

			public static uint EncodingSchemeToValue(EncodingSchemeEnum enumItem)
			{
				return enumItem switch
				{
					EncodingSchemeEnum.EC2C5 => 0u, 
					EncodingSchemeEnum.Reserved => 1u, 
					_ => uint.MaxValue, 
				};
			}

			public static string EncodingSchemeToString(EncodingSchemeEnum enumItem)
			{
				return enumItem switch
				{
					EncodingSchemeEnum.EC2C5 => "EC2:5", 
					EncodingSchemeEnum.Reserved => "Reserved", 
					_ => "Invalid EncodingScheme Value", 
				};
			}

			public static string EncodingSchemeToDescription()
			{
				StringBuilder stringBuilder = new StringBuilder();
				stringBuilder.AppendLine("0x0 = EC2:5");
				stringBuilder.AppendLine("0x1-0xFF = Reserved");
				return stringBuilder.ToString();
			}
		}

		private const uint _Subopcode = 1u;

		private uint _StreamId;

		private uint _LtAddress;

		private uint _Codec;

		private uint _SampleRate;

		private uint _MaxPacketSize;

		private uint _EncodingScheme;

		private uint _TtpOffsetInUs;

		private List<uint> _PrivateKeyList = new List<uint>(new uint[16]);

		private ulong _InitVector;

		private uint _Volume;

		private uint _TransmissionPower;

		private uint _PcmSamplesPerFrame;

		public uint Subopcode => 1u;

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

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

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

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

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

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

		public uint TtpOffsetInUs
		{
			get
			{
				return _TtpOffsetInUs;
			}
			set
			{
				_TtpOffsetInUs = value;
			}
		}

		public List<uint> PrivateKeyList => _PrivateKeyList;

		public ulong InitVector
		{
			get
			{
				return _InitVector;
			}
			set
			{
				_InitVector = value;
			}
		}

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

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

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

		public StreamIdEnum GetStreamIdAsStreamIdEnum()
		{
			return StreamIdInfo.ValueToStreamId(_StreamId);
		}

		public void SetStreamIdAsStreamIdEnum(StreamIdEnum enumItem)
		{
			StreamId = StreamIdInfo.StreamIdToValue(enumItem);
		}

		public CodecEnum GetCodecAsCodecEnum()
		{
			return CodecInfo.ValueToCodec(_Codec);
		}

		public void SetCodecAsCodecEnum(CodecEnum enumItem)
		{
			Codec = CodecInfo.CodecToValue(enumItem);
		}

		public SampleRateEnum GetSampleRateAsSampleRateEnum()
		{
			return SampleRateInfo.ValueToSampleRate(_SampleRate);
		}

		public void SetSampleRateAsSampleRateEnum(SampleRateEnum enumItem)
		{
			SampleRate = SampleRateInfo.SampleRateToValue(enumItem);
		}

		public EncodingSchemeEnum GetEncodingSchemeAsEncodingSchemeEnum()
		{
			return EncodingSchemeInfo.ValueToEncodingScheme(_EncodingScheme);
		}

		public void SetEncodingSchemeAsEncodingSchemeEnum(EncodingSchemeEnum enumItem)
		{
			EncodingScheme = EncodingSchemeInfo.EncodingSchemeToValue(enumItem);
		}
	}

	private const uint _Opcode = 64547u;

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

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

	public uint Opcode => 64547u;

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

	public UserFieldsWrapper UserFields => _UserFields;

	public override void SetDefaultValues()
	{
		UserFields.MaxPacketSize = 186u;
		UserFields.TtpOffsetInUs = 250000u;
		for (int num = UserFields.PrivateKeyList.Count - 1; num >= 0; num--)
		{
			UserFields.PrivateKeyList[0] = 190u;
			UserFields.PrivateKeyList[1] = 55u;
			UserFields.PrivateKeyList[2] = 25u;
			UserFields.PrivateKeyList[3] = 237u;
			UserFields.PrivateKeyList[4] = 106u;
			UserFields.PrivateKeyList[5] = 94u;
			UserFields.PrivateKeyList[6] = 148u;
			UserFields.PrivateKeyList[7] = 52u;
			UserFields.PrivateKeyList[8] = 190u;
			UserFields.PrivateKeyList[9] = 80u;
			UserFields.PrivateKeyList[10] = 187u;
			UserFields.PrivateKeyList[11] = 164u;
			UserFields.PrivateKeyList[12] = 194u;
			UserFields.PrivateKeyList[13] = 127u;
			UserFields.PrivateKeyList[14] = 134u;
			UserFields.PrivateKeyList[15] = 87u;
		}
		UserFields.InitVector = 16053919725846930502uL;
		UserFields.TransmissionPower = 9u;
		UserFields.PcmSamplesPerFrame = 512u;
	}

	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.StreamId = bitBuilder.RemoveBitsAsUint(8);
		UserFields.LtAddress = bitBuilder.RemoveBitsAsUint(8);
		UserFields.Codec = bitBuilder.RemoveBitsAsUint(8);
		UserFields.SampleRate = bitBuilder.RemoveBitsAsUint(8);
		UserFields.MaxPacketSize = bitBuilder.RemoveBitsAsUintLittleEndian(16);
		UserFields.EncodingScheme = bitBuilder.RemoveBitsAsUint(8);
		UserFields.TtpOffsetInUs = bitBuilder.RemoveBitsAsUintLittleEndian(32);
		for (int num = UserFields.PrivateKeyList.Count - 1; num >= 0; num--)
		{
			UserFields.PrivateKeyList[num] = bitBuilder.RemoveBitsAsUint(8);
		}
		UserFields.InitVector = bitBuilder.RemoveBitsAsUlongLittleEndian(64);
		UserFields.Volume = bitBuilder.RemoveBitsAsUint(8);
		UserFields.TransmissionPower = bitBuilder.RemoveBitsAsUint(8);
		UserFields.PcmSamplesPerFrame = bitBuilder.RemoveBitsAsUintLittleEndian(16);
		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.StreamId, 8);
		bitBuilder.AddBitsAsUint(UserFields.LtAddress, 8);
		bitBuilder.AddBitsAsUint(UserFields.Codec, 8);
		bitBuilder.AddBitsAsUint(UserFields.SampleRate, 8);
		bitBuilder.AddBitsAsUintLittleEndian(UserFields.MaxPacketSize, 16);
		bitBuilder.AddBitsAsUint(UserFields.EncodingScheme, 8);
		bitBuilder.AddBitsAsUintLittleEndian(UserFields.TtpOffsetInUs, 32);
		for (int num = UserFields.PrivateKeyList.Count - 1; num >= 0; num--)
		{
			if (UserFields.PrivateKeyList[num] > 255)
			{
				throw new Exception("UserFields.PrivateKeyList[i] is > 0xFF");
			}
			bitBuilder.AddBitsAsUint(UserFields.PrivateKeyList[num], 8);
		}
		bitBuilder.AddBitsAsUlongLittleEndian(UserFields.InitVector, 64);
		bitBuilder.AddBitsAsUint(UserFields.Volume, 8);
		bitBuilder.AddBitsAsUint(UserFields.TransmissionPower, 8);
		bitBuilder.AddBitsAsUintLittleEndian(UserFields.PcmSamplesPerFrame, 16);
		_PayloadLength = (uint)((bitBuilder.GetNumberOfBits() - numberOfBits - 8) / 8);
		if ((bitBuilder.GetNumberOfBits() - numberOfBits - 8) % 8 != 0)
		{
			_PayloadLength++;
		}
		bitBuilder.ChangeBitsAsUint(numberOfBits, _PayloadLength, 8);
		return bitBuilder.ToString();
	}
}
