/*
**
** Copyright 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.android.commands.media;

import android.app.ActivityManager;
import android.content.Context;
import android.content.pm.ParceledListSlice;
import android.media.MediaMetadata;
import android.media.session.ISessionController;
import android.media.session.ISessionControllerCallback;
import android.media.session.ISessionManager;
import android.media.session.ParcelableVolumeInfo;
import android.media.session.PlaybackState;
import android.os.Bundle;
import android.os.HandlerThread;
import android.os.IBinder;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.SystemClock;
import android.util.AndroidException;
import android.view.InputDevice;
import android.view.KeyCharacterMap;
import android.view.KeyEvent;

import com.android.internal.os.BaseCommand;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.util.List;

public class Media extends BaseCommand {
    private ISessionManager mSessionService;

    /**
     * Command-line entry point.
     *
     * @param args The command-line arguments
     */
    public static void main(String[] args) {
        (new Media()).run(args);
    }

    public void onShowUsage(PrintStream out) {
        out.println(
                "usage: media [subcommand] [options]\n" +
                "       media dispatch KEY\n" +
                "       media list-sessions\n" +
                "       media monitor <tag>\n" +
                "\n" +
                "media dispatch: dispatch a media key to the system.\n" +
                "                KEY may be: play, pause, play-pause, mute, headsethook,\n" +
                "                stop, next, previous, rewind, record, fast-forword.\n" +
                "media list-sessions: print a list of the current sessions.\n" +
                        "media monitor: monitor updates to the specified session.\n" +
                "                       Use the tag from list-sessions.\n"
        );
    }

    public void onRun() throws Exception {
        mSessionService = ISessionManager.Stub.asInterface(ServiceManager.checkService(
                Context.MEDIA_SESSION_SERVICE));
        if (mSessionService == null) {
            System.err.println(NO_SYSTEM_ERROR_CODE);
            throw new AndroidException(
                    "Can't connect to media session service; is the system running?");
        }

        String op = nextArgRequired();

        if (op.equals("dispatch")) {
            runDispatch();
        } else if (op.equals("list-sessions")) {
            runListSessions();
        } else if (op.equals("monitor")) {
            runMonitor();
        } else {
            showError("Error: unknown command '" + op + "'");
            return;
        }
    }

    private void sendMediaKey(KeyEvent event) {
        try {
            mSessionService.dispatchMediaKeyEvent(event, false);
        } catch (RemoteException e) {
        }
    }

    private void runMonitor() throws Exception {
        String id = nextArgRequired();
        if (id == null) {
            showError("Error: must include a session id");
            return;
        }
        boolean success = false;
        try {
            List<IBinder> sessions = mSessionService
                    .getSessions(null, ActivityManager.getCurrentUser());
            for (IBinder session : sessions) {
                ISessionController controller = ISessionController.Stub.asInterface(session);
                try {
                    if (controller != null && id.equals(controller.getTag())) {
                        ControllerMonitor monitor = new ControllerMonitor(controller);
                        monitor.run();
                        success = true;
                        break;
                    }
                } catch (RemoteException e) {
                    // ignore
                }
            }
        } catch (Exception e) {
            System.out.println("***Error monitoring session*** " + e.getMessage());
        }
        if (!success) {
            System.out.println("No session found with id " + id);
        }
    }

    private void runDispatch() throws Exception {
        String cmd = nextArgRequired();
        int keycode;
        if ("play".equals(cmd)) {
            keycode = KeyEvent.KEYCODE_MEDIA_PLAY;
        } else if ("pause".equals(cmd)) {
            keycode = KeyEvent.KEYCODE_MEDIA_PAUSE;
        } else if ("play-pause".equals(cmd)) {
            keycode = KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE;
        } else if ("mute".equals(cmd)) {
            keycode = KeyEvent.KEYCODE_MUTE;
        } else if ("headsethook".equals(cmd)) {
            keycode = KeyEvent.KEYCODE_HEADSETHOOK;
        } else if ("stop".equals(cmd)) {
            keycode = KeyEvent.KEYCODE_MEDIA_STOP;
        } else if ("next".equals(cmd)) {
            keycode = KeyEvent.KEYCODE_MEDIA_NEXT;
        } else if ("previous".equals(cmd)) {
            keycode = KeyEvent.KEYCODE_MEDIA_PREVIOUS;
        } else if ("rewind".equals(cmd)) {
            keycode = KeyEvent.KEYCODE_MEDIA_REWIND;
        } else if ("record".equals(cmd)) {
            keycode = KeyEvent.KEYCODE_MEDIA_RECORD;
        } else if ("fast-forward".equals(cmd)) {
            keycode = KeyEvent.KEYCODE_MEDIA_FAST_FORWARD;
        } else {
            showError("Error: unknown dispatch code '" + cmd + "'");
            return;
        }

        final long now = SystemClock.uptimeMillis();
        sendMediaKey(new KeyEvent(now, now, KeyEvent.ACTION_DOWN, keycode, 0, 0,
                KeyCharacterMap.VIRTUAL_KEYBOARD, 0, 0, InputDevice.SOURCE_KEYBOARD));
        sendMediaKey(new KeyEvent(now, now, KeyEvent.ACTION_UP, keycode, 0, 0,
                KeyCharacterMap.VIRTUAL_KEYBOARD, 0, 0, InputDevice.SOURCE_KEYBOARD));
    }

    class ControllerMonitor extends ISessionControllerCallback.Stub {
        private final ISessionController mController;

        public ControllerMonitor(ISessionController controller) {
            mController = controller;
        }

        @Override
        public void onSessionDestroyed() {
            System.out.println("onSessionDestroyed. Enter q to quit.");

        }

        @Override
        public void onEvent(String event, Bundle extras) {
            System.out.println("onSessionEvent event=" + event + ", extras=" + extras);
        }

        @Override
        public void onPlaybackStateChanged(PlaybackState state) {
            System.out.println("onPlaybackStateChanged " + state);
        }

        @Override
        public void onMetadataChanged(MediaMetadata metadata) {
            String mmString = metadata == null ? null : "title=" + metadata
                    .getDescription();
            System.out.println("onMetadataChanged " + mmString);
        }

        @Override
        public void onQueueChanged(ParceledListSlice queue) throws RemoteException {
            System.out.println("onQueueChanged, "
                    + (queue == null ? "null queue" : " size=" + queue.getList().size()));
        }

        @Override
        public void onQueueTitleChanged(CharSequence title) throws RemoteException {
            System.out.println("onQueueTitleChange " + title);
        }

        @Override
        public void onExtrasChanged(Bundle extras) throws RemoteException {
            System.out.println("onExtrasChanged " + extras);
        }

        @Override
        public void onVolumeInfoChanged(ParcelableVolumeInfo info) throws RemoteException {
            System.out.println("onVolumeInfoChanged " + info);
        }

        void printUsageMessage() {
            try {
                System.out.println("V2Monitoring session " + mController.getTag()
                        + "...  available commands: play, pause, next, previous");
            } catch (RemoteException e) {
                System.out.println("Error trying to monitor session!");
            }
            System.out.println("(q)uit: finish monitoring");
        }

        void run() throws RemoteException {
            printUsageMessage();
            HandlerThread cbThread = new HandlerThread("MediaCb") {
                @Override
                protected void onLooperPrepared() {
                    try {
                        mController.registerCallbackListener(ControllerMonitor.this);
                    } catch (RemoteException e) {
                        System.out.println("Error registering monitor callback");
                    }
                }
            };
            cbThread.start();

            try {
                InputStreamReader converter = new InputStreamReader(System.in);
                BufferedReader in = new BufferedReader(converter);
                String line;

                while ((line = in.readLine()) != null) {
                    boolean addNewline = true;
                    if (line.length() <= 0) {
                        addNewline = false;
                    } else if ("q".equals(line) || "quit".equals(line)) {
                        break;
                    } else if ("play".equals(line)) {
                        mController.play();
                    } else if ("pause".equals(line)) {
                        mController.pause();
                    } else if ("next".equals(line)) {
                        mController.next();
                    } else if ("previous".equals(line)) {
                        mController.previous();
                    } else {
                        System.out.println("Invalid command: " + line);
                    }

                    synchronized (this) {
                        if (addNewline) {
                            System.out.println("");
                        }
                        printUsageMessage();
                    }
                }
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                cbThread.getLooper().quit();
                try {
                    mController.unregisterCallbackListener(this);
                } catch (Exception e) {
                    // ignoring
                }
            }
        }
    }

    private void runListSessions() {
        System.out.println("Sessions:");
        try {
            List<IBinder> sessions = mSessionService
                    .getSessions(null, ActivityManager.getCurrentUser());
            for (IBinder session : sessions) {

                ISessionController controller = ISessionController.Stub.asInterface(session);
                if (controller != null) {
                    try {
                        System.out.println("  tag=" + controller.getTag()
                                + ", package=" + controller.getPackageName());
                    } catch (RemoteException e) {
                        // ignore
                    }
                }
            }
        } catch (Exception e) {
            System.out.println("***Error listing sessions***");
        }
    }
}
