using System;
using System.Threading.Tasks;

namespace Server.Core
{
    public class WaitCoroutineLock
    {
        private TaskCompletionSource<CoroutineLock> tcs;
        
        public static WaitCoroutineLock Create()
        {
            WaitCoroutineLock waitCoroutineLock = new WaitCoroutineLock();
            waitCoroutineLock.tcs = new TaskCompletionSource<CoroutineLock>();
            return waitCoroutineLock;
        }

        public void SetResult(CoroutineLock coroutineLock)
        {
            if (this.tcs == null)
            {
                throw new NullReferenceException("SetResult tcs is null");
            }

            var t = this.tcs;
            this.tcs = null;
            t.SetResult(coroutineLock);
        }

        public void SetException(Exception exception)
        {
            if (this.tcs == null)
            {
                throw new NullReferenceException("SetException tcs is null");
            }

            var t = this.tcs;
            this.tcs = null;
            t.SetException(exception);
        }

        public bool IsDisposed()
        {
            return this.tcs == null;
        }

        public async Task<CoroutineLock> Wait()
        {
            return await this.tcs.Task;
        }
    }
}