using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Npgsql;

namespace skyscraper5.Data.PostgreSql
{
	public delegate void WriterTask(NpgsqlConnection connection);

	public partial class PostgresqlDataStore
    {
        private Thread _writerThread;

        

        private Queue<WriterTask> _writerTasks;

        internal void EnqueueTask(WriterTask task)
        {
            if (_writerTasks == null)
            {
                _writerTasks = new Queue<WriterTask>();
            }

            lock (_writerTasks)
            {
	            _writerTasks.Enqueue(task);
            }

            if (_writerThread == null)
            {
                _writerThread = new Thread(WriterThreadFunction);
                _writerThread.Priority = ThreadPriority.Highest;
                _writerThread.Name = "PostgreSQL Writer Thread";
                _writerThread.Start();
            }
        }

        private NpgsqlTransaction transaction;
        private void WriterThreadFunction()
        {
            using (NpgsqlConnection connection = new NpgsqlConnection(connectionStringBuilder.ToString()))
            {
                connection.Open();
                transaction = connection.BeginTransaction();
                while (_writerTasks.Count > 0)
                {
	                WriterTask task;
	                lock (_writerTasks)
	                {
		                task = _writerTasks.Dequeue();
	                }
	                task(connection);
                }
                transaction.Commit();
                transaction.Dispose();
                connection.Close();
            }

            _writerThread = null;
        }

        private void CommitTransaction(NpgsqlConnection conn)
        {
			transaction.Commit();
			transaction.Dispose();
			transaction = conn.BeginTransaction();
            if (_isWaitingForCompletion)
            {
                Console.WriteLine("-> DB: {0} tasks remain.", _writerTasks.Count);
            }
		}
    }
}
