/*
 * Copyright (C) 2013 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.example.android.mediarouter.player;

import android.app.PendingIntent;
import android.net.Uri;
import android.support.v7.media.MediaItemStatus;
import android.support.v7.media.MediaSessionStatus;
import android.util.Log;

import com.example.android.mediarouter.player.Player.Callback;

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

/**
 * SessionManager manages a media session as a queue. It supports common
 * queuing behaviors such as enqueue/remove of media items, pause/resume/stop,
 * etc.
 *
 * Actual playback of a single media item is abstracted into a Player interface,
 * and is handled outside this class.
 */
public class SessionManager implements Callback {
    private static final String TAG = "SessionManager";
    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);

    private String mName;
    private int mSessionId;
    private int mItemId;
    private boolean mPaused;
    private boolean mSessionValid;
    private Player mPlayer;
    private Callback mCallback;
    private List<PlaylistItem> mPlaylist = new ArrayList<PlaylistItem>();

    public SessionManager(String name) {
        mName = name;
    }

    public boolean hasSession() {
        return mSessionValid;
    }

    public String getSessionId() {
        return mSessionValid ? Integer.toString(mSessionId) : null;
    }

    public PlaylistItem getCurrentItem() {
        return mPlaylist.isEmpty() ? null : mPlaylist.get(0);
    }

    // Get the cached statistic info from the player (will not update it)
    public String getStatistics() {
        checkPlayer();
        return mPlayer.getStatistics();
    }

    // Returns the cached playlist (note this is not responsible for updating it)
    public List<PlaylistItem> getPlaylist() {
        return mPlaylist;
    }

    // Updates the playlist asynchronously, calls onPlaylistReady() when finished.
    public void updateStatus() {
        if (DEBUG) {
            log("updateStatus");
        }
        checkPlayer();
        // update the statistics first, so that the stats string is valid when
        // onPlaylistReady() gets called in the end
        mPlayer.updateStatistics();

        if (mPlaylist.isEmpty()) {
            // If queue is empty, don't forget to call onPlaylistReady()!
            onPlaylistReady();
        } else if (mPlayer.isQueuingSupported()) {
            // If player supports queuing, get status of each item. Player is
            // responsible to call onPlaylistReady() after last getStatus().
            // (update=1 requires player to callback onPlaylistReady())
            for (int i = 0; i < mPlaylist.size(); i++) {
                PlaylistItem item = mPlaylist.get(i);
                mPlayer.getStatus(item, (i == mPlaylist.size() - 1) /* update */);
            }
        } else {
            // Otherwise, only need to get status for current item. Player is
            // responsible to call onPlaylistReady() when finished.
            mPlayer.getStatus(getCurrentItem(), true /* update */);
        }
    }

    public PlaylistItem add(Uri uri, String mime) {
        return add(uri, mime, null);
    }

    public PlaylistItem add(Uri uri, String mime, PendingIntent receiver) {
        if (DEBUG) {
            log("add: uri=" + uri + ", receiver=" + receiver);
        }
        // create new session if needed
        startSession();
        checkPlayerAndSession();

        // append new item with initial status PLAYBACK_STATE_PENDING
        PlaylistItem item = new PlaylistItem(
                Integer.toString(mSessionId), Integer.toString(mItemId), uri, mime, receiver);
        mPlaylist.add(item);
        mItemId++;

        // if player supports queuing, enqueue the item now
        if (mPlayer.isQueuingSupported()) {
            mPlayer.enqueue(item);
        }
        updatePlaybackState();
        return item;
    }

    public PlaylistItem remove(String iid) {
        if (DEBUG) {
            log("remove: iid=" + iid);
        }
        checkPlayerAndSession();
        return removeItem(iid, MediaItemStatus.PLAYBACK_STATE_CANCELED);
    }

    public PlaylistItem seek(String iid, long pos) {
        if (DEBUG) {
            log("seek: iid=" + iid +", pos=" + pos);
        }
        checkPlayerAndSession();
        // seeking on pending items are not yet supported
        checkItemCurrent(iid);

        PlaylistItem item = getCurrentItem();
        if (pos != item.getPosition()) {
            item.setPosition(pos);
            if (item.getState() == MediaItemStatus.PLAYBACK_STATE_PLAYING
                    || item.getState() == MediaItemStatus.PLAYBACK_STATE_PAUSED) {
                mPlayer.seek(item);
            }
        }
        return item;
    }

    public PlaylistItem getStatus(String iid) {
        checkPlayerAndSession();

        // This should only be called for local player. Remote player is
        // asynchronous, need to use updateStatus() instead.
        if (mPlayer.isRemotePlayback()) {
            throw new IllegalStateException(
                    "getStatus should not be called on remote player!");
        }

        for (PlaylistItem item : mPlaylist) {
            if (item.getItemId().equals(iid)) {
                if (item == getCurrentItem()) {
                    mPlayer.getStatus(item, false);
                }
                return item;
            }
        }
        return null;
    }

    public void pause() {
        if (DEBUG) {
            log("pause");
        }
        mPaused = true;
        updatePlaybackState();
    }

    public void resume() {
        if (DEBUG) {
            log("resume");
        }
        mPaused = false;
        updatePlaybackState();
    }

    public void stop() {
        if (DEBUG) {
            log("stop");
        }
        mPlayer.stop();
        mPlaylist.clear();
        mPaused = false;
        updateStatus();
    }

    public String startSession() {
        if (!mSessionValid) {
            mSessionId++;
            mItemId = 0;
            mPaused = false;
            mSessionValid = true;
            return Integer.toString(mSessionId);
        }
        return null;
    }

    public boolean endSession() {
        if (mSessionValid) {
            mSessionValid = false;
            return true;
        }
        return false;
    }

    public MediaSessionStatus getSessionStatus(String sid) {
        int sessionState = (sid != null && sid.equals(mSessionId)) ?
                MediaSessionStatus.SESSION_STATE_ACTIVE :
                    MediaSessionStatus.SESSION_STATE_INVALIDATED;

        return new MediaSessionStatus.Builder(sessionState)
                .setQueuePaused(mPaused)
                .build();
    }

    // Suspend the playback manager. Put the current item back into PENDING
    // state, and remember the current playback position. Called when switching
    // to a different player (route).
    public void suspend(long pos) {
        for (PlaylistItem item : mPlaylist) {
            item.setRemoteItemId(null);
            item.setDuration(0);
        }
        PlaylistItem item = getCurrentItem();
        if (DEBUG) {
            log("suspend: item=" + item + ", pos=" + pos);
        }
        if (item != null) {
            if (item.getState() == MediaItemStatus.PLAYBACK_STATE_PLAYING
                    || item.getState() == MediaItemStatus.PLAYBACK_STATE_PAUSED) {
                item.setState(MediaItemStatus.PLAYBACK_STATE_PENDING);
                item.setPosition(pos);
            }
        }
    }

    // Unsuspend the playback manager. Restart playback on new player (route).
    // This will resume playback of current item. Furthermore, if the new player
    // supports queuing, playlist will be re-established on the remote player.
    public void unsuspend() {
        if (DEBUG) {
            log("unsuspend");
        }
        if (mPlayer.isQueuingSupported()) {
            for (PlaylistItem item : mPlaylist) {
                mPlayer.enqueue(item);
            }
        }
        updatePlaybackState();
    }

    // Player.Callback
    @Override
    public void onError() {
        finishItem(true);
    }

    @Override
    public void onCompletion() {
        finishItem(false);
    }

    @Override
    public void onPlaylistChanged() {
        // Playlist has changed, update the cached playlist
        updateStatus();
    }

    @Override
    public void onPlaylistReady() {
        // Notify activity to update Ui
        if (mCallback != null) {
            mCallback.onStatusChanged();
        }
    }

    private void log(String message) {
        Log.d(TAG, mName + ": " + message);
    }

    private void checkPlayer() {
        if (mPlayer == null) {
            throw new IllegalStateException("Player not set!");
        }
    }

    private void checkSession() {
        if (!mSessionValid) {
            throw new IllegalStateException("Session not set!");
        }
    }

    private void checkPlayerAndSession() {
        checkPlayer();
        checkSession();
    }

    private void checkItemCurrent(String iid) {
        PlaylistItem item = getCurrentItem();
        if (item == null || !item.getItemId().equals(iid)) {
            throw new IllegalArgumentException("Item is not current!");
        }
    }

    private void updatePlaybackState() {
        PlaylistItem item = getCurrentItem();
        if (item != null) {
            if (item.getState() == MediaItemStatus.PLAYBACK_STATE_PENDING) {
                item.setState(mPaused ? MediaItemStatus.PLAYBACK_STATE_PAUSED
                        : MediaItemStatus.PLAYBACK_STATE_PLAYING);
                if (!mPlayer.isQueuingSupported()) {
                    mPlayer.play(item);
                }
            } else if (mPaused && item.getState() == MediaItemStatus.PLAYBACK_STATE_PLAYING) {
                mPlayer.pause();
                item.setState(MediaItemStatus.PLAYBACK_STATE_PAUSED);
            } else if (!mPaused && item.getState() == MediaItemStatus.PLAYBACK_STATE_PAUSED) {
                mPlayer.resume();
                item.setState(MediaItemStatus.PLAYBACK_STATE_PLAYING);
            }
            // notify client that item playback status has changed
            if (mCallback != null) {
                mCallback.onItemChanged(item);
            }
        }
        updateStatus();
    }

    private PlaylistItem removeItem(String iid, int state) {
        checkPlayerAndSession();
        List<PlaylistItem> queue =
                new ArrayList<PlaylistItem>(mPlaylist.size());
        PlaylistItem found = null;
        for (PlaylistItem item : mPlaylist) {
            if (iid.equals(item.getItemId())) {
                if (mPlayer.isQueuingSupported()) {
                    mPlayer.remove(item.getRemoteItemId());
                } else if (item.getState() == MediaItemStatus.PLAYBACK_STATE_PLAYING
                        || item.getState() == MediaItemStatus.PLAYBACK_STATE_PAUSED){
                    mPlayer.stop();
                }
                item.setState(state);
                found = item;
                // notify client that item is now removed
                if (mCallback != null) {
                    mCallback.onItemChanged(found);
                }
            } else {
                queue.add(item);
            }
        }
        if (found != null) {
            mPlaylist = queue;
            updatePlaybackState();
        } else {
            log("item not found");
        }
        return found;
    }

    private void finishItem(boolean error) {
        PlaylistItem item = getCurrentItem();
        if (item != null) {
            removeItem(item.getItemId(), error ?
                    MediaItemStatus.PLAYBACK_STATE_ERROR :
                        MediaItemStatus.PLAYBACK_STATE_FINISHED);
            updateStatus();
        }
    }

    // set the Player that this playback manager will interact with
    public void setPlayer(Player player) {
        mPlayer = player;
        checkPlayer();
        mPlayer.setCallback(this);
    }

    // provide a callback interface to tell the UI when significant state changes occur
    public void setCallback(Callback callback) {
        mCallback = callback;
    }

    @Override
    public String toString() {
        String result = "Media Queue: ";
        if (!mPlaylist.isEmpty()) {
            for (PlaylistItem item : mPlaylist) {
                result += "\n" + item.toString();
            }
        } else {
            result += "<empty>";
        }
        return result;
    }

    public interface Callback {
        void onStatusChanged();
        void onItemChanged(PlaylistItem item);
    }
}
