﻿/*
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

namespace DotPulsar.Internal;

using Abstractions;
using Exceptions;
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;

public sealed class AsyncQueue<T> : IEnqueue<T>, IDequeue<T>, IDisposable
{
    private readonly object _lock;
    private readonly Queue<T> _queue;
    private readonly LinkedList<CancelableCompletionSource<T>> _pendingDequeues;
    private int _isDisposed;

    public AsyncQueue()
    {
        _lock = new object();
        _queue = new Queue<T>();
        _pendingDequeues = new LinkedList<CancelableCompletionSource<T>>();
    }

    public void Enqueue(T item)
    {
        lock (_lock)
        {
            ThrowIfDisposed();

            var node = _pendingDequeues.First;
            if (node is not null)
            {
                node.Value.SetResult(item);
                node.Value.Dispose();
                _pendingDequeues.RemoveFirst();
            }
            else
                _queue.Enqueue(item);
        }
    }

    public ValueTask<T> Dequeue(CancellationToken cancellationToken = default)
    {
        LinkedListNode<CancelableCompletionSource<T>>? node = null;

        lock (_lock)
        {
            ThrowIfDisposed();

            if (_queue.Count > 0)
                return new ValueTask<T>(_queue.Dequeue());

            node = _pendingDequeues.AddLast(new CancelableCompletionSource<T>());
        }

        node.Value.SetupCancellation(() => Cancel(node), cancellationToken);
        return new ValueTask<T>(node.Value.Task);
    }

    public void Dispose()
    {
        lock (_lock)
        {
            if (Interlocked.Exchange(ref _isDisposed, 1) != 0)
                return;

            foreach (var pendingDequeue in _pendingDequeues)
                pendingDequeue.Dispose();

            _pendingDequeues.Clear();
            _queue.Clear();
        }
    }

    private void Cancel(LinkedListNode<CancelableCompletionSource<T>> node)
    {
        lock (_lock)
        {
            try
            {
                node.Value.Dispose();
                _pendingDequeues.Remove(node);
            }
            catch
            {
                // ignored
            }
        }
    }

    private void ThrowIfDisposed()
    {
        if (_isDisposed != 0)
            throw new AsyncQueueDisposedException();
    }
}
