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

namespace skyscraper5.Dvb.SystemSoftwareUpdate.Model
{
    public class Compatibility
    {
        public Compatibility(MemoryStream input)
        {
            if (input.GetAvailableBytes() < 2)
                return;
            DescriptorType = input.ReadUInt8();
            if (DescriptorType == 0)
                return;
            byte descriptorLength = input.ReadUInt8();
            if (descriptorLength == 0)
                return;
            if (DescriptorType >= 0x03)
            {
                if (input.GetAvailableBytes() >= descriptorLength)
                    PrivateData = input.ReadBytes(descriptorLength);
                return;
            }
            if (input.GetAvailableBytes() < 6)
                return;
            SpecifierType = input.ReadUInt8();
            SpecifierData = BitConverter.ToString(input.ReadBytes(3));
            Model = input.ReadUInt16BE();
            if (input.GetAvailableBytes() < 2)
                return;
            Version = input.ReadUInt16BE();
            if (input.GetAvailableBytes() == 0)

                return;
            byte subDescriptorCount = input.ReadUInt8();
            SubDescriptors = new Compatibility[subDescriptorCount];
            for (int i = 0; i < subDescriptorCount; i++)
            {
                if (input.GetAvailableBytes() == 0)
                    return;
                SubDescriptors[i] = new Compatibility(input);
            }
        }

        public byte[] PrivateData { get; private set; }
        public Compatibility[] SubDescriptors { get; }
        public string SpecifierData { get; private set; }
        public ushort Model { get; }
        public byte SpecifierType { get; private set; }
        public byte DescriptorType { get; private set; }
        public ushort Version { get; }

        public override string ToString()
        {
            if (DescriptorType >= 0x03)
            {
                CRC32 crc32 = new CRC32();
                int hash = crc32.GetCrc32(new MemoryStream(PrivateData));
                return String.Format("Private Type {0:X2} ({0:X8})", DescriptorType, hash);
            }
            else
            {
                return String.Format("{0}, Model {1}", SpecifierData, Model);
            }
        }
    }
}
