using skyscraper5.Mpeg2;
using skyscraper5.Skyscraper;
using skyscraper5.Skyscraper.IO;
using skyscraper5.Skyscraper.Plugins;
using skyscraper5.src.Skyscraper.Scraper.Storage.Utilities;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace skyscraper5.src.InteractionChannel.Model.Descriptors
{
	[SkyscraperPlugin]
	[TsDescriptor(0x4a,"RMT")]
	public class _0x4a_LinkageDescriptor : TsDescriptor
	{
		public _0x4a_LinkageDescriptor(byte[] buffer)
		{
			MemoryStream ms = new MemoryStream(buffer);
			this.TransportStreamId = ms.ReadUInt16BE();
			this.OriginalNetworkId = ms.ReadUInt16BE();
			this.ServiceId = ms.ReadUInt16BE();
			this.LinkageType = ms.ReadUInt8();
			this.InteractiveNetworkId = ms.ReadUInt16BE();

			byte populationIdLoopCount = ms.ReadUInt8(); populationIdLoopCount++;
			PopulationIds = new Population[populationIdLoopCount];
			for (int i = 0; i < populationIdLoopCount; i++)
			{
				if (ms.GetAvailableBytes() < 4)
				{
					Valid = false;
					return;
				}
				PopulationIds[i] = new Population();
				PopulationIds[i].Base = ms.ReadUInt16BE();
				PopulationIds[i].Mask = ms.ReadUInt16BE();
			}

			PrivateData = ms.ReadBytes(ms.GetAvailableBytes());
			Valid = true;
		}

		public ushort TransportStreamId { get; }
		public ushort OriginalNetworkId { get; }
		public ushort ServiceId { get; }
		public byte LinkageType { get; }
		public ushort InteractiveNetworkId { get; }
		public Population[] PopulationIds { get; }
		public byte[] PrivateData { get; }

		public class Population
		{
			public ushort Base { get; internal set; }
			public ushort Mask { get; internal set; }

			public override string ToString()
			{
				return String.Format("({0},{1})", Base, Mask);
			}
		}

		public override string ToString()
		{
			StringBuilder sb = new StringBuilder();
			sb.Append("ONID {0}, TSID {1}", OriginalNetworkId, TransportStreamId);

			if (PopulationIds != null)
			{
				for (int i = 0; i < PopulationIds.Length; i++)
				{
					sb.Append(", ({0},{1})", PopulationIds[i].Base, PopulationIds[i].Mask);
				}
			}
			return sb.ToString();
		}

		public DatabaseKeyRmtLinkage ToKey()
		{
			return new DatabaseKeyRmtLinkage(TransportStreamId, OriginalNetworkId, ServiceId, LinkageType, InteractiveNetworkId);
		}
	}
}
