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()
		{
			return String.Format("Link type {0}", LinkageType);
		}

		

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

		protected bool Equals(_0x4a_LinkageDescriptor other)
		{
			return TransportStreamId == other.TransportStreamId && OriginalNetworkId == other.OriginalNetworkId && ServiceId == other.ServiceId && LinkageType == other.LinkageType && InteractiveNetworkId == other.InteractiveNetworkId;
		}

		public override bool Equals(object? obj)
		{
			if (ReferenceEquals(null, obj)) 
				return false;
			if (ReferenceEquals(this, obj)) 
				return true;
			if (obj.GetType() != this.GetType()) 
				return false;
			return Equals((_0x4a_LinkageDescriptor)obj);
		}

		public override int GetHashCode()
		{
			return HashCode.Combine(TransportStreamId, OriginalNetworkId, ServiceId, LinkageType, InteractiveNetworkId);
		}
	}
}
