package de.thpeetz.kontor.tysc.services;

import static org.junit.jupiter.api.Assertions.*;

import java.util.List;

import de.thpeetz.kontor.tysc.data.FieldPosition;
import org.junit.jupiter.api.MethodOrderer.OrderAnnotation;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestMethodOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import de.thpeetz.kontor.tysc.TestConstants;
import de.thpeetz.kontor.tysc.data.Player;
import de.thpeetz.kontor.tysc.data.Rooster;
import de.thpeetz.kontor.tysc.data.Sport;
import de.thpeetz.kontor.tysc.data.Team;

@SpringBootTest
@TestMethodOrder(OrderAnnotation.class)
class SportServiceTest {

    @Autowired
    private SportService sportService;


    @Test
    @Order(1)
    void testFindAllSports() {
        List<Sport> sports = sportService.findAllSports(null);
        assertEquals(TestConstants.SPORT_COUNT, sports.size());
        assertEquals(3, sportService.findAllSports("ball").size());
    }

    @Test
    @Order(2)
    void testSaveSport() {
        Sport sport = new Sport();
        sport.setName(TestConstants.SPORT_NAME);
        sport = sportService.saveSport(sport);
        assertNotNull(sport);
        assertEquals(TestConstants.SPORT_COUNT+1, sportService.findAllSports(null).size());
    }

    @Test
    @Order(3)
    void testDeleteSport() {
        List<Sport> sports = sportService.findAllSports(TestConstants.SPORT_NAME);
        assertEquals(1, sports.size());
        Sport sport = sports.get(0);
        sportService.deleteSport(sport);
        assertEquals(TestConstants.SPORT_COUNT, sportService.findAllSports(null).size());
    }

    @Test
    @Order(4)
    void testFindAllPlayers() {
        assertEquals(TestConstants.PLAYER_COUNT, sportService.findAllPlayers(null).size());
        assertEquals(TestConstants.PLAYER_CHRIS_COUNT, sportService.findAllPlayers(TestConstants.PLAYER_CHRIS_NAME).size());
    }

    @Test
    @Order(5)
    void testSavePlayer() {
        Player player = new Player();
        player.setFirstName(TestConstants.PLAYER_FIRSTNAME);
        player.setLastName(TestConstants.PLAYER_LASTNAME);
        player = sportService.savePlayer(player);
        assertNotNull(player);
    }

    @Test
    @Order(6)
    void testDeletePlayer() {
        List<Player> players = sportService.findAllPlayers(TestConstants.PLAYER_LASTNAME);
        assertEquals(1, players.size());
        Player player = players.get(0);
        sportService.deletePlayer(player);
        assertEquals(TestConstants.PLAYER_COUNT, sportService.findAllPlayers(null).size());
    }


    @Test
    @Order(7)
    void testFindAllPositions() {
        assertEquals(TestConstants.POSITION_COUNT, sportService.findAllPositions(null).size());
        assertEquals(TestConstants.POSITION_CENTER_COUNT, sportService.findAllPositions(TestConstants.POSITION_CENTER).size());
    }

    @Test
    @Order(8)
    void testFindAllPositionsForSport() {
        List<Sport> sports = sportService.findAllSports(TestConstants.FOOTBALL_NAME);
        assertEquals(1, sports.size());
        Sport football = sports.get(0);
        assertEquals(TestConstants.FOOTBALL_POSITION_COUNT, sportService.findAllPositionsForSport(football).size());
    }

    @Test
    @Order(9)
    void testSavePosition() {
        List<Sport> sports = sportService.findAllSports(TestConstants.FOOTBALL_NAME);
        Sport football = sports.get(0);
        FieldPosition position = new FieldPosition();
        position.setSport(football);
        position.setName(TestConstants.POSITION_NAME);
        position.setShortName(TestConstants.POSITION_SHORTNAME);
        sportService.savePosition(position);
        assertEquals(TestConstants.POSITION_COUNT+1, sportService.findAllPositions(null).size());
    }

    @Test
    @Order(10)
    void testDeletePosition() {
        List<FieldPosition> positions = sportService.findAllPositions(TestConstants.POSITION_NAME);
        assertEquals(1, positions.size());
        FieldPosition position = positions.get(0);
        sportService.deletePosition(position);
        assertEquals(TestConstants.POSITION_COUNT, sportService.findAllPositions(null).size());
    }

    @Test
    @Order(11)
    void testFindAllTeams() {
        assertEquals(TestConstants.TEAM_COUNT, sportService.findAllTeams(null).size());
        assertEquals(1, sportService.findAllTeams("sharks").size());
    }

    @Test
    @Order(12)
    void testSaveTeam() {
        List<Sport> sports = sportService.findAllSports(TestConstants.FOOTBALL_NAME);
        Sport football = sports.get(0);
        Team team = new Team();
        team.setSport(football);
        team.setName(TestConstants.TEAM_NAME);
        team.setShortName(TestConstants.TEAM_SHORTNAME);
        sportService.saveTeam(team);
        assertEquals(TestConstants.TEAM_COUNT+1, sportService.findAllTeams(null).size());
    }

    @Test
    @Order(13)
    void testDeleteTeam() {
        List<Team> teams = sportService.findAllTeams(TestConstants.TEAM_NAME);
        assertEquals(1, teams.size());
        Team team = teams.get(0);
        sportService.deleteTeam(team);
        assertEquals(TestConstants.TEAM_COUNT, sportService.findAllTeams(null).size());
    }

    @Test
    @Order(14)
    void testFindAllRoosters() {
        assertEquals(TestConstants.ROOSTER_COUNT, sportService.findAllRoosters().size());
    }

    @Test
    @Order(15)
    void testFindRoosterByFields() {
        List<Rooster> roosters = sportService.findAllRoosters();
        Rooster existingRooster = roosters.get(4);
        Team team = existingRooster.getTeam();
        Player player = existingRooster.getPlayer();
        FieldPosition position = existingRooster.getPosition();
        int year = existingRooster.getYear();
        Rooster rooster = sportService.findRoosterByFields(team, player, position, year);
        assertNotNull(rooster);
        assertEquals(existingRooster.getId(), rooster.getId());
    }

    @Test
    @Order(16)
    void testSaveRooster() {
        Rooster rooster = new Rooster();
        Player player = sportService.findAllPlayers(TestConstants.PLAYER_CHRIS_NAME).get(0);
        rooster.setPlayer(player);
        Team team = sportService.findAllTeams(TestConstants.DOLPHINS_NAME).get(0);
        rooster.setTeam(team);
        FieldPosition position = sportService.findAllPositions(TestConstants.QUARTERBACK_NAME).get(0);
        rooster.setPosition(position);
        rooster.setYear(TestConstants.ROOSTER_YEAR);
        sportService.saveRooster(rooster);
        assertEquals(TestConstants.ROOSTER_COUNT+1, sportService.findAllRoosters().size());
    }

    @Test
    @Order(17)
    void testDeleteRooster() {
        Team team = sportService.findAllTeams(TestConstants.DOLPHINS_NAME).get(0);
        Player player = sportService.findAllPlayers(TestConstants.PLAYER_CHRIS_NAME).get(0);
        FieldPosition position = sportService.findAllPositions(TestConstants.QUARTERBACK_NAME).get(0);
        Rooster rooster = sportService.findRoosterByFields(team, player, position, TestConstants.ROOSTER_YEAR);
        assertNotNull(rooster);
        sportService.deleteRooster(rooster);
        assertEquals(TestConstants.ROOSTER_COUNT, sportService.findAllRoosters().size());
    }
}
