using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace skyscraper5.Rds.Messages
{
    [RdsMessage(0x17,RdsMessageHeaderType.Mel)]
    class RequestMessage : RdsMessage
    {
        private static RdsMessageAttribute[] attributes;
        private static void Initalize()
        {
            if (attributes == null)
                attributes = new RdsMessageAttribute[Byte.MaxValue];
            else
                return;

            Type[] typeCandidates = typeof(RdsDecoder).Assembly.GetTypes();
            bool validTypeFound = false;
            foreach (Type typeCandidate in typeCandidates)
            {
                Attribute customAttributes = typeCandidate.GetCustomAttributes(typeof(RdsMessageAttribute)).FirstOrDefault();
                if (customAttributes == null)
                    continue;

                RdsMessageAttribute rdsAttribute = customAttributes as RdsMessageAttribute;
                attributes[rdsAttribute.MessageElementCode] = rdsAttribute;
                validTypeFound = true;
            }

            if (!validTypeFound)
                throw new RdsException("failed to load rds message types");
        }

        public RequestMessage(byte[] buffer)
        {
            Initalize();
            byte ptr = 0;
            CodeOfRequestedMessage = buffer[ptr++];

            RdsMessageAttribute attribute = attributes[CodeOfRequestedMessage];
            if (attribute == null)
                throw new NotImplementedException(String.Format("RDS Message 0x{1:X2}", CodeOfRequestedMessage));

            if (attribute.NeedsDsn)
                Dsn = buffer[ptr++];

            if (attribute.NeedsPsn)
                Psn = buffer[ptr++];

            FurtherInformation = new byte[buffer.Length - ptr];
            Array.Copy(buffer, ptr, FurtherInformation, 0, buffer.Length - ptr);
        }

        public byte[] FurtherInformation { get; private set; }

        public byte? Psn { get; set; }

        public byte? Dsn { get; private set; }

        public byte CodeOfRequestedMessage { get; private set; }
    }
}
