package com.marverenic.music.player.extensions.persistence;

import android.content.Context;
import android.net.Uri;

import com.marverenic.music.data.store.MediaStoreUtil;
import com.marverenic.music.data.store.ReadOnlyPreferenceStore;
import com.marverenic.music.model.Song;
import com.marverenic.music.player.MusicPlayer;
import com.marverenic.music.player.PlayerState;
import com.marverenic.music.player.extensions.MusicPlayerExtension;
import com.marverenic.music.player.persistence.PlaybackPersistenceManager;

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

public class PersistenceExtension extends MusicPlayerExtension {

    private PlaybackPersistenceManager mPlaybackPersistenceManager;
    private Context mContext;

    public PersistenceExtension(PlaybackPersistenceManager playbackPersistenceManager, Context context) {
        mPlaybackPersistenceManager = playbackPersistenceManager;
        mContext = context;
    }

    @Override
    public void onCreateMusicPlayer(MusicPlayer musicPlayer, ReadOnlyPreferenceStore preferences) {
        PlaybackPersistenceManager.State state = mPlaybackPersistenceManager.getStateBlocking();

        musicPlayer.restorePlayerState(new PlayerState.Builder()
                .setPlaying(false)
                .setQueue(MediaStoreUtil.buildSongListFromUris(state.getQueue(), mContext))
                .setShuffledQueue(MediaStoreUtil.buildSongListFromUris(state.getShuffledQueue(), mContext))
                .setQueuePosition(state.getQueuePosition())
                .setSeekPosition((int) state.getSeekPosition())
                .build());
    }

    @Override
    public void onQueueChanged(MusicPlayer musicPlayer) {
        mPlaybackPersistenceManager.setState(convertPersistableState(musicPlayer.getState()));
    }

    @Override
    public void onSongStarted(MusicPlayer musicPlayer) {
        updatePosition(musicPlayer);
    }

    @Override
    public void onSongPaused(MusicPlayer musicPlayer) {
        updatePosition(musicPlayer);
    }

    @Override
    public void onSeekPositionChanged(MusicPlayer musicPlayer) {
        updatePosition(musicPlayer);
    }

    private void updatePosition(MusicPlayer musicPlayer) {
        int seekPosition = musicPlayer.getCurrentPosition();
        int queueIndex = musicPlayer.getQueuePosition();
        mPlaybackPersistenceManager.setPosition(seekPosition, queueIndex);
    }

    private PlaybackPersistenceManager.State convertPersistableState(PlayerState state) {
        return new PlaybackPersistenceManager.State(
                state.getSeekPosition(),
                state.getQueuePosition(),
                convertSongsToUris(state.getQueue()),
                convertSongsToUris(state.getShuffledQueue())
        );
    }

    private List<Uri> convertSongsToUris(List<Song> songs) {
        if (songs == null) {
            return Collections.emptyList();
        }

        List<Uri> uris = new ArrayList<>(songs.size());
        for (Song song : songs) {
            uris.add(song.getLocation());
        }
        return uris;
    }

}

@@ -115,63 +115,8 @@
 i;%0A%0A
-import com.marverenic.music.data.store.MediaStoreUtil;%0A
 impo
@@ -537,16 +537,128 @@
 .List;%0A%0A
+import timber.log.Timber;%0A%0Aimport static com.marverenic.music.data.store.MediaStoreUtil.buildSongListFromUris;%0A%0A
 public c
@@ -1232,25 +1232,24 @@
 king();%0A
-%0A
         
 musicPla
@@ -1244,191 +1244,428 @@
     
-musicPlayer.restorePlayerState(new PlayerState.Builder()%0A                .setPlaying(false)%0A                .setQueue(MediaStoreUtil.buildSongListFromUris(state.getQueue(), mContext))
+List%3CSong%3E queue = buildSongListFromUris(state.getQueue(), mContext);%0A        List%3CSong%3E shuffledQueue = buildSongListFromUris(state.getShuffledQueue(), mContext);%0A%0A        int queuePosition;%0A        if (musicPlayer.isShuffled()) %7B%0A            queuePosition = Math.min(state.getQueuePosition(), shuffledQueue.size() - 1);%0A        %7D else %7B%0A            queuePosition = Math.min(state.getQueuePosition(), queue.size() - 1);
 %0A   
@@ -1665,32 +1665,35 @@
 1);%0A        
+%7D%0A%0A
         
 .setShuffled
@@ -1684,100 +1684,410 @@
     
-.setShuffledQueue(MediaStoreUtil.buildSongListFromUris(state.getShuffledQueue(), mContext))%0A
+long seekPosition;%0A        if (queuePosition != state.getQueuePosition()) %7B%0A            seekPosition = 0;%0A        %7D else %7B%0A            seekPosition = state.getSeekPosition();%0A        %7D%0A%0A        try %7B%0A            musicPlayer.restorePlayerState(new PlayerState.Builder()%0A                    .setPlaying(false)%0A                    .setQueue(queue)%0A                    .setShuffledQueue(shuffledQueue)%0A    
     
@@ -2116,26 +2116,17 @@
 osition(
-state.getQ
+q
 ueuePosi
@@ -2121,36 +2121,38 @@
 on(queuePosition
-()
 )%0A
+    
                 
@@ -2175,25 +2175,16 @@
 ((int) s
-tate.getS
 eekPosit
@@ -2186,19 +2186,48 @@
 Position
+)%0A                    .build
 ())
+;
 %0A       
@@ -2227,34 +2227,200 @@
         
-        .build());
+%7D catch (RuntimeException e) %7B%0A            Timber.e(e, %22Failed to restore queue. The player will be reset.%22);%0A            musicPlayer.setQueue(Collections.emptyList(), 0, 0);%0A        %7D
 %0A    %7D%0A%0A

Fix IndexOutOfBoundsException on service start