using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Npgsql;
using NpgsqlTypes;
using skyscraper5.Mpeg2.Descriptors;
using skyscraper5.Skyscraper.Scraper.Storage.Utilities;

namespace skyscraper5.Data.PostgreSql
{
	public partial class PostgresqlDataStore
	{
		private HashSet<DatabaseKeyCat> _knownCats;
		public bool TestForCaSystem(int currentNetworkId, int currentTransportStreamId, int caDescriptorCaPid)
		{
			if (_knownCats == null)
				_knownCats = new HashSet<DatabaseKeyCat>();

			DatabaseKeyCat key = new DatabaseKeyCat(currentNetworkId, currentTransportStreamId, caDescriptorCaPid);
			if (_knownCats.Contains(key))
				return true;

			bool result = false;
			using (NpgsqlConnection conn = new NpgsqlConnection(connectionStringBuilder.ToString()))
			{
				conn.Open();
				result = TestForCaSystemEx(currentNetworkId, currentTransportStreamId, caDescriptorCaPid, conn);
				conn.Close();
			}

			if (result)
				_knownCats.Add(key);

			return result;

		}

		private static bool TestForCaSystemEx(int currentNetworkId, int currentTransportStreamId, int caDescriptorCaPid, NpgsqlConnection conn)
		{
			bool result;
			NpgsqlCommand command = conn.CreateCommand();
			command.CommandText = "SELECT dateadded FROM dvb_cat WHERE nid = @nid AND tsid = @tsid AND pid = @pid";
			command.Parameters.AddWithValue("@nid", NpgsqlDbType.Integer, currentNetworkId);
			command.Parameters.AddWithValue("@tsid", NpgsqlDbType.Integer, currentTransportStreamId);
			command.Parameters.AddWithValue("@pid", NpgsqlDbType.Integer, caDescriptorCaPid);
			NpgsqlDataReader dataReader = command.ExecuteReader();
			result = dataReader.Read();
			dataReader.Close();
			command.Dispose();
			return result;
		}

		public void StoreCaSystem(int currentNetworkId, int currentTransportStreamId, CaDescriptor caDescriptor)
		{
			EnqueueTask(x => WriteCaSystems(x, currentNetworkId, currentTransportStreamId, caDescriptor));
			DatabaseKeyCat key = new DatabaseKeyCat(currentNetworkId, currentTransportStreamId, caDescriptor.CaPid);
			_knownCats.Add(key);
		}

		private void WriteCaSystems(NpgsqlConnection connection, int currentNetworkId, int currentTransportStreamId, CaDescriptor caDescriptor)
		{
			if (TestForCaSystemEx(currentNetworkId,currentTransportStreamId,caDescriptor.CaPid,connection))
			{
				return;
			}
			NpgsqlCommand command = connection.CreateCommand();
			command.CommandText = "INSERT INTO dvb_cat (nid,tsid,pid,ca_system_id,private_data) " +
			                      "VALUES (@nid,@tsid,@pid,@ca_system_id,@private_data)";
			command.Parameters.AddWithValue("@nid", NpgsqlDbType.Integer, currentNetworkId);
			command.Parameters.AddWithValue("@tsid", NpgsqlDbType.Integer, currentTransportStreamId);
			command.Parameters.AddWithValue("@pid", NpgsqlDbType.Integer, caDescriptor.CaPid);
			command.Parameters.AddWithValue("@ca_system_id", NpgsqlDbType.Integer, (int)caDescriptor.CaSystemId);

			object privateData = DBNull.Value;
			if (caDescriptor.PrivateData != null && caDescriptor.PrivateData.Length > 0)
				privateData = caDescriptor.PrivateData;

			command.Parameters.AddWithValue("@private_data", NpgsqlDbType.Bytea, privateData);
			command.ExecuteNonQuery();
		}
	}
}
