import java.util.ArrayList;
import java.util.List;

/** Operaciones nuevas sobre el árbol, escritas con un switch sobre el tipo sealed. */
public final class Playables {
    private Playables() {
    }

    public static int countSongs(Playable p) {
        return switch (p) {
            case Song s -> 1;
            case Playlist list -> {
                int n = 0;
                for (Playable entry : list.entries()) {
                    n += countSongs(entry);
                }
                yield n;
            }
        };
    }

    /** Todas las canciones del árbol, en orden, sin las listas. */
    public static List<Song> songs(Playable p) {
        List<Song> result = new ArrayList<>();
        collect(p, result);
        return result;
    }

    private static void collect(Playable p, List<Song> into) {
        switch (p) {
            case Song s -> into.add(s);
            case Playlist list -> list.entries().forEach(entry -> collect(entry, into));
        }
    }

    /** El árbol con sangría, una línea por elemento. */
    public static String tree(Playable p) {
        StringBuilder sb = new StringBuilder();
        tree(p, "", sb);
        return sb.toString();
    }

    private static void tree(Playable p, String indent, StringBuilder sb) {
        sb.append(indent).append(p.title()).append("  ").append(p.length()).append('\n');
        if (p instanceof Playlist list) {
            for (Playable entry : list.entries()) {
                tree(entry, indent + "  ", sb);
            }
        }
    }
}
