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;
using skyscraper5.Skyscraper.Text;

namespace skyscraper5.Dvb.Descriptors
{
	[SkyscraperPlugin]
	[TsDescriptor(0x48,"SDT","Astra SGT")]
    [BannedTable("TSDT","PMT")]
    public class ServiceDescriptor : TsDescriptor
    {
        public ServiceDescriptor(byte[] buffer)
        {
            MemoryStream ms = new MemoryStream(buffer, false);
            ServiceType = (ServiceTypeCoding)ms.ReadUInt8();
            byte serviceProviderNameLength = ms.ReadUInt8();
            ServiceProviderName = En300468AnnexATextDecoder.GetInstance().Decode(ms.ReadBytes(serviceProviderNameLength));
            byte serviceNameLength = ms.ReadUInt8();
            ServiceName = En300468AnnexATextDecoder.GetInstance().Decode(ms.ReadBytes(serviceNameLength));
        }

        public ServiceDescriptor(string serviceName, string serviceProviderName, ServiceTypeCoding serviceType)
        {
	        ServiceName = serviceName;
	        ServiceProviderName = serviceProviderName;
	        ServiceType = serviceType;
        }

        public string ServiceName { get; private set; }

        public string ServiceProviderName { get; private set; }

        public ServiceTypeCoding ServiceType { get; private set; }

        public enum ServiceTypeCoding : byte
        {
            TV_MPEG2 = 0x01,
            Radio = 0x02,
            Teletext = 0x03,
            NvodReference = 0x04,
            NvodTimeShifted = 0x05,
            Mosaic_MPEG2 = 0x06,
            FmRadio = 0x07,
            DvbSrm = 0x08,                  //ETSI TS 102 770 
            Radio_AAC = 0x0a,
            Mosaic_H264 = 0x0b,
            DataBroadcast = 0x0c,
            CommonInterfaceUsage = 0x0d,    //CENELEC EN 50221 
            RcsMap = 0x0e,                  //ETSI EN 301 790 
            RcsFls = 0x0f,                  //ETSI EN 301 790 
            DvbMhp = 0x10,                  
            HDTV_MPEG2 = 0x11,
            TV_H264 = 0x16,
            H264SdNvodTimeShifted = 0x17,
            H264SdNvodReference = 0x18,
            HDTV_H264 = 0x19,
            H264HdNvodTimeShifted = 0x1a,
            H264HdNvodReference = 0x1b,
            _3DTV_H264 = 0x1c,
            H264StereoscopicHdNvodTimeShifted = 0x1d,
            H264StereoscopicHdNvodRefence = 0x1e,
            TV_HEVC = 0x1f,
            _4KTV_HEVC = 0x20,
            VVC = 0x21,
            AVS3 = 0x22
        }

        public override byte[] Serialize()
        {
	        byte[] nameBuffer = En300468AnnexATextDecoder.GetInstance().Encode(ServiceName);
	        if (nameBuffer.Length > byte.MaxValue)
		        throw new Exception("Service name too long");

			byte[] providerBuffer = En300468AnnexATextDecoder.GetInstance().Encode(ServiceProviderName);
			if (providerBuffer.Length > byte.MaxValue)
				throw new Exception("Service Provider Name too long");

			MemoryStream ms = new MemoryStream();
	        ms.WriteUInt8((byte)ServiceType);

	        ms.WriteUInt8((byte)providerBuffer.Length);
	        ms.Write(providerBuffer, 0, providerBuffer.Length);

			ms.WriteUInt8((byte)nameBuffer.Length);
	        ms.Write(nameBuffer, 0, nameBuffer.Length);

            return ms.ToArray();
        }
    }
}
