package music;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertSame;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

class PlaylistTest {
    private final Song a = new Song("A", "X", 200);
    private final Song b = new Song("B", "X", 45);
    private final Song c = new Song("C", "Y", 300);
    private Playlist list;

    // Se ejecuta antes de cada prueba: cada una empieza con una lista nueva.
    @BeforeEach
    void setUp() {
        list = new Playlist("Prueba");
    }

    @Test
    void emptyPlaylistHasZeroDuration() {
        assertEquals(0, list.size());
        assertEquals(0, list.totalSeconds());
    }

    @Test
    void totalSecondsAddsAllSongs() {
        list.add(a);
        list.add(b);
        list.add(c);

        assertEquals(545, list.totalSeconds());
    }

    @Test
    void longestOfSeveral() {
        list.add(a);
        list.add(c);
        list.add(b);

        assertSame(c, list.longest());
    }

    @Test
    void longestKeepsTheFirstOnATie() {
        Song alsoTwoHundred = new Song("D", "Z", 200);
        list.add(a);
        list.add(alsoTwoHundred);

        assertSame(a, list.longest());
    }

    @Test
    void longestOfEmptyPlaylistIsRejected() {
        assertThrows(IllegalArgumentException.class, () -> list.longest());
    }

    @Test
    void sameSongCanBeAddedTwice() {
        list.add(a);
        list.add(a);

        assertEquals(2, list.size());
        assertEquals(400, list.totalSeconds());
    }

    @Test
    void containsComparesByValue() {
        list.add(a);

        assertTrue(list.contains(new Song("A", "X", 200)));
        assertFalse(list.contains(new Song("A", "X", 201)));
    }

    @Test
    void removeShorterThanRemovesConsecutiveSongs() {
        list.add(a);
        list.add(b);
        list.add(new Song("E", "Y", 30));
        list.add(c);

        int removed = list.removeShorterThan(60);

        assertEquals(2, removed);
        assertEquals(2, list.size());
        assertSame(a, list.get(0));
        assertSame(c, list.get(1));
    }

    @Test
    void songsReturnsACopy() {
        list.add(a);

        list.songs().clear();

        assertEquals(1, list.size());
    }

    @Test
    void rejectsNull() {
        assertThrows(IllegalArgumentException.class, () -> list.add(null));
    }
}
