package com.example.backend;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.transaction.annotation.Transactional;

import com.example.backend.users.model.UserEntity;
import com.example.backend.users.service.UserService;
import com.example.backend.core.error.NotFoundException;

@SpringBootTest
class UserServiceTests {
    @Autowired
    private UserService userService;

    private UserEntity user;

    @BeforeEach
    void createData() {
        removeData();

        user = userService.create(new UserEntity("admin", "forum98761@gmail.com", "bth4323", "Александр", "Мельников"));
        userService.create(new UserEntity("Dude23", "ovalinartem25@gmail.com", "dsre32462", "Дмитрий", "Иванов"));
        userService.create(new UserEntity("TestUser", "user53262@gmail.com", "lawy7728", "Мария", "Котова"));
    }

    @AfterEach
    void removeData() {
        userService.getAll().forEach(item -> userService.delete(item.getId()));
    }

    @Test
    void getTest() {
        Assertions.assertThrows(NotFoundException.class, () -> userService.get(0L));
    }

    @Transactional
    @Test
    void createTest() {
        Assertions.assertEquals(3, userService.getAll().size());
        Assertions.assertEquals(user, userService.get(user.getId()));
    }

    @Test
    void createNotUniqueTest() {
        final UserEntity nonUniqueUser = new UserEntity("admin", "forum98761@gmail.com", "bth4323", "Александр",
                "Мельников");
        Assertions.assertThrows(IllegalArgumentException.class, () -> userService.create(nonUniqueUser));
    }

    @Test
    void createNullableTest() {
        final UserEntity nullableUser = new UserEntity(null, "forum98761@gmail.com", "bth4323", "Александр",
                "Мельников");
        Assertions.assertThrows(DataIntegrityViolationException.class, () -> userService.create(nullableUser));
    }

    @Transactional
    @Test
    void updateTest() {
        final String test = "TEST";
        final String oldLogin = user.getLogin();
        final UserEntity newEntity = userService.update(user.getId(),
                new UserEntity(test, "forum98761@gmail.com", "bth4323", "Александр",
                        "Мельников"));
        Assertions.assertEquals(3, userService.getAll().size());
        Assertions.assertEquals(newEntity, userService.get(user.getId()));
        Assertions.assertEquals(test, newEntity.getLogin());
        Assertions.assertNotEquals(oldLogin, newEntity.getLogin());
    }

    @Test
    void deleteTest() {
        userService.delete(user.getId());
        Assertions.assertEquals(2, userService.getAll().size());

        final UserEntity newEntity = userService
                .create(new UserEntity("admin", "forum98761@gmail.com", "bth4323", "Александр", "Мельников"));
        Assertions.assertEquals(3, userService.getAll().size());
        Assertions.assertNotEquals(user.getId(), newEntity.getId());
    }
}
