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

namespace skyscraper5.DNS.Protocol.ResourceRecords.Records
{
	public class StartOfAuthorityResourceRecord : BaseResourceRecord, SimpleDnsRecord
	{
		public StartOfAuthorityResourceRecord(IResourceRecord record, byte[] message, int dataOffset)
			: base(record)
		{
			MasterDomainName = Domain.FromArray(message, dataOffset, out dataOffset);
			ResponsibleDomainName = Domain.FromArray(message, dataOffset, out dataOffset);

			Options tail = Marshalling.Struct.GetStruct<Options>(message, dataOffset, Options.SIZE);

			SerialNumber = tail.SerialNumber;
			RefreshInterval = tail.RefreshInterval;
			RetryInterval = tail.RetryInterval;
			ExpireInterval = tail.ExpireInterval;
			MinimumTimeToLive = tail.MinimumTimeToLive;
		}

		public Domain MasterDomainName { get; }
		public Domain ResponsibleDomainName { get; }
		public long SerialNumber { get; }
		public TimeSpan RefreshInterval { get; }
		public TimeSpan RetryInterval { get; }
		public TimeSpan ExpireInterval { get; }
		public TimeSpan MinimumTimeToLive { get; }

		public string GetDataAsString()
		{
			dynamic child = new
			{
				MasterDomainName = MasterDomainName.ToString(),
				ResponsibleDomainName = ResponsibleDomainName.ToString(),
				SerialNumber = SerialNumber,
				RefreshInterval = RefreshInterval,
				RetryInterval = RetryInterval,
				ExpireInterval = ExpireInterval,
				MinimumTimeToLive = MinimumTimeToLive
			};
			string result = JsonConvert.SerializeObject(child);
			return result;
		}

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

			private uint serialNumber;
			private uint refreshInterval;
			private uint retryInterval;
			private uint expireInterval;
			private uint ttl;

			public long SerialNumber
			{
				get { return serialNumber; }
				set { serialNumber = (uint)value; }
			}

			public TimeSpan RefreshInterval
			{
				get { return TimeSpan.FromSeconds(refreshInterval); }
				set { refreshInterval = (uint)value.TotalSeconds; }
			}

			public TimeSpan RetryInterval
			{
				get { return TimeSpan.FromSeconds(retryInterval); }
				set { retryInterval = (uint)value.TotalSeconds; }
			}

			public TimeSpan ExpireInterval
			{
				get { return TimeSpan.FromSeconds(expireInterval); }
				set { expireInterval = (uint)value.TotalSeconds; }
			}

			public TimeSpan MinimumTimeToLive
			{
				get { return TimeSpan.FromSeconds(ttl); }
				set { ttl = (uint)value.TotalSeconds; }
			}
		}


	}
}
