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

namespace skyscraper8.Docsis.AnnexC
{
	public class DsidEncoding
	{
		public DsidEncoding(byte[] buffer)
		{
			MemoryStream ms = new MemoryStream(buffer, false);

			while (ms.GetAvailableBytes() > 2)
			{
				byte type = ms.ReadUInt8();
				byte length = ms.ReadUInt8();
				byte[] v = ms.ReadBytes(length);
				switch (type)
				{
					case 1:
						byte[] uintBuffer = new byte[] { v[2], v[1], v[0], 0 };
						DSID = BitConverter.ToUInt32(uintBuffer);
						break;
					case 2:
						DownstreamServiceIdentifierAction = (DownstreamServiceIdentifierActionEnum)v[0];
						break;
					case 3:
						DownstreamResequencingEncodings = new EncodedResequencingAttributes(v);
						break;
					case 4:
						MulticastEncodings = new EncodedMulticastAttributes(v);
						break;
					default:
						//CM-SP-MULPIv4.0-I01-190815.pdf, page 731
						throw new NotImplementedException(String.Format("DSID Encoding 50.{0}", type));
				}
			}
		}

		public uint? DSID { get; }

		public DownstreamServiceIdentifierActionEnum? DownstreamServiceIdentifierAction { get; }

		public enum DownstreamServiceIdentifierActionEnum
		{
			Add = 0,
			Change = 1,
			Delete = 2
		}

		public EncodedResequencingAttributes DownstreamResequencingEncodings { get; }
		internal EncodedMulticastAttributes MulticastEncodings { get; }

		public class EncodedResequencingAttributes
		{
			public EncodedResequencingAttributes(byte[] buffer)
			{
				MemoryStream ms = new MemoryStream(buffer, false);

				while (ms.GetAvailableBytes() > 2)
				{
					byte type = ms.ReadUInt8();
					byte length = ms.ReadUInt8();
					byte[] v = ms.ReadBytes(length);
					switch (type)
					{
						case 1:
							IsResequencing = v[0] == 1;
							break;
						case 2:
							DownstreamResequencingChannelList = v;
							break;
						case 3:
							DsidResequencingWaitTime = v[0];
							break;
						default:
							//CM-SP-MULPIv4.0-I01-190815.pdf, page 731
							throw new NotImplementedException(String.Format("EncodedResequencingAttributes 50.3.{0}", type));
					}
				}
			}

			public bool? IsResequencing { get; }
			public byte[] DownstreamResequencingChannelList { get; }
			public byte DsidResequencingWaitTime { get; }
		}
	}
}
