using skyscraper5.Skyscraper.IO;
using System;
using System.IO;

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

        protected override void SetValue(byte type, byte[] v)
        {
            switch (type)
            {
                case 7:
                    AuthKey = v;
                    break;
                case 9:
					(v[3], v[2], v[1], v[0]) = (v[0], v[1], v[2], v[3]);
                    KeyLifetime = BitConverter.ToUInt32(v, 0);
                    break;
				case 10:
                    KeySequenceNumber = v[0];
                    break;
                case 23:
                    SaDescriptor = new SaDescriptorObject(v);
                    break;
                default:
                    //CM-SP-SECv4.0-I01-190815.pdf, page 52
                    throw new NotImplementedException();
            }
        }

        public byte KeySequenceNumber { get; private set; }

        public uint KeyLifetime { get; private set; }
		public byte[] AuthKey { get; private set; }
		public SaDescriptorObject SaDescriptor { get; private set; }

		public class SaDescriptorObject
		{
            public SaDescriptorObject(byte[] buffer)
            {
                MemoryStream ms = new MemoryStream(buffer, false);
                while (ms.GetAvailableBytes() > 3)
                {
                    byte type = ms.ReadUInt8();
                    ushort length = ms.ReadUInt16BE();
                    byte[] value = ms.ReadBytes(length);

                    switch(type)
                    {
                        case 12:
                            (value[0], value[1]) = (value[1], value[0]);
                            SAID = BitConverter.ToUInt16(value);
                            break;
                        case 20:
                            DataEncryptionAlgorithm = (DataEncryptionAlgorithmIdentifiers)value[0];
                            DataAuthenticationAlgorithm = (DataAuthenticationIdentifiers)value[1];
                            break;
                        case 24:
                            SaType = (SaTypeEnum)value[0];
                            break;
						default:
							//CM-SP-SECv4.0-I01-190815.pdf, page 65
							throw new NotImplementedException();
					}
                }
            }

			public ushort SAID { get; private set; }
			public SaTypeEnum SaType { get; private set; }
			public DataEncryptionAlgorithmIdentifiers DataEncryptionAlgorithm { get; private set; }
			public DataAuthenticationIdentifiers DataAuthenticationAlgorithm { get; private set; }

			public enum SaTypeEnum
            {
                Primary,
                Static,
                Dynamic
            }

            public enum DataEncryptionAlgorithmIdentifiers
            {
                Cbc56Des = 1,
                Cbc40Des = 2,
                Cbc128Aes = 3,
            }

            public enum DataAuthenticationIdentifiers
            {
                NoDataAuthentication = 0
            }
		}
	}
}
