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

namespace skyscraper5.Mhp.Descriptors
{
	[SkyscraperPlugin]
	[TsDescriptor(0x00,"AIT")]
    public class ApplicationDescriptor : TsDescriptor
    {
        public ApplicationDescriptor(byte[] buffer)
        {
            MemoryStream ms = new MemoryStream(buffer, false);
            int application_profiles_length = ms.ReadUInt8();
            if (application_profiles_length % 5 != 0)
                throw new MhpException("{0} % 5 != 0", nameof(application_profiles_length));
            application_profiles_length /= 5;

            ApplicationProfiles = new ApplicationProfileEncoding[application_profiles_length];
            for (int i = 0; i < application_profiles_length; i++)
            {
                ApplicationProfiles[i] = new ApplicationProfileEncoding();
                ApplicationProfiles[i].ApplicationProfile = ms.ReadUInt16BE();
                ApplicationProfiles[i].Major = ms.ReadUInt8();
                ApplicationProfiles[i].Minor = ms.ReadUInt8();
                ApplicationProfiles[i].Micro = ms.ReadUInt8();
            }

            byte readUInt8 = ms.ReadUInt8();
            ServiceBoundFlag = ((readUInt8 & 0x80)) != 0;
            Visibility = ((readUInt8 & 0x60) >> 5);

            ApplicationPriority = ms.ReadUInt8();

            long availableBytes = ms.GetAvailableBytes();
            TransportProtocolLabel = new byte[availableBytes];
            for (long i = 0; i < availableBytes; i++)
            {
                TransportProtocolLabel[i] = ms.ReadUInt8();
            }
            Valid = true;
        }

        public byte[] TransportProtocolLabel { get; private set; }

        public byte ApplicationPriority { get; private set; }

        public int Visibility { get; private set; }

        public bool ServiceBoundFlag { get; private set; }

        public ApplicationProfileEncoding[] ApplicationProfiles { get; private set; }

        public struct ApplicationProfileEncoding
        {
            public ushort ApplicationProfile { get; internal set; }
            public byte Major { get; internal set; }

            public byte Minor { get; internal set; }
            public byte Micro { get; internal set; }
        }
    }
}
