using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using skyscraper5.Mpeg2;
using skyscraper5.Skyscraper.IO;

namespace skyscraper8.Mpeg2.Psi
{
	internal abstract class PrivateSectionParser : IPsiProcessor
	{
		public void GatherPsi(PsiSection section, int sourcePid)
		{
			byte[] bytes = section.GetData();
			MemoryStream ms = new MemoryStream(bytes, false);
			byte tableId = ms.ReadUInt8();

			byte byteA = ms.ReadUInt8();
			bool sectionSyntaxIndicator = (byteA & 0x80) != 0;
			bool privateIndicator = (byteA & 0x40) != 0;
			int reserved = (byteA & 0x30) >> 4;
			int privateSectionLength = (byteA & 0xf);
			privateSectionLength <<= 8;
			privateSectionLength += ms.ReadUInt8();
			if (!sectionSyntaxIndicator)
			{
				byte[] payload = ms.ReadBytes(ms.GetAvailableBytes());
				HandleTable(tableId, sourcePid, payload);
			}
			else
			{
				ushort tableIdExtension = ms.ReadUInt16BE();

				byte byteB = ms.ReadUInt8();
				reserved = (byteB & 0xc0) >> 6;
				int versionNumber = (byteB & 0x3e) >> 1;
				bool currentNextIndicator = (byteB & 0x01) != 0;

				byte sectionNumber = ms.ReadUInt8();
				byte lastSectionNumber = ms.ReadUInt8();
				int blockLength = privateSectionLength - 9;
				byte[] payload = ms.ReadBytes(blockLength);
				uint crc32 = ms.ReadUInt32BE();
				HandleTable(tableId, sourcePid, sectionNumber, lastSectionNumber, tableIdExtension, payload);
			}
		}

		protected virtual void HandleTable(byte tableId, int sourcePid, byte sectionNumber, byte lastSectionNumber, ushort tableIdExtension, byte[] payload)
		{
			throw new PsiException("You should implement the override for no section syntax indicator.");
		}

		protected virtual void HandleTable(byte tableId, int sourcePid, byte[] payload)
		{
			throw new PsiException("You should implement the override for the section syntax indicator.");
		}
	}
}
