package cz.muni.fi.pa165.soccermanager.repository;

import cz.muni.fi.pa165.soccermanager.PersistenceApplication;
import cz.muni.fi.pa165.soccermanager.entity.Player;
import cz.muni.fi.pa165.soccermanager.enums.Nation;
import cz.muni.fi.pa165.soccermanager.enums.PlayerState;
import cz.muni.fi.pa165.soccermanager.enums.Position;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.TestExecutionListeners;
import org.springframework.test.context.testng.AbstractTestNGSpringContextTests;
import org.springframework.test.context.transaction.TransactionalTestExecutionListener;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.transaction.Transactional;
import java.time.LocalDate;

import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.testng.AssertJUnit.assertTrue;

/**
 * Player Dao test
 *
 * @author Petr Balazy (uco: 527362)
 */
@ContextConfiguration(classes = PersistenceApplication.class)
@TestExecutionListeners(TransactionalTestExecutionListener.class)
@Transactional
public class PlayerRepositoryTest extends AbstractTestNGSpringContextTests {

    @PersistenceContext
    protected EntityManager em;

    Player player1;
    Player player2;

    @Autowired
    private PlayerRepository playerRepository;

    @BeforeMethod
    public void setUp() {
        player1 = new Player();
        player1.setDressNumber(1);
        player1.setName("Pedro Sancez");
        player1.setBirthDate(LocalDate.of(1998, 12, 12));
        player1.setTeam(null);
        player1.setState(PlayerState.ACTIVE);
        player1.setWeight(92);
        player1.setPosition(Position.DEFENDER);
        player1.setHeight(181.2);
        player1.setNation(Nation.SLOVAKIA);

        player2 = new Player();
        player2.setDressNumber(1);
        player2.setName("Pedro Sancez");
        player2.setBirthDate(LocalDate.of(1998, 12, 12));
        player2.setTeam(null);
        player2.setState(PlayerState.ACTIVE);
        player2.setWeight(82);
        player2.setPosition(Position.DEFENDER);
        player2.setHeight(189.2);
        player2.setNation(Nation.SLOVAKIA);

        em.persist(player1);
        em.persist(player2);
    }

    @Test
    public void createTest() {
        final var player = new Player();
        player.setDressNumber(1);
        player.setName("Pablo Janos");
        player.setBirthDate(LocalDate.of(1998, 12, 12));
        player.setTeam(null);
        player.setState(PlayerState.INACTIVE);
        player.setWeight(100);
        player.setPosition(Position.DEFENDER);
        player.setHeight(2.2);
        player.setNation(Nation.SLOVAKIA);

        playerRepository.save(player);

        final var createdPlayer = em.find(Player.class, player.getId());
        assertThat(createdPlayer).isEqualTo(player);
    }

    @Test
    public void findByIdTest() {
        final var p = playerRepository.findById(player1.getId());
        assertTrue(p.isPresent());
        assertThat(p.get()).isEqualTo(player1);

        final var p2 = playerRepository.findById(100L);
        assertFalse(p2.isPresent());
    }

    @Test
    public void findAllTest() {
        final var players = playerRepository.findAll();
        assertThat(players).hasSize(2).containsExactly(player1, player2);
    }

    @Test
    public void removeTest() {
        final var players = playerRepository.findAll();
        assertThat(players).hasSize(2).containsExactly(player1, player2);

        playerRepository.delete(player2);

        final var players2 = playerRepository.findAll();
        assertThat(players2).hasSize(1).containsExactly(player1);
    }
}