using System;
using System.Collections.Concurrent;
using SQLitePCL.pretty;
namespace Emby.Server.Implementations.Data;
/// 
/// A pool of SQLite Database connections.
/// 
public sealed class ConnectionPool : IDisposable
{
    private readonly BlockingCollection _connections = new();
    private bool _disposed;
    /// 
    /// Initializes a new instance of the  class.
    /// 
    /// The number of database connection to create.
    /// Factory function to create the database connections.
    public ConnectionPool(int count, Func factory)
    {
        for (int i = 0; i < count; i++)
        {
            _connections.Add(factory.Invoke());
        }
    }
    /// 
    /// Gets a database connection from the pool if one is available, otherwise blocks.
    /// 
    /// A database connection.
    public ManagedConnection GetConnection()
    {
        if (_disposed)
        {
            ThrowObjectDisposedException();
        }
        return new ManagedConnection(_connections.Take(), this);
        static void ThrowObjectDisposedException()
        {
            throw new ObjectDisposedException(nameof(ConnectionPool));
        }
    }
    /// 
    /// Return a database connection to the pool.
    /// 
    /// The database connection to return.
    public void Return(SQLiteDatabaseConnection connection)
    {
        if (_disposed)
        {
            connection.Dispose();
            return;
        }
        _connections.Add(connection);
    }
    /// 
    public void Dispose()
    {
        if (_disposed)
        {
            return;
        }
        foreach (var connection in _connections)
        {
            connection.Dispose();
        }
        _connections.Dispose();
        _disposed = true;
    }
}