using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using System.Runtime.ExceptionServices;
using System.Threading.Tasks;
using Fort23.UTool;
namespace Fort23.Core
{
    public enum AwaiterStatus
    {
        Pending,
        Succeeded,
        Faulted,
    }
    /// 
    /// 这是一个同步等待异步的框架, 如果要使用真正的异步,请使用Task
    /// A
    /// 
    [AsyncMethodBuilder(typeof(AsyncTaskMethodBuilder))]
    public class CTask : ICTaskResult, IAwaitable, IAwaiter
    {
        private Action _continuation;
        private AwaiterStatus state;
        private Exception _exception;
        private static readonly Queue queue = new Queue();
        public int currIndex = 0;
        static int allIndex = 0;
        public static bool isHindPool=false;
        /// 
        /// 创建  的新实例,并得到一个可以用于报告操作执行完毕的委托。
        /// 
        /// 
        /// 创建好的  的新实例,将此返回值作为方法的返回值可以让方法支持 await 异步等待。
        /// 
        public static CTask Create(bool isPool=true)
        {
#if !COMBAT_SERVER
            
            lock (queue)
            {
                if (queue.Count == 0||!isPool||isHindPool)
                {
                    CTask cTask = new CTask();
                    allIndex++;
                    cTask.currIndex = allIndex;
                    return cTask;
                }
                CTask value = queue.Dequeue();
                value.state = AwaiterStatus.Pending;
                return value;
            }
#endif
            return  new CTask();
            // var task = new CTask();
            // return task;
        }
        private CTask()
        {
        }
        public CTask GetAwaiter()
        {
            return this;
        }
        public bool IsCompleted
        {
            get { return this.state != AwaiterStatus.Pending; }
        }
        public void OnCompleted(Action continuation)
        {
            if (IsCompleted)
            {
                continuation?.Invoke();
            }
            else
            {
                _continuation += continuation;
            }
        }
        // private T Result { get; set; }
        /// 
        /// 这个方法在return await CTask的时候自动调用
        /// 
        public void GetResult()
        {
            if (_exception != null)
            {
                ExceptionDispatchInfo.Capture(_exception).Throw();
            }
            Recycle();
        }
        /// 
        /// 调用此方法以报告任务结束,并指定返回值和异步任务中的异常。
        /// 当使用  静态方法创建此类型的实例后,调用方可以通过方法参数中传出的委托来调用此方法。
        /// 
        /// 异步操作中的异常。
        public void SetResult(Exception exception = null)
        {
            _exception = exception;
            if (AwaiterStatus.Faulted == state)
            {
                return;
            }
            this.state = AwaiterStatus.Succeeded;
            if (_continuation != null)
            {
                _continuation.Invoke();
            }
        }
        public void SetResult()
        {
            SetResult(null);
        }
        /// 
        /// 
        /// 
        /// 
        public void SetException(Exception exception)
        {
            this.state = AwaiterStatus.Faulted;
            _exception = exception;
            LogTool.Error(_exception);
        }
        private void Recycle()
        {
            _continuation = null;
            _exception = null;
            if (state == AwaiterStatus.Pending)
            {
                return;
            }
            this.state = AwaiterStatus.Pending;
#if !COMBAT_SERVER
            lock (queue)
            {
                // 太多了
                if (queue.Count > 300||isHindPool)
                {
                    return;
                }
                if (queue.Contains(this))
                {
                    return;
                }
                queue.Enqueue(this);
            }
#endif
        }
        public override async Task AwaitTask()
        {
            await this;
        }
    }
    /// 
    /// 这是一个同步等待异步的框架, 如果要使用真正的异步,请使用Task
    /// A
    /// 
    /// 
    [AsyncMethodBuilder(typeof(AsyncTaskMethodBuilder<>))]
    public class CTask : ICTaskResult, IAwaitable, T>, IAwaiter
    {
        private Action _continuation;
        private AwaiterStatus state;
        private Exception _exception;
#if !COMBAT_SERVER
        private static readonly Queue> queue = new Queue>();
#endif
        public static bool isHindPool=false;
        /// 
        /// 创建  的新实例,并得到一个可以用于报告操作执行完毕的委托。
        /// 
        /// 
        /// 创建好的  的新实例,将此返回值作为方法的返回值可以让方法支持 await 异步等待。
        /// 
        public static CTask Create(bool isPool=true)
        {
#if !COMBAT_SERVER
            lock (queue)
            {
                if (queue.Count == 0||!isPool||isHindPool)
                {
                    return new CTask();
                }
                CTask value = queue.Dequeue();
                value.state = AwaiterStatus.Pending;
                return value;
            }
#endif
            return new CTask();
            // var task = new CTask();
            // return task;
        }
        private CTask()
        {
        }
        public CTask GetAwaiter()
        {
            return this;
        }
        public bool IsCompleted
        {
            get { return state != AwaiterStatus.Pending; }
        }
        public void OnCompleted(Action continuation)
        {
            if (IsCompleted)
            {
                continuation?.Invoke();
            }
            else
            {
                _continuation += continuation;
            }
        }
        private T _result;
        public T Result
        {
            get { return _result; }
        }
        /// 
        /// 这个方法在return await CTask的时候自动调用
        /// 
        /// 
        public T GetResult()
        {
            if (_exception != null)
            {
                ExceptionDispatchInfo.Capture(_exception).Throw();
            }
            Recycle();
            return _result;
        }
        /// 
        /// 调用此方法以报告任务结束,并指定返回值和异步任务中的异常。
        /// 当使用  静态方法创建此类型的实例后,调用方可以通过方法参数中传出的委托来调用此方法。
        /// 
        /// 异步返回值。
        /// 异步操作中的异常。
        public void SetResult(T result, Exception exception = null)
        {
            _result = result;
            _exception = exception;
            if (this.state == AwaiterStatus.Faulted)
            {
                return;
            }
            this.state = AwaiterStatus.Succeeded;
            if (_continuation != null)
            {
                _continuation.Invoke();
            }
        }
        /// 
        /// 
        /// 
        /// 
        public void SetException(Exception exception)
        {
            this.state = AwaiterStatus.Faulted;
            _exception = exception;
            LogTool.Error(_exception);
        }
        private void Recycle()
        {
            _continuation = null;
            _exception = null;
            if (state == AwaiterStatus.Pending)
            {
                return;
            }
            this.state = AwaiterStatus.Pending;
#if !COMBAT_SERVER
            lock (queue)
            {
                // 太多了,回收一下
                if (queue.Count > 300||isHindPool)
                {
                    return;
                }
                if (queue.Contains(this))
                {
                    return;
                }
                queue.Enqueue(this);
            }
#endif
        }
        public override async Task AwaitTask()
        {
            await this;
        }
    }
}