using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;

namespace skyscraper5.DNS.Protocol
{
	public class Question
	{
		public static IList<Question> GetAllFromArray(byte[] message, int offset, int questionCount)
		{
			return GetAllFromArray(message, offset, questionCount, out offset);
		}
		
		public static IList<Question> GetAllFromArray(byte[] message, int offset, int questionCount, out int endOffset)
		{
			IList<Question> questions = new List<Question>(questionCount);

			for (int i = 0; i < questionCount; i++)
			{
				try
				{
					questions.Add(FromArray(message, offset, out offset));
				}
				catch (IndexOutOfRangeException ioore)
				{
					endOffset = offset;
					return questions;
				}
				catch (ArgumentException ae)
				{
					endOffset = offset;
					return questions;
				}
			}

			endOffset = offset;
			return questions;
		}

		public static Question FromArray(byte[] message, int offset, out int endOffset)
		{
			Domain domain = Domain.FromArray(message, offset, out offset);
			Tail tail = Marshalling.Struct.GetStruct<Tail>(message, offset, Tail.SIZE);

			endOffset = offset + Tail.SIZE;

			return new Question(domain, tail.Type, tail.Class);
		}

		[Marshalling.Endian(Marshalling.Endianness.Big)]
		[StructLayout(LayoutKind.Sequential, Pack = 2)]
		private struct Tail
		{
			public const int SIZE = 4;

			private ushort type;
			private ushort klass;

			public RecordType Type
			{
				get { return (RecordType)type; }
				set { type = (ushort)value; }
			}

			public RecordClass Class
			{
				get { return (RecordClass)klass; }
				set { klass = (ushort)value; }
			}
		}

		private Domain domain;
		private RecordType type;
		private RecordClass klass;

		public Question(Domain domain, RecordType type = RecordType.A, RecordClass klass = RecordClass.IN)
		{
			this.domain = domain;
			this.type = type;
			this.klass = klass;
		}
	}
}
