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

namespace QCRPG.TSL.BT.Packets;

public class QlmpEstServiceRsp : PacketBase
{
	public class UserFieldsWrapper
	{
		public enum LogIdEnum
		{
			OTA_QLMP_CTRL_RX_PDU,
			OTA_QLMP_CTRL_TX_PDU,
			InvalidLogIdValue
		}

		public static class LogIdInfo
		{
			public static LogIdEnum ValueToLogId(uint value)
			{
				return value switch
				{
					774u => LogIdEnum.OTA_QLMP_CTRL_RX_PDU, 
					775u => LogIdEnum.OTA_QLMP_CTRL_TX_PDU, 
					_ => LogIdEnum.InvalidLogIdValue, 
				};
			}

			public static uint LogIdToValue(LogIdEnum enumItem)
			{
				return enumItem switch
				{
					LogIdEnum.OTA_QLMP_CTRL_RX_PDU => 774u, 
					LogIdEnum.OTA_QLMP_CTRL_TX_PDU => 775u, 
					_ => uint.MaxValue, 
				};
			}

			public static string LogIdToString(LogIdEnum enumItem)
			{
				return enumItem switch
				{
					LogIdEnum.OTA_QLMP_CTRL_RX_PDU => "OTA_QLMP_CTRL_RX_PDU", 
					LogIdEnum.OTA_QLMP_CTRL_TX_PDU => "OTA_QLMP_CTRL_TX_PDU", 
					_ => "Invalid LogId Value", 
				};
			}

			public static string LogIdToDescription()
			{
				StringBuilder stringBuilder = new StringBuilder();
				stringBuilder.AppendLine("0x306 = OTA_QLMP_CTRL_RX_PDU");
				stringBuilder.AppendLine("0x307 = OTA_QLMP_CTRL_TX_PDU");
				return stringBuilder.ToString();
			}
		}

		public enum MinorTypeEnum
		{
			QLMP_EST_SERVICE_RSP,
			InvalidMinorTypeValue
		}

		public static class MinorTypeInfo
		{
			public static MinorTypeEnum ValueToMinorType(uint value)
			{
				if (value == 5)
				{
					return MinorTypeEnum.QLMP_EST_SERVICE_RSP;
				}
				return MinorTypeEnum.InvalidMinorTypeValue;
			}

			public static uint MinorTypeToValue(MinorTypeEnum enumItem)
			{
				if (enumItem == MinorTypeEnum.QLMP_EST_SERVICE_RSP)
				{
					return 5u;
				}
				return uint.MaxValue;
			}

			public static string MinorTypeToString(MinorTypeEnum enumItem)
			{
				if (enumItem == MinorTypeEnum.QLMP_EST_SERVICE_RSP)
				{
					return "QLMP_EST_SERVICE_RSP";
				}
				return "Invalid MinorType Value";
			}

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

		public class SupportedKeysEnumCollection
		{
		}

		public static class SupportedKeysInfo
		{
			public static SupportedKeysEnumCollection ValueToSupportedKeys(uint value)
			{
				return new SupportedKeysEnumCollection();
			}

			public static uint SupportedKeysToValue(SupportedKeysEnumCollection enumCollection)
			{
				return 0u;
			}

			public static string SupportedKeysToString(SupportedKeysEnumCollection enumCollection)
			{
				string text = "";
				return text.TrimEnd('\r', '\n');
			}

			public static string SupportedKeysToDescription()
			{
				StringBuilder stringBuilder = new StringBuilder();
				stringBuilder.AppendLine("Bit 0: Bit 0 = Connection Q-Root Key (BR/EDR Link Key). All other bits unassigned");
				return stringBuilder.ToString();
			}
		}

		private const uint _MinorType = 5u;

		private uint _SeqNum;

		private uint _LogsLostDrop;

		private uint _ProdId;

		private uint _LogId;

		private uint _LogFormatLevel;

		private uint _Timestamp;

		private uint _Handle;

		private uint _PduLength;

		private uint _SupportedKeys;

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

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

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

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

		public uint LogId
		{
			get
			{
				return _LogId;
			}
			set
			{
				if (value > 65535)
				{
					throw new Exception("Maximum possible value for LogId is 0xFFFF");
				}
				if (LogIdInfo.ValueToLogId(value) == LogIdEnum.InvalidLogIdValue)
				{
					throw new Exception("Invalid LogId value");
				}
				_LogId = value;
			}
		}

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

		public uint Timestamp
		{
			get
			{
				return _Timestamp;
			}
			set
			{
				_Timestamp = value;
			}
		}

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

		public uint MinorType => 5u;

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

		public uint SupportedKeys
		{
			get
			{
				return _SupportedKeys;
			}
			set
			{
				_SupportedKeys = value;
			}
		}

		public List<uint> ChallengeRandomList => _ChallengeRandomList;

		public LogIdEnum GetLogIdAsLogIdEnum()
		{
			return LogIdInfo.ValueToLogId(_LogId);
		}

		public void SetLogIdAsLogIdEnum(LogIdEnum enumItem)
		{
			LogId = LogIdInfo.LogIdToValue(enumItem);
		}

		public MinorTypeEnum GetMinorTypeAsMinorTypeEnum()
		{
			return MinorTypeInfo.ValueToMinorType(5u);
		}

