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

namespace skyscraper5.Hdmv.Descriptors
{
    [UserDefinedDescriptor(0x48444d56, 0x88, "PMT")]
    internal class CopyControlDescriptor : TsDescriptor
    {
        public CopyControlDescriptor(byte[] buffer)
        {
            MemoryStream ms = new MemoryStream(buffer, false);
            CaSystemId = ms.ReadUInt16BE();
            PrivateData = ms.ReadBytes(ms.GetAvailableBytes());
            if (CaSystemId == 0x0fff)
                PrivateData = new AacsPrivateData((byte[])PrivateData);
            Valid = true;
        }

        public ushort CaSystemId { get; }

        public object PrivateData { get; }

        public class AacsPrivateData : Validatable
        {
            public AacsPrivateData(byte[] buffer)
            {
                if (buffer.Length != 2)
                {
                    Valid = false;
                    return;
                }
                (buffer[0], buffer[1]) = (buffer[1], buffer[0]);
                ushort data = BitConverter.ToUInt16(buffer, 0);
                RetentionMoveMode = (data & 0x4000) != 0;
                RetentionState = (data & 0x3800);
                EPN = (data & 0x0400) != 0;
                CCI = (CciMeanings)((data & 0x0300) >> 8);
                //Reserved = (data & 0x00f8);
                ImageConstraintToken = (data & 0x0004) != 0;
                ApsType = (data & 0x0002);

                Valid = true;
                OriginalData = buffer;
            }

            public bool RetentionMoveMode { get; }
            public int RetentionState { get; }
            public bool EPN { get; }
            public CciMeanings CCI { get; }
            public bool ImageConstraintToken { get; }
            public int ApsType { get; }

            public enum CciMeanings
            {
                CopyControlNotAsserted = 0,
                ReservedForNoMoreCopy = 1,
                CopyOneGeneration = 2,
                NeverCopy = 3
            }

            public byte[] OriginalData { get; }
        }
    }
}
