diff --git a/jukebox/src/main/java/at/lockstep/jukebox/sync/SyncCoordinator.java b/jukebox/src/main/java/at/lockstep/jukebox/sync/SyncCoordinator.java index ab03758..61f0669 100644 --- a/jukebox/src/main/java/at/lockstep/jukebox/sync/SyncCoordinator.java +++ b/jukebox/src/main/java/at/lockstep/jukebox/sync/SyncCoordinator.java @@ -42,6 +42,13 @@ import java.util.Set; */ public final class SyncCoordinator { + private static final String TAG = "SyncCoordinator"; + + /** Cap per-item title/artist lines so huge playlists do not overwhelm logcat. */ + private static final int SYNC_DETAIL_TITLE_LOG_LIMIT = 50; + + private static final int SYNC_DETAIL_NULL_TRACK_LOG_LIMIT = 15; + private final PlaylistDao dao; private final LockstepPlaylistClient remote; @@ -127,8 +134,78 @@ public final class SyncCoordinator { * that playlist only. */ public void syncPlaylistDetail(@NonNull String playlistId) throws IOException, LockstepApiException { + Log.d(TAG, "syncPlaylistDetail start requestedId=" + playlistId); FullPlaylistDto detail = remote.fetchPlaylistDetail(playlistId); + String resolvedId = detail.id; + Log.d( + TAG, + "syncPlaylistDetail fetched resolvedId=" + + resolvedId + + " requestedMatch=" + + Objects.equals(playlistId, resolvedId) + + " name=" + + detail.name + + " snapshotId=" + + detail.snapshotId + ); + if (detail.items == null) { + Log.w(TAG, "syncPlaylistDetail: detail.items is null (no playlist items page in response)"); + } else { + List entries = detail.items.itemsOrEmpty(); + int withItem = 0; + int withoutItem = 0; + int titlesLogged = 0; + int nullItemLogged = 0; + for (int i = 0; i < entries.size(); i++) { + PlaylistItemDto w = entries.get(i); + if (w.item != null) { + withItem++; + if (titlesLogged < SYNC_DETAIL_TITLE_LOG_LIMIT) { + TrackDto t = w.item; + Log.d( + TAG, + "syncPlaylistDetail items[" + i + "] id=" + t.id + + " title=" + t.name + + " artist=" + + PlaylistMappers.artistDisplayName(t.artistsOrEmpty())); + titlesLogged++; + } + } else { + withoutItem++; + if (nullItemLogged < SYNC_DETAIL_NULL_TRACK_LOG_LIMIT) { + Log.d( + TAG, + "syncPlaylistDetail items[" + i + "] (null item; e.g. removed or unsupported type)"); + nullItemLogged++; + } + } + } + Integer total = detail.items.total; + Log.d( + TAG, + "syncPlaylistDetail items page: entryCount=" + + entries.size() + + " entriesWithItem=" + + withItem + + " entriesWithNullItem=" + + withoutItem + + " paging.total=" + + total + + " titleArtistLinesLogged=" + + titlesLogged + + (withItem > titlesLogged + ? " (cap=" + SYNC_DETAIL_TITLE_LOG_LIMIT + ", see SyncCoordinator constants)" + : "") + ); + } PlaylistMappers.PlaylistStorageRows rows = PlaylistMappers.toPlaylistStorageRows(detail); + Log.d( + TAG, + "syncPlaylistDetail after map: dedupedTrackEntities=" + + rows.trackEntities.size() + + " playlistTrackRows=" + + rows.playlistTracks.size() + ); persistFullPlaylist(detail, rows); } @@ -142,5 +219,6 @@ public final class SyncCoordinator { rows.trackEntities, rows.playlistTracks ); + Log.d(TAG, "syncPlaylistDetail persisted replacePlaylistContent for id=" + detail.id); } }