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

namespace skyscraper5.Docsis.MacManagement.BaselinePrivacyKeyManagementMessages
{
    public class KeyReply : PrivacyKeyManagementResponse.BpkmMessageObject
    {
        public KeyReply(byte[] buffer) : base(buffer)
        {
        }

        protected override void SetValue(byte type, byte[] v)
        {
            switch (type)
            {
                case 10:
                    KeySequenceNumber = v[0];
                    break;
                case 11:
                    HmacDigest = v;
                    break;
                case 12:
                    (v[1], v[0]) = (v[0], v[1]);
                    SAID = BitConverter.ToUInt16(v, 0);
                    break;
                case 13:
                    if (TekParameters == null)
                        TekParameters = new List<TekParameter>();
                    TekParameters.Add(new TekParameter(v));
                    break;
                default:
                    //CM-SP-SECv4.0-I01-190815.pdf page 53
                    throw new NotImplementedException();
            }
        }

        public byte[] HmacDigest { get; set; }

        public List<TekParameter> TekParameters { get; private set; }
        public class TekParameter
        {
            public TekParameter(byte[] buffer)
            {
                MemoryStream ms = new MemoryStream(buffer, false);
                while (ms.GetAvailableBytes() > 3)
                {
                    byte type = ms.ReadUInt8();
                    ushort length = ms.ReadUInt16BE();
                    byte[] v = ms.ReadBytes(length);
                    switch (type)
                    {
                        case 8:
                            TEK = v;
                            break;
                        case 9:
                            (v[0], v[1], v[2], v[3]) = (v[3], v[2], v[1], v[0]);
                            KeyLifetime = BitConverter.ToUInt32(v, 0);
                            break;
                        case 10:
                            TekKeySequenceNumber = v[0];
                            break;
                        case 15:
                            CbcIv = v;
                            break;
                        default:
                            //CM-SP-SECv4.0-I01-190815.pdf page 60-61
                            throw new NotImplementedException();
                    }
                }
            }

            public byte[] CbcIv { get; set; }

            public byte? TekKeySequenceNumber { get; set; }

            public uint? KeyLifetime { get; set; }

            public byte[] TEK { get; set; }

            public override string ToString()
            {
                return $"{nameof(TekKeySequenceNumber)}: {TekKeySequenceNumber}, {nameof(TEK)}: {TEK}";
            }
        }

        public ushort? SAID { get; set; }

        public byte? KeySequenceNumber { get; set; }
    }
}
