﻿/*
 * 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 Exceptions;
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;

public sealed class AsyncLock : IAsyncDisposable
{
    private readonly LinkedList<CancelableCompletionSource<IDisposable>> _pending;
    private readonly SemaphoreSlim _semaphoreSlim;
    private readonly Releaser _releaser;
    private readonly Task<IDisposable> _completedTask;
    private int _isDisposed;

    public AsyncLock()
    {
        _pending = new LinkedList<CancelableCompletionSource<IDisposable>>();
        _semaphoreSlim = new SemaphoreSlim(1, 1);
        _releaser = new Releaser(Release);
        _completedTask = Task.FromResult((IDisposable) _releaser);
    }

    public Task<IDisposable> Lock(CancellationToken cancellationToken)
    {
        LinkedListNode<CancelableCompletionSource<IDisposable>>? node = null;

        lock (_pending)
        {
            ThrowIfDisposed();

            if (_semaphoreSlim.CurrentCount == 1) //Lock is free
            {
                _semaphoreSlim.Wait(cancellationToken); //Will never block
                return _completedTask;
            }

            //Lock was not free
            var ccs = new CancelableCompletionSource<IDisposable>();
            node = _pending.AddLast(ccs);
        }

        cancellationToken.Register(() => Cancel(node));

        return node.Value.Task;
    }

    public async ValueTask DisposeAsync()
    {
        lock (_pending)
        {
            if (Interlocked.Exchange(ref _isDisposed, 1) != 0)
                return;

            foreach (var pending in _pending)
                pending.Dispose();

            _pending.Clear();
        }

        await _semaphoreSlim.WaitAsync().ConfigureAwait(false); //Wait for possible lock-holder to finish

        _semaphoreSlim.Release();
        _semaphoreSlim.Dispose();
    }

    private void Cancel(LinkedListNode<CancelableCompletionSource<IDisposable>> node)
    {
        lock (_pending)
        {
            try
            {
                _pending.Remove(node);
                node.Value.Dispose();
            }
            catch
            {
                // Ignore
            }
        }
    }

    private void Release()
    {
        lock (_pending)
        {
            var node = _pending.First;
            if (node is not null)
            {
                node.Value.SetResult(_releaser);
                node.Value.Dispose();
                _pending.RemoveFirst();
                return;
            }

            if (_semaphoreSlim.CurrentCount == 0)
                _semaphoreSlim.Release();
        }
    }

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

    private class Releaser : IDisposable
    {
        private readonly Action _release;

        public Releaser(Action release)
            => _release = release;

        public void Dispose()
            => _release();
    }
}
