using System;
using System.Collections.Generic;
using System.Linq;

namespace Fort23.Core
{
    public class CTaskAwaitBuffer : IDisposable
    {
        private List<ICTaskResult> _cTasks = new List<ICTaskResult>();

        public ICTaskResult[] GetTask
        {
            get { return _cTasks.ToArray(); }
        } 

        private int count;
        private CTask CTask;

        private bool _isWait;

        public void Clear()
        {
            _cTasks.Clear();
            _isWait = false;
            CTask = null;
            count = 0;
        }

        public void AddTask(ICTaskResult icTaskResult)
        {
            _cTasks.Add(icTaskResult);
            if (_isWait)
            {
                count++;
                AwaitTask(icTaskResult);
            }
        }

        public async CTask WaitAll()
        {
            _isWait = true;
            count += _cTasks.Count;

            if (count == 0)
            {
                return;
            }

            CTask = CTask.Create(false);
            ICTaskResult[] icTaskResults=  _cTasks.ToArray();
            for (int i = 0; i < icTaskResults.Length; i++)
            {
                AwaitTask(icTaskResults[i]);
            }

            await CTask;
        }


        public async void AwaitTask(ICTaskResult icTaskResult)
        {
            await icTaskResult.AwaitTask();
            count--;
            _cTasks.Remove(icTaskResult);
            if (count <= 0 && _isWait)
            {
                _isWait = false;
                CTask cta = CTask;
                if (_cTasks != null)
                {
                    _cTasks.Clear();
                }

                count = 0;
                cta.SetResult();
            }
        }

        public void Dispose()
        {
            _cTasks.Clear();
            CTask = null;
            _isWait = false;
        }
    }
}