package net.drewgottlieb.soapy;

import android.util.Log;

import org.jdeferred.Deferred;

import org.jdeferred.DeferredManager;
import org.jdeferred.DoneCallback;
import org.jdeferred.FailCallback;
import org.jdeferred.Promise;
import org.jdeferred.impl.DefaultDeferredManager;
import org.jdeferred.impl.DeferredObject;

import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class Shower {
    private String rfid = null;
    private SoapyUser user = null;
    private List<SoapyTrack> tracks = null;
    private int nextTrackIndex = 0;

    private static final ExecutorService executorService = Executors.newCachedThreadPool();
    private static final DeferredManager dm = new DefaultDeferredManager(executorService);

    public Shower() {
    }

    public boolean isPlayable() {
        return (rfid != null);
    }

    public void setRfid(String rfid) {
        this.rfid = rfid;
    }

    public String getRfid() {
        return rfid;
    }

    public Promise<SoapyUser, Throwable, Void> getUser() {
        final Deferred<SoapyUser, Throwable, Void> deferred = new DeferredObject<>();

        if (user == null) {
            dm.when(SoapyWebAPI.getInstance().fetchUserAndTracks(rfid)).done(new DoneCallback<SoapyUser>() {
                public void onDone(SoapyUser user) {
                    Shower.this.user = user;
                    SoapyPlaylist playlist = user.getPlaylist();
                    String lastPlayedSong = playlist.getLastPlayedSong();
                    tracks = user.getTracks();
                    for (int i = 0; i < tracks.size(); i++) {
                        Log.i("Shower", "User has track: " + tracks.get(i));
                        SoapyTrack track = tracks.get(i);
                        if (track.isLocal()) {
                            Log.i("Shower", "Ignoring local track: " + tracks.get(i));
                            tracks.remove(i);
                            i--;
                        }
                        if (track.getURI().equals(lastPlayedSong) && i < tracks.size() - 1) {
                            nextTrackIndex = i + 1;
                        }
                    }
                    nextTrackIndex %= tracks.size();
                    for (SoapyTrack track : tracks) {
                        Log.i("Shower", "User has track: " + track);
                    }
                    deferred.resolve(user);
                }
            }).fail(new FailCallback<SoapyWebAPI.SoapyWebError>() {
                public void onFail(SoapyWebAPI.SoapyWebError e) {
                    deferred.reject(e);
                }
            });
        } else {
            deferred.resolve(user);
        }

        return deferred.promise();
    }

    public Promise<String, Throwable, Void> getAccessToken() {
        final Deferred<String, Throwable, Void> deferred = new DeferredObject<>();

        dm.when(getUser()).done(new DoneCallback<SoapyUser>() {
            @Override
            public void onDone(SoapyUser user) {
                deferred.resolve(user.getSpotifyAccessToken());
            }
        }).fail(new FailCallback<Throwable>() {
            @Override
            public void onFail(Throwable result) {
                deferred.reject(result);
            }
        });

        return deferred.promise();
    }

    public SoapyTrack getNextTrack() {
        if (tracks.isEmpty()) {
            return null;
        }

        int i = 0;
        SoapyTrack ret = null;

        do {
            // If we're back where we started, no tracks are playable.
            if (i++ >= tracks.size()) {
                return null;
            }

            ret = tracks.get(nextTrackIndex);

            nextTrackIndex++;
            nextTrackIndex %= tracks.size();
        } while (ret == null || ret.isLocal());

        return ret;
    }
}

@@ -1641,85 +1641,8 @@
 ) %7B%0A
-                        Log.i(%22Shower%22, %22User has track: %22 + tracks.get(i));%0A
     
@@ -1818,24 +1818,16 @@
  + track
-s.get(i)
 );%0A     
@@ -1900,16 +1900,54 @@
    i--;%0A
+                            continue;%0A
         
@@ -2033,33 +2033,8 @@
 ong)
- && i %3C tracks.size() - 1
 ) %7B%0A
@@ -2135,183 +2135,178 @@
     
-%7D%0A                    nextTrackIndex %25= tracks.size();%0A                    for (SoapyTrack track : tracks) %7B%0A                        Log.i(%22Shower%22, %22User has track: %22 + track
+    Log.i(%22Shower%22, %22User has track: %22 + track);%0A                    %7D%0A                    if (tracks.size() %3E 0) %7B%0A                        nextTrackIndex %25= tracks.size(
 );%0A 
@@ -3412,230 +3412,18 @@
     
-int i = 0;%0A        SoapyTrack ret = null;%0A%0A        do %7B%0A            // If we're back where we started, no tracks are playable.%0A            if (i++ %3E= tracks.size()) %7B%0A                return null;%0A            %7D%0A%0A           
+SoapyTrack
  ret
@@ -3454,36 +3454,32 @@
 ndex);%0A%0A        
-    
 nextTrackIndex++
@@ -3480,36 +3480,32 @@
 ndex++;%0A        
-  
-  
 nextTrackIndex %25
@@ -3524,56 +3524,8 @@
 e();
-%0A        %7D while (ret == null %7C%7C ret.isLocal());
 %0A%0A  

Simplify next-song logic. And don't divide by zero.