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


namespace skyscraper5.Mpeg2.Descriptors
{
	[SkyscraperPlugin]
	[TsDescriptor(0x26, "PMT")]
    [BannedTable("NIT")]
    class MetadataDescriptor : TsDescriptor
    {
        public MetadataDescriptor(byte[] buffer)
        {
            MemoryStream ms = new MemoryStream(buffer, false);
            MetadataApplicationFormat = ms.ReadUInt16BE();
            if (MetadataApplicationFormat == 0xffff)
            {
				MetadataApplicationFormatIdentifier = ms.ReadUInt32BE();
            }
            MetadataFormat = ms.ReadUInt8();
            if (MetadataFormat == 0xff)
            {
                MetadataFormatIdentifier = ms.ReadUInt32BE();
            }
            MetadataServiceId = ms.ReadUInt8();
            byte bytea = ms.ReadUInt8();
            DecoderConfigFlag = (bytea & 0xe0) >> 7;
            bool DsmCcFlag = (bytea & 0x10) != 0;
            if (DsmCcFlag)
            {
                byte serviceIdentificationLength = ms.ReadUInt8();
                ServiceIdentificationRecord = ms.ReadBytes(serviceIdentificationLength);
            }
            if (DecoderConfigFlag == 0b001)
            {
                byte decoderConfigLength = ms.ReadUInt8();
                DecoderConfig = ms.ReadBytes(decoderConfigLength);
            }
            if (DecoderConfigFlag == 0b011)
            {
                byte decConfigIdentificationRecordLength = ms.ReadUInt8();
                DecoderConfigIdentificationRecord = ms.ReadBytes(decConfigIdentificationRecordLength);
            }
            if (DecoderConfigFlag == 0b100)
            {
                DecoderConfigMetadataServiceId = ms.ReadUInt16BE();
            }
            if (DecoderConfigFlag == 0b101 || DecoderConfigFlag == 0xb110)
            {
                byte reservedDataLength = ms.ReadUInt8();
                this.Reserved = ms.ReadBytes(reservedDataLength);
            }
            PrivateData = ms.ReadBytes(ms.GetAvailableBytes());
            Valid = true;
        }

		public ushort MetadataApplicationFormat { get; }
		public uint? MetadataApplicationFormatIdentifier { get; private set; }
		public byte MetadataFormat { get; }
		public uint? MetadataFormatIdentifier { get; }
		public byte MetadataServiceId { get; }
		public int DecoderConfigFlag { get; }
		public byte[] ServiceIdentificationRecord { get; }
		public byte[] DecoderConfig { get; }
		public byte[] DecoderConfigIdentificationRecord { get; }
		public ushort DecoderConfigMetadataServiceId { get; }
		public byte[] Reserved { get; }
		public byte[] PrivateData { get; }
	}
}
