using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using skyscraper5.Data.PostgreSql;
using skyscraper5.Dvb.Psi.Model;
using skyscraper5.Ietf.Rfc971;
using skyscraper5.Skyscraper.Scraper.Storage.InMemory;

namespace skyscraper8.EPGCollectorPort.SkyscraperSide.Freesat
{
	internal interface IFreesatTunnelDataStorage
	{
		bool StoreEitEvent(EitEvent eitEvent);
		void StoreNitNetwork(NitNetwork nitNetwork);
		bool TestNitNetwork(NitNetwork nitNetwork);
		bool TestForNitTransportStream(ushort networkId, NitTransportStream transportStream);
		void StoreNitTransportStream(ushort networkId, NitTransportStream transportStream);
	}

	internal class FreesatTunnelDataStorage : IFreesatTunnelDataStorage
	{
		public FreesatTunnelDataStorage(object[] getPluginConnector)
		{
			object o = getPluginConnector[0];
			switch (o)
			{
				case InMemoryPluginToken t1:
					_storageEngine = new FreesatTunnelDataStorageInMemory();
					break;
				case PostgresqlToken t2:
					_storageEngine = new FreesatTunnelDataStoragePostgresql(t2);
					break;
				default:
					throw new NotImplementedException(o.GetType().FullName);
			}
		}

		private IFreesatTunnelDataStorage _storageEngine;
		
		public bool StoreEitEvent(EitEvent eitEvent)
		{
			return _storageEngine.StoreEitEvent(eitEvent);
		}

		public void StoreNitNetwork(NitNetwork nitNetwork)
		{
			_storageEngine.StoreNitNetwork(nitNetwork);
		}

		public bool TestNitNetwork(NitNetwork nitNetwork)
		{
			return _storageEngine.TestNitNetwork(nitNetwork);
		}

		public bool TestForNitTransportStream(ushort networkId, NitTransportStream transportStream)
		{
			return _storageEngine.TestForNitTransportStream(networkId, transportStream);
		}

		public void StoreNitTransportStream(ushort networkId, NitTransportStream transportStream)
		{
			_storageEngine.StoreNitTransportStream(networkId, transportStream);
		}
	}

	internal class FreesatTunnelDataStorageInMemory : IFreesatTunnelDataStorage
	{
		private HashSet<EitEvent> _eitEvents;
		public bool StoreEitEvent(EitEvent eitEvent)
		{
			if (_eitEvents == null)
				_eitEvents = new HashSet<EitEvent>();

			return _eitEvents.Add(eitEvent);
		}

		private NitNetwork[] _nitNetworks;
		public void StoreNitNetwork(NitNetwork nitNetwork)
		{
			if (_nitNetworks == null)
				_nitNetworks = new NitNetwork[ushort.MaxValue];

			_nitNetworks[nitNetwork.NetworkId] = nitNetwork;
		}

		public bool TestNitNetwork(NitNetwork nitNetwork)
		{
			if (_nitNetworks == null)
				return false;

			return _nitNetworks[nitNetwork.NetworkId] != null;
		}

		private NitTransportStream[][] _nitTransportStreams;
		public bool TestForNitTransportStream(ushort networkId, NitTransportStream transportStream)
		{
			if (_nitTransportStreams == null)
				return false;
			if (_nitTransportStreams[networkId] == null)
				return false;

			return _nitTransportStreams[networkId][transportStream.TransportStreamId] != null;
		}

		public void StoreNitTransportStream(ushort networkId, NitTransportStream transportStream)
		{
			if (_nitTransportStreams == null)
				_nitTransportStreams = new NitTransportStream[ushort.MaxValue][];
			if (_nitTransportStreams[networkId] == null)
				_nitTransportStreams[networkId] = new NitTransportStream[ushort.MaxValue];
		}
	}
}
