﻿using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace DrivenRop.Tests
{
   [TestClass]
   public class ThenTeeAsyncToAsyncTests
   {
      [TestMethod]
      public void AsyncToAsyncWorksProperly()
      {
         var helper = new TeeHelper();
         Task.FromResult(new[] { 1, 2, 3 })
            .ThenTeeAsync(helper.Increment).GetAwaiter().GetResult();
         Assert.IsTrue(
            helper.Result.SequenceEqual(new[] { 2, 3, 4 }));
      }

      [TestMethod]
      public void AsyncToAsyncWorksProperly1()
      {
         var helper = new TeeHelper();
         Task.FromResult(new[] { 1, 2, 3 })
            .ThenTeeAsync(helper.Increment1, 1).GetAwaiter().GetResult();
         Assert.IsTrue(
            helper.Result.SequenceEqual(new[] { 2, 3, 4 }));
      }

      [TestMethod]
      public void AsyncToAsyncWorksProperly2()
      {
         var helper = new TeeHelper();
         Task.FromResult(new[] { 1, 2, 3 })
            .ThenTeeAsync(helper.Increment2, 1, 1).GetAwaiter().GetResult();
         Assert.IsTrue(
            helper.Result.SequenceEqual(new[] { 3, 4, 5 }));
      }

      [TestMethod]
      public void AsyncToAsyncWorksProperly3()
      {
         var helper = new TeeHelper();
         Task.FromResult(new[] { 1, 2, 3 })
            .ThenTeeAsync(helper.Increment3, 1, 1, 1).GetAwaiter().GetResult();
         Assert.IsTrue(
            helper.Result.SequenceEqual(new[] { 4, 5, 6 }));
      }

      [TestMethod]
      public void AsyncToAsyncWorksProperly4()
      {
         var helper = new TeeHelper();
         Task.FromResult(new[] { 1, 2, 3 })
            .ThenTeeAsync(helper.Increment4, 1, 1, 1, 1).GetAwaiter().GetResult();
         Assert.IsTrue(
            helper.Result.SequenceEqual(new[] { 5, 6, 7 }));
      }

      [TestMethod]
      public void AsyncToAsyncWorksProperly5()
      {
         var helper = new TeeHelper();
         Task.FromResult(new[] { 1, 2, 3 })
            .ThenTeeAsync(helper.Increment5, 1, 1, 1, 1, 1).GetAwaiter().GetResult();
         Assert.IsTrue(
            helper.Result.SequenceEqual(new[] { 6, 7, 8 }));
      }

      // INFRASTRUCTURE

      private class TeeHelper
      {
         public IEnumerable<int> Result;

         public Task Increment(IEnumerable<int> values)
         {
            return Task.FromResult(Result = values.Select(v => v + 1));
         }

         public Task Increment1(IEnumerable<int> values, int value1)
         {
            return Task.FromResult(Result = values.Select(v => v + value1));
         }

         public Task Increment2(IEnumerable<int> values, int value1, int value2)
         {
            return Task.FromResult(Result = values.Select(v => v + value1 + value2));
         }

         public Task Increment3(IEnumerable<int> values, int value1, int value2, int value3)
         {
            return Task.FromResult(Result = values.Select(v => v + value1 + value2 + value3));
         }

         public Task Increment4(IEnumerable<int> values, int value1, int value2, int value3, int value4)
         {
            return Task.FromResult(Result = values.Select(v => v + value1 + value2 + value3 + value4));
         }

         public Task Increment5(IEnumerable<int> values, int value1, int value2, int value3, int value4, int value5)
         {
            return Task.FromResult(Result = values.Select(v => v + value1 + value2 + value3 + value4 + value5));
         }
      }
   }
}
