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

namespace CodeUtilsTests
{
	class AutoThreadProxyTest
	{
		[Test]
		public void Run()
		{
			var proxy = new AutoThreadProxy();
			proxy.UnhandledException += HandleUnhandledException;

			for (int i = 0; i < 100; ++i)
			{
				var index = i;
				proxy.QueueWorkItem(() => Debug.WriteLine("item" + index));
			}

			proxy.QueueWorkItem(() => { throw new Exception("bogus"); });

			Debug.WriteLine("some shit");
			{
				var wait = new AutoWaitManager();
				proxy.QueueWorkItem(wait.Set);
				wait.Wait(Timeout.Infinite, CancellationToken.None);
			}

			GC.Collect();

		}

		[Test]
		public void PerformanceTest()
		{
			var options = new AutoThreadProxyOptions();
			// Keep threads alive for 500 ms after all items have been executed.
			options.KeepAliveTime_ms = 500;
			var proxy = new AutoThreadProxy(options);

			// testing synchronous execution performance
			{
				var wait = new AutoWaitManager();
				var sw = Stopwatch.StartNew();
				int calls = 1000;
				for (int i = 0; i < calls; ++i)
				{
					wait.Reset();
					var index = i;
					proxy.QueueWorkItem(wait.Set);
					wait.Wait(Timeout.Infinite, CancellationToken.None);
				}
				Debug.WriteLine($"Synchronous execution performance: {(double)sw.ElapsedMilliseconds / (double)calls} ms/call.");
			}

			GC.Collect();
		}

		static void HandleUnhandledException(object sender, UnhandledAutoThreadProxyExceptionEventArgs e)
		{
			Debug.WriteLine(e.ExceptionDispatchInfo.ToString());
		}
	}
}
