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

namespace skyscraper5.src.InteractionChannel.Model
{
	internal class InteractionChannelDsmCcPrivateSectionHeader : Validatable
	{
		public InteractionChannelDsmCcPrivateSectionHeader(MemoryStream ms)
		{
			TableId = ms.ReadUInt8();

			byte byteA = ms.ReadUInt8();
			SectionSyntaxIndicator = (byteA & 0x80) != 0;
			PrivateIndicator = (byteA & 0x40) != 0;
			int reserved = (byteA & 0x30) >> 4;
			SectionLength = (byteA & 0x0f);
			SectionLength <<= 8;
			SectionLength += ms.ReadUInt8();
			if (SectionLength != ms.GetAvailableBytes())
			{
				Valid = false;
				return;
			}

			byte[] mac = new byte[6];
			mac[5] = ms.ReadUInt8();
			mac[4] = ms.ReadUInt8();

			byte byteB = ms.ReadUInt8();
			int reservedB = ((byteB & 0xC0) >> 6);
			PayloadScramblingControl = ((byteB & 0x30) >> 4);
			AddressScramblingControl = ((byteB & 0x0C) >> 2);
			LlcSnap = (byteB & 0x02) != 0;
			if (LlcSnap)
			{
				Valid = false;
				return;
			}
			CurrentNextIndicator = (byteB & 0x01) != 0;
			if (!CurrentNextIndicator)
			{
				Valid = false;
				return;
			}

			SectionNumber = ms.ReadUInt8();
			LastSectionNumber = ms.ReadUInt8();
			mac[3] = ms.ReadUInt8();
			mac[2] = ms.ReadUInt8();
			mac[1] = ms.ReadUInt8();
			mac[0] = ms.ReadUInt8();

			MacAddress = new PhysicalAddress(mac);
			Valid = true;
		}

		public byte TableId { get; }
		public bool SectionSyntaxIndicator { get; }
		public bool PrivateIndicator { get; }
		public int SectionLength { get; }
		public int PayloadScramblingControl { get; }
		public int AddressScramblingControl { get; }
		public bool LlcSnap { get; }
		public bool CurrentNextIndicator { get; }
		public PhysicalAddress MacAddress { get; }
		public byte SectionNumber { get; }
		public byte LastSectionNumber { get; }

		private bool? _isBroadcast;
		public bool IsBroadcast
		{
			get
			{
				if (!_isBroadcast.HasValue)
				{
					PhysicalAddress broadcast = new PhysicalAddress(new byte[] { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff });
					_isBroadcast = MacAddress.Equals(broadcast);
				}
				return _isBroadcast.Value;
			}
		}
	}
}
