using System;
using System.IO;

namespace QCRPG.Framework;

public class SnoopLogReader
{
	private enum DataLinkType
	{
		Unencapsulated_HCI = 1001,
		HCI_UART,
		HCI_BSCP,
		HCI_Serial
	}

	private class SnoopFileHeader
	{
		public ulong IdentificationPattern;

		public uint VersionNumber;

		public uint DataLink;
	}

	public class PacketRecord : IDeepCopyable<PacketRecord>
	{
		public uint OriginalLength;

		public uint IncludedLength;

		public uint PacketFlags;

		public uint CumulativeDrops;

		public ulong TimeStamp;

		public PacketRecord DeepCopy()
		{
			PacketRecord packetRecord = new PacketRecord();
			packetRecord.OriginalLength = OriginalLength;
			packetRecord.IncludedLength = IncludedLength;
			packetRecord.PacketFlags = PacketFlags;
			packetRecord.CumulativeDrops = CumulativeDrops;
			packetRecord.TimeStamp = TimeStamp;
			return packetRecord;
		}
	}

	private string fileName;

	private string debugLogFileName = "debugLog_" + DateTime.Now.ToString("yyMMdd_hhmm") + ".txt";

	private BinaryReader reader;

	private int fileHeader_IdentificationPattern_Length = 8;

	private int fileHeader_VersionNumber_Length = 4;

	private int fileHeader_DataLink_Length = 4;

	private int fileHeaderLength = 16;

	private int packetRecordLength = 24;

	public long BytesRead
	{
		get
		{
			if (reader != null && reader.BaseStream != null)
			{
				return reader.BaseStream.Position;
			}
			return 0L;
		}
	}

	public long TotalNumberOfBytes
	{
		get
		{
			if (reader != null && reader.BaseStream != null)
			{
				return reader.BaseStream.Length;
			}
			return 0L;
		}
	}

	public void OpenSnoopFile(string fileName)
	{
		this.fileName = fileName;
		SnoopFileHeader snoopFileHeader = new SnoopFileHeader();
		try
		{
			reader = new BinaryReader(File.Open(fileName, FileMode.Open));
			snoopFileHeader.IdentificationPattern = reader.ReadUInt64();
			snoopFileHeader.VersionNumber = reader.ReadUInt32();
			snoopFileHeader.DataLink = reader.ReadUInt32();
			if (snoopFileHeader.IdentificationPattern != 31647721776706658L)
			{
				throw new Exception("Invalid File Header");
			}
		}
		catch (Exception ex)
		{
			throw ex;
		}
	}

	private uint GetUInt32(bool bigEndian = true)
	{
		uint value = reader.ReadUInt32();
		byte[] bytes = BitConverter.GetBytes(value);
		if (bigEndian)
		{
			Array.Reverse(bytes);
		}
		return BitConverter.ToUInt32(bytes, 0);
	}

	private ulong GetUInt64(bool bigEndian = true)
	{
		ulong value = reader.ReadUInt64();
		byte[] bytes = BitConverter.GetBytes(value);
		if (bigEndian)
		{
			Array.Reverse(bytes);
		}
		return BitConverter.ToUInt32(bytes, 0);
	}

	private byte[] GetNbytes(uint n)
	{
		byte[] array = new byte[n];
		reader.Read(array, 0, (int)n);
		return array;
	}

	public SnoopLogPacketData GetNextPacketRecord()
	{
		SnoopLogPacketData result = null;
		PacketRecord packetRecord = new PacketRecord();
		int num = 0;
		while (reader.BaseStream.Position < reader.BaseStream.Length)
		{
			if (reader.BaseStream.Position >= reader.BaseStream.Length)
			{
				continue;
			}
			try
			{
				packetRecord.OriginalLength = GetUInt32();
				packetRecord.IncludedLength = GetUInt32();
				packetRecord.PacketFlags = GetUInt32();
				packetRecord.CumulativeDrops = GetUInt32();
				packetRecord.TimeStamp = GetUInt64();
				result = new SnoopLogPacketData(GetNbytes(packetRecord.IncludedLength), packetRecord);
				num++;
				if (num < 1)
				{
					continue;
				}
				return result;
			}
			catch (Exception)
			{
				return null;
			}
		}
		return result;
	}

	public void CloseFile()
	{
		if (reader != null)
		{
			reader.Close();
		}
	}
}
