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

using Moq;
using Moq.Internals;
using Moq.Language;
using Moq.Protected;

using OAuth2Study.Model;
using OAuth2Study.IDal;
using OAuth2Study.Dal.MsSql;
using OAuth2Study.IBll;
using OAuth2Study.Bll;

namespace OAuth2Study.UnitTest
{
    public class UserMoqFixture : IDisposable
    {
        public Mock<UserIDal> mockDal;
        public Mock<UserIBll> mockBll;
        public List<User> users;

        public UserMoqFixture()
        {
            mockDal = new Mock<UserIDal>();
            mockBll = new Mock<UserIBll>();

            users = new List<User>()
            {
                new User(){Id=1,Name="first",Password="123456", Age=1,Gender=0},
                new User(){Id=2,Name="second",Password="123456", Age=2,Gender=0},
                new User(){Id=3,Name="third",Password="123456", Age=3,Gender=0},
                new User(){Id=4,Name="four",Password="123456", Age=4,Gender=0},
                new User(){Id=5,Name="five",Password="123456", Age=5,Gender=0},
            };

            SetUserDal();
            SetUserBll();
        }

        private void SetUserDal()
        {
            mockDal.Setup(u => u.AddUser(It.Is<User>(para => new List<int>() {1,2,3,4,5 }.Contains(para.Id))))
                .Returns((User user) => (true, user));
            

            mockDal.Setup(u => u.UpdateUser(It.Is<User>(para => new List<int>() {1,2,3,4,5 }.Contains(para.Id))))
                .Returns((User user) => (true, user));

            mockDal.Setup(u => u.RemoveUser(It.Is<User>(para => new List<int>() { 1, 2, 3, 4, 5 }.Contains(para.Id))))
                .Returns((User user) => (true));

            mockDal.Setup(u => u.GetUser(It.IsAny<int>()))
                .Returns((int userId) => (users.SingleOrDefault(q => q.Id == userId)));

            mockDal.Setup(u => u.ExitsByName(It.IsAny<string>()))
                .Returns((string userName) => (users.Any(q => q.Name == userName)));

            mockDal.Setup(u => u.GetUsers())
                .Returns(users.AsQueryable);

        }

        private void SetUserBll()
        {
            mockBll.Setup(u => u.AddUser(It.Is<User>(para => new List<int>() { 1, 2, 3, 4, 5 }.Contains(para.Id))))
                .Returns((User user) => (true, user));


            mockBll.Setup(u => u.UpdateUser(It.Is<User>(para => new List<int>() { 1, 2, 3, 4, 5 }.Contains(para.Id))))
                .Returns((User user) => (true, user));

            mockBll.Setup(u => u.RemoveUser(It.Is<User>(para => new List<int>() { 1, 2, 3, 4, 5 }.Contains(para.Id))))
                .Returns((User user) => (true));

            mockBll.Setup(u => u.GetUser(It.IsAny<int>()))
                .Returns((int userId) => (users.SingleOrDefault(q => q.Id == userId)));

            mockBll.Setup(u => u.ExitsByName(It.IsAny<string>()))
                .Returns((string userName) => (users.Any(q => q.Name == userName)));

            mockBll.Setup(u => u.GetUsers())
                .Returns(users.AsQueryable);
        }

        public void Dispose()
        {
           
        }
    }
}