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

import java.io.IOException;
import java.io.InvalidClassException;
import java.io.ObjectInputFilter;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;

class SerializationTest {
    @TempDir
    Path dir;

    private Path write(Object obj) throws IOException {
        Path file = dir.resolve("obj.bin");
        try (ObjectOutputStream out = new ObjectOutputStream(Files.newOutputStream(file))) {
            out.writeObject(obj);
        }
        return file;
    }

    @Test
    void playlistRoundTripLosesOnlyTheTransientField() throws Exception {
        Playlist list = new Playlist("p");
        list.add(new Song("A", "B", 100));
        Path file = write(list);
        try (ObjectInputStream in = new ObjectInputStream(Files.newInputStream(file))) {
            Playlist back = (Playlist) in.readObject();
            assertEquals(list.songs(), back.songs());
            assertEquals("p", back.name());
            assertEquals(0, back.totalSeconds());
        }
    }

    @Test
    void filterRejectsClassesThatAreNotAllowed() throws Exception {
        Path file = write(new PlainSong("A", 100));
        try (ObjectInputStream in = new ObjectInputStream(Files.newInputStream(file))) {
            in.setObjectInputFilter(ObjectInputFilter.Config.createFilter("Song;Playlist;java.util.ArrayList;!*"));
            assertThrows(InvalidClassException.class, in::readObject);
        }
    }

    @Test
    void tamperedRecordIsRejected() throws Exception {
        String result = SerializationDemo.tamper(new Song("A", "B", 254));
        assertEquals("java.io.InvalidObjectException: duración inválida: -5", result);
    }
}
