import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

import java.util.ArrayList;

import org.junit.jupiter.api.Test;

public class ThreeTest
{
    @Test
    public void testPartA()
    {
        String[] players = {"Alex", "Ben", "Cara"};
        Round r = new Round(players);

        assertEquals(3, r.competitorList.size());

        assertEquals("Alex", r.competitorList.get(0).name);
        assertEquals(1, r.competitorList.get(0).rank);

        assertEquals("Ben", r.competitorList.get(1).name);
        assertEquals(2, r.competitorList.get(1).rank);

        assertEquals("Cara", r.competitorList.get(2).name);
        assertEquals(3, r.competitorList.get(2).rank);
    }

    @Test
    public void testPartBAgainstExample1()
    {
        String[] players = {"Alex", "Ben", "Cara"};
        Round r = new Round(players);

        ArrayList<Match> expected = new ArrayList<Match>();
        expected.add(new Match(
                r.competitorList.get(1), r.competitorList.get(2)));

        assertTrue(hasSameMatches(expected, r.buildMatches()));
    }

    @Test
    public void testPartBAgainstExample2()
    {
        String[] players = {"Rei", "Sam", "Vi", "Tim"};
        Round r = new Round(players);

        ArrayList<Match> expected = new ArrayList<Match>();
        expected.add(new Match(
                r.competitorList.get(0), r.competitorList.get(3)));
        expected.add(new Match(
                r.competitorList.get(1), r.competitorList.get(2)));

        assertTrue(hasSameMatches(expected, r.buildMatches()));
    }

    @Test
    public void testPartBAgainstAgainstEvenExample()
    {
        String[] players = {"a", "b", "c", "d", "e", "f", "g", "h", "i", "j"};
        Round r = new Round(players);

        ArrayList<Match> expected = new ArrayList<Match>();
        expected.add(new Match(
                r.competitorList.get(0), r.competitorList.get(9)));
        expected.add(new Match(
                r.competitorList.get(1), r.competitorList.get(8)));
        expected.add(new Match(
                r.competitorList.get(2), r.competitorList.get(7)));
        expected.add(new Match(
                r.competitorList.get(3), r.competitorList.get(6)));
        expected.add(new Match(
                r.competitorList.get(4), r.competitorList.get(5)));

        assertTrue(hasSameMatches(expected, r.buildMatches()));
    }

    @Test
    public void testPartBAgainstAgainstOddExample()
    {
        String[] players = {"a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k"};
        Round r = new Round(players);

        ArrayList<Match> expected = new ArrayList<Match>();
        expected.add(new Match(
                r.competitorList.get(1), r.competitorList.get(10)));
        expected.add(new Match(
                r.competitorList.get(2), r.competitorList.get(9)));
        expected.add(new Match(
                r.competitorList.get(3), r.competitorList.get(8)));
        expected.add(new Match(
                r.competitorList.get(4), r.competitorList.get(7)));
        expected.add(new Match(
                r.competitorList.get(5), r.competitorList.get(6)));

        assertTrue(hasSameMatches(expected, r.buildMatches()));
    }

    private static boolean hasSameMatches(
            ArrayList<Match> expected,
            ArrayList<Match> actual)
    {
        if(actual.size() != expected.size())
            return false;

        for(Match m : expected)
            if( ! actual.contains(m) )
                return false;

        return true;
    }
}