		public SupportedKeysEnumCollection GetSupportedKeysAsSupportedKeysEnumCollection()
		{
			return SupportedKeysInfo.ValueToSupportedKeys(_SupportedKeys);
		}

		public void SetSupportedKeysAsSupportedKeysEnumCollection(SupportedKeysEnumCollection enumCollection)
		{
			SupportedKeys = SupportedKeysInfo.SupportedKeysToValue(enumCollection);
		}
	}

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

	private PacketInfoBase info;

	private uint _AclheaderSeqnumPadding;

	private uint _LogformatlevelTimestampPadding;

	private uint _LogLength;

	public UserFieldsWrapper _UserFields = new UserFieldsWrapper();

	public override PacketType Type => PacketType.EnhancedLog;

	public override Type[] ExpectedResponseTypes => expectedResponseTypes;

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

	public uint AclheaderSeqnumPadding
	{
		get
		{
			return _AclheaderSeqnumPadding;
		}
		set
		{
			if (value > 16777215)
			{
				throw new Exception("Maximum possible value for AclheaderSeqnumPadding is 0xFFFFFF");
			}
			_AclheaderSeqnumPadding = value;
		}
	}

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

	public uint LogLength
	{
		get
		{
			ToBitString();
			return _LogLength;
		}
	}

	public UserFieldsWrapper UserFields => _UserFields;

	protected override bool FromBitBuilder(ref BitBuilder bitBuilder)
	{
		AclheaderSeqnumPadding = bitBuilder.RemoveBitsAsUint(24);
		UserFields.SeqNum = bitBuilder.RemoveBitsAsUint(8);
		UserFields.LogsLostDrop = bitBuilder.RemoveBitsAsUint(8);
		UserFields.ProdId = bitBuilder.RemoveBitsAsUint(8);
		UserFields.LogId = bitBuilder.RemoveBitsAsUintLittleEndian(16);
		UserFields.LogFormatLevel = bitBuilder.RemoveBitsAsUint(8);
		LogformatlevelTimestampPadding = bitBuilder.RemoveBitsAsUint(8);
		UserFields.Timestamp = bitBuilder.RemoveBitsAsUintLittleEndian(32);
		_LogLength = bitBuilder.RemoveBitsAsUintLittleEndian(16);
		int numberOfBits = bitBuilder.GetNumberOfBits();
		if (numberOfBits > _LogLength * 8 + 7)
		{
			return false;
		}
		if (numberOfBits < _LogLength * 8)
		{
			return false;
		}
		UserFields.Handle = bitBuilder.RemoveBitsAsUint(8);
		if (bitBuilder.RemoveBitsAsUint(8) != UserFields.MinorType)
		{
			return false;
		}
		UserFields.PduLength = bitBuilder.RemoveBitsAsUint(8);
		UserFields.SupportedKeys = bitBuilder.RemoveBitsAsUintLittleEndian(32);
		for (int num = UserFields.ChallengeRandomList.Count - 1; num >= 0; num--)
		{
			UserFields.ChallengeRandomList[num] = bitBuilder.RemoveBitsAsUint(8);
		}
		if (bitBuilder.GetNumberOfBits() > 7)
		{
			return false;
		}
		return true;
	}

	public override string ToBitString()
	{
		BitBuilder bitBuilder = new BitBuilder();
		bitBuilder.AddBitsAsUint(AclheaderSeqnumPadding, 24);
		bitBuilder.AddBitsAsUint(UserFields.SeqNum, 8);
		bitBuilder.AddBitsAsUint(UserFields.LogsLostDrop, 8);
		bitBuilder.AddBitsAsUint(UserFields.ProdId, 8);
		bitBuilder.AddBitsAsUintLittleEndian(UserFields.LogId, 16);
		bitBuilder.AddBitsAsUint(UserFields.LogFormatLevel, 8);
		bitBuilder.AddBitsAsUint(LogformatlevelTimestampPadding, 8);
		bitBuilder.AddBitsAsUintLittleEndian(UserFields.Timestamp, 32);
		int numberOfBits = bitBuilder.GetNumberOfBits();
		bitBuilder.AddBitsAsUintLittleEndian(0u, 16);
		bitBuilder.AddBitsAsUint(UserFields.Handle, 8);
		bitBuilder.AddBitsAsUint(UserFields.MinorType, 8);
		bitBuilder.AddBitsAsUint(UserFields.PduLength, 8);
		bitBuilder.AddBitsAsUintLittleEndian(UserFields.SupportedKeys, 32);
		for (int num = UserFields.ChallengeRandomList.Count - 1; num >= 0; num--)
		{
			if (UserFields.ChallengeRandomList[num] > 255)
			{
				throw new Exception("UserFields.ChallengeRandomList[i] is > 0xFF");
			}
			bitBuilder.AddBitsAsUint(UserFields.ChallengeRandomList[num], 8);
		}
		_LogLength = (uint)((bitBuilder.GetNumberOfBits() - numberOfBits - 16) / 8);
		if ((bitBuilder.GetNumberOfBits() - numberOfBits - 16) % 8 != 0)
		{
			_LogLength++;
		}
		bitBuilder.ChangeBitsAsUintLittleEndian(numberOfBits, _LogLength, 16);
		return bitBuilder.ToString();
	}
}
