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

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.NoSuchFileException;
import java.nio.file.Path;
import java.util.List;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;

class CsvSongRepositoryTest {
    @TempDir
    Path dir;

    @Test
    void roundTripKeepsEverySong() throws IOException {
        List<Song> songs = List.of(
                new Song("Contigo Perú", "Arturo \"Zambo\" Cavero", 254),
                new Song("Lima, de noche", "Los Ensayos", 205),
                new Song("Ñaña", "Piña y Café", 99));
        SongRepository repo = new CsvSongRepository(dir.resolve("s.csv"));
        repo.save(songs);
        assertEquals(songs, repo.load());
    }

    @Test
    void emptyListRoundTrip() throws IOException {
        SongRepository repo = new CsvSongRepository(dir.resolve("vacio.csv"));
        repo.save(List.of());
        assertEquals(List.of(), repo.load());
    }

    @Test
    void missingFileIsNoSuchFile() {
        SongRepository repo = new CsvSongRepository(dir.resolve("no-existe.csv"));
        assertThrows(NoSuchFileException.class, repo::load);
    }

    @Test
    void badNumberReportsTheLine() throws IOException {
        Path file = dir.resolve("malo.csv");
        Files.writeString(file, "title,artist,seconds\nA,B,100\nC,D,tres\n");
        MalformedCsvException e = assertThrows(MalformedCsvException.class,
                () -> new CsvSongRepository(file).load());
        assertEquals(3, e.line());
    }

    @Test
    void wrongFieldCountReportsTheLine() throws IOException {
        Path file = dir.resolve("malo.csv");
        Files.writeString(file, "title,artist,seconds\nLima, de noche,Los Ensayos,205\n");
        MalformedCsvException e = assertThrows(MalformedCsvException.class,
                () -> new CsvSongRepository(file).load());
        assertEquals("línea 2: se esperaban 3 campos y hay 4", e.getMessage());
    }

    @Test
    void invalidSongReportsTheLine() throws IOException {
        Path file = dir.resolve("malo.csv");
        Files.writeString(file, "title,artist,seconds\nA,B,-1\n");
        MalformedCsvException e = assertThrows(MalformedCsvException.class,
                () -> new CsvSongRepository(file).load());
        assertEquals("línea 2: duración inválida: -1", e.getMessage());
    }

    @Test
    void missingHeaderIsRejected() throws IOException {
        Path file = dir.resolve("sin-encabezado.csv");
        Files.writeString(file, "A,B,100\n");
        assertThrows(MalformedCsvException.class, () -> new CsvSongRepository(file).load());
    }
}
