using System;
using System.Collections.Concurrent;
using System.Diagnostics;
using System.Threading;
using System.Threading.Tasks;
namespace FastGithub.Http
{
    /// 
    /// 表示LifetimeHttpHandler清理器
    /// 
    sealed class LifetimeHttpHandlerCleaner
    {
        /// 
        /// 当前监视生命周期的记录的数量
        /// 
        private int trackingEntryCount = 0;
        /// 
        /// 监视生命周期的记录队列
        /// 
        private readonly ConcurrentQueue trackingEntries = new();
        /// 
        /// 获取或设置清理的时间间隔
        /// 默认10s
        /// 
        public TimeSpan CleanupInterval { get; set; } = TimeSpan.FromSeconds(10d);
        /// 
        /// 添加要清除的httpHandler
        /// 
        /// httpHandler
        public void Add(LifetimeHttpHandler handler)
        {
            var entry = new TrackingEntry(handler);
            this.trackingEntries.Enqueue(entry);
            // 从0变为1,要启动清理作业
            if (Interlocked.Increment(ref this.trackingEntryCount) == 1)
            {
                this.StartCleanup();
            }
        }
        /// 
        /// 启动清理作业
        /// 
        private async void StartCleanup()
        {
            await Task.Yield();
            while (this.Cleanup() == false)
            {
                await Task.Delay(this.CleanupInterval);
            }
        }
        /// 
        /// 清理失效的拦截器
        /// 返回是否完全清理
        /// 
        /// 
        private bool Cleanup()
        {
            var cleanCount = this.trackingEntries.Count;
            for (var i = 0; i < cleanCount; i++)
            {
                this.trackingEntries.TryDequeue(out var entry);
                Debug.Assert(entry != null);
                if (entry.CanDispose == false)
                {
                    this.trackingEntries.Enqueue(entry);
                    continue;
                }
                entry.Dispose();
                if (Interlocked.Decrement(ref this.trackingEntryCount) == 0)
                {
                    return true;
                }
            }
            return false;
        }
        /// 
        /// 表示监视生命周期的记录
        /// 
        private class TrackingEntry : IDisposable
        {
            /// 
            /// 用于释放资源的对象
            /// 
            private readonly IDisposable disposable;
            /// 
            /// 监视对象的弱引用
            /// 
            private readonly WeakReference weakReference;
            /// 
            /// 获取是否可以释放资源
            /// 
            /// 
            public bool CanDispose => this.weakReference.IsAlive == false;
            /// 
            /// 监视生命周期的记录
            /// 
            /// 激活状态的httpHandler
            public TrackingEntry(LifetimeHttpHandler handler)
            {
                this.disposable = handler.InnerHandler!;
                this.weakReference = new WeakReference(handler);
            }
            /// 
            /// 释放资源
            /// 
            public void Dispose()
            {
                try
                {
                    this.disposable.Dispose();
                }
                catch (Exception)
                {
                }
            }
        }
    }
}