using NUnit.Framework;
using Wierszowki.Core.Interfaces;
using Wierszowki.Core.Linq;
using Wierszowki.Services;

namespace Wierszowki.Tests.Core
{
    [TestFixture]
    public class UserRepositoryTests
    {
        [Test]
        public void User_Tries_To_Find_User_Returns_True()
        {
            const string login = "marek";
            const string password = "marek";
            
            IRepository<User> userRepository = new LinqRepository<User>();
            //IRepository<User> userRepository = new TestUserRepository();

            User user;
            var found = userRepository.TryFindOne(u => u.Login == login && u.Password == password, out user);

            Assert.That(found, Is.True);
            Assert.That(user, Is.Not.Null);
            Assert.That(user.Login, Is.EqualTo(login));
            Assert.That(user.Password, Is.EqualTo(password));
        }

        [Test]
        public void User_Can_Add_New()
        {
            var user = new User { FirstName = "Test", LastName = "User", Login = "test_login", Password = "test" };

            IRepository<User> userRepository = new LinqRepository<User>();
            userRepository.Insert(user);

            User userFromDb;
            var found = userRepository.TryFindOne(u => u.Login == user.Login && u.Password == u.Password, out userFromDb);

            Assert.That(found, Is.True);
            Assert.That(userFromDb, Is.Not.Null);

            userRepository.Delete(user);
        }


        [Test]
        public void User_Can_Delete_New()
        {
            var user = new User { FirstName = "Test", LastName = "User", Login = "test_login", Password = "test" };

            IRepository<User> userRepository = new LinqRepository<User>();
            userRepository.Insert(user);

            var userToDelete = userRepository.FindOne(u => u.Login == user.Login);
            userRepository.Delete(userToDelete);

            User userFromDb;
            var found = userRepository.TryFindOne(u => u.Login == user.Login, out userFromDb);

            Assert.That(found, Is.False);
            Assert.That(userFromDb, Is.Null);
        }

        [Test]
        public void Can_Update_FirstName()
        {
            const string login = "marek";
            const string newFirstName = "Maras";

            IRepository<User> userRepository = new LinqRepository<User>();
            var user = userRepository.FindOne(u => u.Login == login);
            var firstName = user.FirstName;
            user.FirstName = newFirstName;
            userRepository.Update(user);

            var userFromDb = userRepository.FindOne(u => u.Login == login);
            Assert.That(userFromDb.FirstName, Is.EqualTo(newFirstName));
            userFromDb.FirstName = firstName;
            userRepository.Update(userFromDb);
        }

        [Test]
        public void User_Can_Find_By_FirstName()
        {
            const string firstName = "marek";

            IRepository<User> userRepository = new LinqRepository<User>();
            var user = userRepository.FindOne(u => u.FirstName == firstName);
            Assert.That(user, Is.Not.Null);
            Assert.That(user.FirstName.ToLower(), Is.EqualTo(firstName));
        }
        
        [Test]
        public void UserService_LoginUser_LogsUserIn()
        {
            IRepository<User> userRepository = new LinqRepository<User>();

            var userService = new UserService(userRepository);

            var isLoginSuccess = userService.LoginUser("marek", "marek");
            Assert.That(isLoginSuccess, Is.True, "User could not log in");
        }

        [Test]
        public void UserService_LoginUser_DoesNotLogsUserIn()
        {
            IRepository<User> userRepository = new LinqRepository<User>();
            var userService = new UserService(userRepository);

            var isLoginSuccess = userService.LoginUser("user", "password");
            Assert.That(isLoginSuccess, Is.False, "User could log in");
        }
    }
}