using AsbCloudApp.Data;
using AsbCloudApp.Services;
using Moq;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Xunit;

namespace AsbCloudWebApi.Tests.ServicesTests
{
    public class DrillerServiceTest
    {
        private static List<DrillerDto> Drillers = new List<DrillerDto> { 
            new DrillerDto
            {
                Id = 1,
                Name = "Тестовый",
                Patronymic = "Тест",
                Surname = "Тестович"
            },
            new DrillerDto
            {
                Id = 1,
                Name = "Тестовый",
                Patronymic = "Тест",
                Surname = "Тестович"
            }
        };
        private ICrudRepository<DrillerDto> service;

        public DrillerServiceTest()
        {
            var repositoryMock = RepositoryFactory.Make<ICrudRepository<DrillerDto>, DrillerDto>(Drillers);

            repositoryMock.Setup(x => x.GetAllAsync(It.IsAny<CancellationToken>()))
                .Returns(() => {
                    var data = Drillers;
                    return Task.FromResult(data.AsEnumerable());
                });
            repositoryMock.Setup(x => x.InsertAsync(It.IsAny<DrillerDto>(), It.IsAny<CancellationToken>()))
                .Returns((DrillerDto dto, CancellationToken token) => {
                    Drillers.Add(dto);
                    return Task.FromResult(Drillers.Count());
                });
            repositoryMock.Setup(x => x.UpdateAsync(It.IsAny<DrillerDto>(), It.IsAny<CancellationToken>()))
                .Returns((DrillerDto dto, CancellationToken token) => {
                    var baseDto = Drillers.First(x => x.Id == dto.Id);

                    Drillers.Remove(baseDto);
                    Drillers.Add(dto);

                    return Task.FromResult(Drillers.Count());
                });

            service = repositoryMock.Object;
        }

        ~DrillerServiceTest()
        {
        }

        [Fact]
        public async Task GetListAsync_count()
        {
            var data = await service.GetAllAsync(CancellationToken.None);
            Assert.Equal(2, data.Count());
        }

        [Fact]
        public async Task InsertAsync_returns_id()
        {
            var dto = new DrillerDto {
                Id = 3,
                Name = "Тестовый",
                Patronymic = "Тест",
                Surname = "Тестович"
            };
            var cnt = await service.InsertAsync(dto, CancellationToken.None);
            Assert.Equal(3, cnt);
        }

        [Fact]
        public async Task UpdateAsync_not_add_if_exists()
        {
            var dto = Drillers.First(x => x.Id == 1);
            dto.Name = "Edit";
            var oldCount = Drillers.Count();
            var count = await service.UpdateAsync(dto, CancellationToken.None);
            Assert.Equal(oldCount, count);
        }
    }
}