using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using skyscraper5.Docsis;
using skyscraper5.Dvb.DataBroadcasting.SkyscraperVfs;
using skyscraper5.Dvb.Descriptors;
using skyscraper5.Dvb.Psi.Model;
using skyscraper5.Mhp.Si.Model;
using skyscraper5.Mpeg2.Descriptors;
using skyscraper5.Mpeg2.Psi.Model;
using skyscraper5.Scte35;
using skyscraper5.Skyscraper.Net;
using skyscraper5.Skyscraper.Scraper;
using skyscraper5.Teletext.Wss;

namespace skyscraper5.src.Skyscraper.FrequencyListGenerator
{
	internal class FrequencyListGeneratorJunction : ISkyscraperUiJunction
	{
		public FrequencyListGeneratorJunction()
		{
			sdtServices = new Dictionary<ushort, SdtService>();
		}

		private Dictionary<ushort, SdtService> sdtServices;
		private Dictionary<ushort, ProgramMapping> programMappings;

		public void NotifyEvent(EitEvent eitEvent)
		{
		}

		public void NotifySdtService(SdtService sdtService)
		{
			if (!sdtServices.ContainsKey(sdtService.ServiceId))
				sdtServices.Add(sdtService.ServiceId, sdtService);
		}

		public void NotifyPatProgram(int pmtPid, ushort programId)
		{

		}

		public void NotifyPmtProgram(ProgramMapping result, int pmtPid)
		{
			if (!programMappings.ContainsKey(result.ProgramNumber))
				programMappings.Add(result.ProgramNumber, result);
		}

		public void NotifyNit(NitTransportStream transportStream)
		{

		}

		public void NotifyMpeTraffic(IpTrafficInfo iti, int ipv4PacketLength)
		{

		}

		public void NotifyAit(AitApplication aitApplication)
		{

		}

		public void DsmCcModuleAdd(int elementaryPid, ushort moduleInfoModuleId, byte moduleInfoModuleVersion)
		{

		}

		public void DsmCcModuleProgress(int elementaryPid, ushort moduleInfoModuleId, byte moduleInfoModuleVersion,
			double moduleInfoDownloadProgress)
		{

		}

		public void DsmCcModuleComplete(int elementaryPid, ushort moduleModuleId, byte moduleModuleVersion)
		{

		}

		public void NotifyWss(ushort programNumber, WssDataBlock wssDataBlock)
		{

		}

		public void NotifyStreamTypeDetection(string contestantTag, int pid)
		{

		}

		public void NotifyBat(BatBouquet batBouquet)
		{

		}

		public void NotifyBatTs(ushort batBouquetBouquetId, BatTransportStream child)
		{

		}

		public void DsmCcVfs(VfsFile vfsFile)
		{

		}

		public void NotifyTot(DateTime utcTime, LocalTimeOffsetDescriptor ltod)
		{

		}

		public void NotifyTdt(DateTime utcTime)
		{

		}

		public void NotifyCat(CaDescriptor caDescriptor)
		{

		}

		public void NotifyScte35(ushort programNumber, SpliceInsert spliceInsert)
		{

		}

		public void NotifyScte35(ushort programNumber, TimeSignal spliceInsert)
		{

		}

		public void SetMemorySaverMode(bool saveMemory)
		{

		}

		public void NotifyDocsisCarrier(DocsisEnvironment docsisEnvironment)
		{

		}

		public void NotifyDocsisFrequency(uint? frequency, bool isUpstream, object mmm)
		{

		}

		public void SetGseMode()
		{

		}

		public void ShowFramegrab(int currentNetworkId, int transportStreamId, ushort mappingProgramNumber,
			int mappingStreamElementaryPid, byte[] imageData)
		{

		}

		public void NotifyBlockstreamCarrier()
		{

		}

		public IEnumerable<HumanReadableService> GetServices()
		{
			foreach (var (pmtPid, pmt) in programMappings)
			{
				ushort serviceId = pmt.ProgramNumber;
				if (!sdtServices.ContainsKey(serviceId))
					continue;
				SdtService service = sdtServices[serviceId];
				string providerName = service.ServiceProviderName;
				string serviceName = service.ServiceName;
				ushort? caId = GetCaId(pmt, service);
				ServiceDescriptor.ServiceTypeCoding serviceType = service.ServiceType.GetValueOrDefault();
				yield return new HumanReadableService(serviceId, providerName, serviceName, caId, serviceType);
			}
		}

		private ushort? GetCaId(ProgramMapping pmt, SdtService sdt)
		{
			if (pmt.CaSystemId.HasValue)
			{
				return pmt.CaSystemId.Value;
			}

			foreach (ProgramMappingStream stream in pmt.Streams)
			{
				if (stream.CaSystemId.HasValue)
					return stream.CaSystemId.Value;
			}

			if (sdt.CaIdentifiers != null)
			{
				if (sdt.CaIdentifiers.Length > 0)
				{
					return sdt.CaIdentifiers[0];
				}
			}

			return null;
		}
	}
}
