using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using AprsSharp.Parsers.Aprs;
using GeoCoordinatePortable;
using Npgsql;
using skyscraper5.Aprs.AprsSharp;
using skyscraper5.Aprs.AprsStorage;
using skyscraper5.Ietf.Rfc971;
using skyscraper5.Skyscraper.Plugins;
using skyscraper5.Skyscraper.Scraper.Storage;
using skyscraper5.Skyscraper.Scraper;
using skyscraper5.Skyscraper.Scraper.Storage.InMemory;

namespace skyscraper5.Aprs
{
	[SkyscraperPlugin]
	[PluginPriority(1)]
	internal class Lx9SesPlugin : ISkyscraperMpePlugin
	{
		public void ConnectToStorage(object[] connector, PluginLogMessage logger)
		{
			bool skipNext = false;
			foreach (object o in connector)
			{
				if (skipNext)
				{
					skipNext = false;
					continue;
				}
				Type connectorType = o.GetType();
				if (connectorType == typeof(InMemoryPluginToken))
				{
					_storage = new AprsInMemoryStorage((InMemoryPluginToken)o);
					break;
				}
				else if (connectorType == typeof(NpgsqlConnectionStringBuilder))
				{
					_storage = new AprsPostgresqlStorage((NpgsqlConnectionStringBuilder)o);
				}
				else
				{
					if (connectorType.Name.Equals("MinioClient"))
					{
						skipNext = true;
						continue;
					}

					if (connectorType.Name.Equals("DirectoryInfo"))
					{
						skipNext = true;
						continue;
					}

					throw new NotImplementedException();
				}
			}

			messageReceiver = new LX9SESMessageReceiver(_storage, logger);
		}

		public void SetContext(DateTime? currentDateTime)
		{
			messageReceiver.currentTime = currentDateTime;
		}

		public bool CanHandlePacket(InternetHeader internetHeader, byte[] ipv4Packet)
		{
			if (internetHeader.Protocol == 0x11)
			{
				if (internetHeader.SourceAddress.Equals(_lx9sesSrc) && internetHeader.DestinationAddress.Equals(_lx9sesDst))
				{
					return true;
				}
			}

			return false;
		}

		public void HandlePacket(InternetHeader internetHeader, byte[] ipv4Packet)
		{
			if (_aprsDecoder == null)
				_aprsDecoder = new AprsDecoder(messageReceiver);
			_aprsDecoder.OnIpv4PacketArrival(internetHeader, ipv4Packet);
		}

		public bool StopProcessingAfterThis()
		{
			return true;
		}

		private AprsDecoder _aprsDecoder;
		private static readonly IPAddress _lx9sesDst = IPAddress.Parse("228.64.0.56");
		private static readonly IPAddress _lx9sesSrc = IPAddress.Parse("10.225.49.1");
		private LX9SESStorage _storage;
		private LX9SESMessageReceiver messageReceiver;


	}


}
