using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ex_052_004_problématique_4
{
    class Program
    {
        static Task DisplayPrimeCountsAsync()
        {
            var machine = new PrimesStateMachine();
            machine.DisplayPrimeCountsFrom(0);
            return machine.Task;
        }

        static void Main(string[] args)
        {
            Task.Run(() => DisplayPrimeCountsAsync());
            Console.WriteLine("please wait...");
            Console.ReadLine();
        }


    }

    class PrimesStateMachine
    {
        TaskCompletionSource<object> mTcs = new TaskCompletionSource<object>();
        
        public Task Task
        {
            get
            {
                return mTcs.Task;
            }
        }

        Task<int> GetPrimesCountAsync(int start, int count)
        {
            return Task.Run(() => Enumerable.Range(start, count).Count(n =>
                Enumerable.Range(2, (int)Math.Sqrt(n) - 1).All(i => n % i > 0)));
        }

        public void DisplayPrimeCountsFrom(int i)
        {
            var awaiter = GetPrimesCountAsync(i * 1000000 + 2, 1000000).GetAwaiter();
            awaiter.OnCompleted(() =>
                {
                    Console.WriteLine("{0} primes between {1} and {2}",
                                    awaiter.GetResult(),
                                    i * 1000000,
                                    (i + 1) * 1000000 - 1);
                    if (i++ < 10)
                    {
                        DisplayPrimeCountsFrom(i);
                    }
                    else
                    {
                        Console.WriteLine("Done");
                        mTcs.SetResult(null);
                    }
                });
        }
    }
}
