/*
 * Copyright (C) 2019 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.settingslib.volume;

import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.ResolveInfo;
import android.media.IRemoteVolumeController;
import android.media.MediaMetadata;
import android.media.session.MediaController;
import android.media.session.MediaController.PlaybackInfo;
import android.media.session.MediaSession.QueueItem;
import android.media.session.MediaSession.Token;
import android.media.session.MediaSessionManager;
import android.media.session.MediaSessionManager.OnActiveSessionsChangedListener;
import android.media.session.PlaybackState;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.os.RemoteException;
import android.util.Log;

import java.io.PrintWriter;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

/**
 * Convenience client for all media session updates.  Provides a callback interface for events
 * related to remote media sessions.
 */
public class MediaSessions {
    private static final String TAG = Util.logTag(MediaSessions.class);

    private static final boolean USE_SERVICE_LABEL = false;

    private final Context mContext;
    private final H mHandler;
    private final MediaSessionManager mMgr;
    private final Map<Token, MediaControllerRecord> mRecords = new HashMap<>();
    private final Callbacks mCallbacks;

    private boolean mInit;

    public MediaSessions(Context context, Looper looper, Callbacks callbacks) {
        mContext = context;
        mHandler = new H(looper);
        mMgr = (MediaSessionManager) context.getSystemService(Context.MEDIA_SESSION_SERVICE);
        mCallbacks = callbacks;
    }

    /**
     * Dump to {@code writer}
     */
    public void dump(PrintWriter writer) {
        writer.println(getClass().getSimpleName() + " state:");
        writer.print("  mInit: ");
        writer.println(mInit);
        writer.print("  mRecords.size: ");
        writer.println(mRecords.size());
        int i = 0;
        for (MediaControllerRecord r : mRecords.values()) {
            dump(++i, writer, r.controller);
        }
    }

    /**
     * init MediaSessions
     */
    public void init() {
        if (D.BUG) Log.d(TAG, "init");
        // will throw if no permission
        mMgr.addOnActiveSessionsChangedListener(mSessionsListener, null, mHandler);
        mInit = true;
        postUpdateSessions();
        mMgr.setRemoteVolumeController(mRvc);
    }

    protected void postUpdateSessions() {
        if (!mInit) return;
        mHandler.sendEmptyMessage(H.UPDATE_SESSIONS);
    }

    /**
     * Destroy MediaSessions
     */
    public void destroy() {
        if (D.BUG) Log.d(TAG, "destroy");
        mInit = false;
        mMgr.removeOnActiveSessionsChangedListener(mSessionsListener);
    }

    /**
     * Set volume {@code level} to remote media {@code token}
     */
    public void setVolume(Token token, int level) {
        final MediaControllerRecord r = mRecords.get(token);
        if (r == null) {
            Log.w(TAG, "setVolume: No record found for token " + token);
            return;
        }
        if (D.BUG) Log.d(TAG, "Setting level to " + level);
        r.controller.setVolumeTo(level, 0);
    }

    private void onRemoteVolumeChangedH(Token sessionToken, int flags) {
        final MediaController controller = new MediaController(mContext, sessionToken);
        if (D.BUG) {
            Log.d(TAG, "remoteVolumeChangedH " + controller.getPackageName() + " "
                    + Util.audioManagerFlagsToString(flags));
        }
        final Token token = controller.getSessionToken();
        mCallbacks.onRemoteVolumeChanged(token, flags);
    }

    private void onUpdateRemoteControllerH(Token sessionToken) {
        final MediaController controller =
                sessionToken != null ? new MediaController(mContext, sessionToken) : null;
        final String pkg = controller != null ? controller.getPackageName() : null;
        if (D.BUG) Log.d(TAG, "updateRemoteControllerH " + pkg);
        // this may be our only indication that a remote session is changed, refresh
        postUpdateSessions();
    }

    protected void onActiveSessionsUpdatedH(List<MediaController> controllers) {
        if (D.BUG) Log.d(TAG, "onActiveSessionsUpdatedH n=" + controllers.size());
        final Set<Token> toRemove = new HashSet<Token>(mRecords.keySet());
        for (MediaController controller : controllers) {
            final Token token = controller.getSessionToken();
            final PlaybackInfo pi = controller.getPlaybackInfo();
            toRemove.remove(token);
            if (!mRecords.containsKey(token)) {
                final MediaControllerRecord r = new MediaControllerRecord(controller);
                r.name = getControllerName(controller);
                mRecords.put(token, r);
                controller.registerCallback(r, mHandler);
            }
            final MediaControllerRecord r = mRecords.get(token);
            final boolean remote = isRemote(pi);
            if (remote) {
                updateRemoteH(token, r.name, pi);
                r.sentRemote = true;
            }
        }
        for (Token t : toRemove) {
            final MediaControllerRecord r = mRecords.get(t);
            r.controller.unregisterCallback(r);
            mRecords.remove(t);
            if (D.BUG) Log.d(TAG, "Removing " + r.name + " sentRemote=" + r.sentRemote);
            if (r.sentRemote) {
                mCallbacks.onRemoteRemoved(t);
                r.sentRemote = false;
            }
        }
    }

    private static boolean isRemote(PlaybackInfo pi) {
        return pi != null && pi.getPlaybackType() == PlaybackInfo.PLAYBACK_TYPE_REMOTE;
    }

    protected String getControllerName(MediaController controller) {
        final PackageManager pm = mContext.getPackageManager();
        final String pkg = controller.getPackageName();
        try {
            if (USE_SERVICE_LABEL) {
                final List<ResolveInfo> ris = pm.queryIntentServices(
                        new Intent("android.media.MediaRouteProviderService").setPackage(pkg), 0);
                if (ris != null) {
                    for (ResolveInfo ri : ris) {
                        if (ri.serviceInfo == null) continue;
                        if (pkg.equals(ri.serviceInfo.packageName)) {
                            final String serviceLabel =
                                    Objects.toString(ri.serviceInfo.loadLabel(pm), "").trim();
                            if (serviceLabel.length() > 0) {
                                return serviceLabel;
                            }
                        }
                    }
                }
            }
            final ApplicationInfo ai = pm.getApplicationInfo(pkg, 0);
            final String appLabel = Objects.toString(ai.loadLabel(pm), "").trim();
            if (appLabel.length() > 0) {
                return appLabel;
            }
        } catch (NameNotFoundException e) {
        }
        return pkg;
    }

    private void updateRemoteH(Token token, String name, PlaybackInfo pi) {
        if (mCallbacks != null) {
            mCallbacks.onRemoteUpdate(token, name, pi);
        }
    }

    private static void dump(int n, PrintWriter writer, MediaController c) {
        writer.println("  Controller " + n + ": " + c.getPackageName());
        final Bundle extras = c.getExtras();
        final long flags = c.getFlags();
        final MediaMetadata mm = c.getMetadata();
        final PlaybackInfo pi = c.getPlaybackInfo();
        final PlaybackState playbackState = c.getPlaybackState();
        final List<QueueItem> queue = c.getQueue();
        final CharSequence queueTitle = c.getQueueTitle();
        final int ratingType = c.getRatingType();
        final PendingIntent sessionActivity = c.getSessionActivity();

        writer.println("    PlaybackState: " + Util.playbackStateToString(playbackState));
        writer.println("    PlaybackInfo: " + Util.playbackInfoToString(pi));
        if (mm != null) {
            writer.println("  MediaMetadata.desc=" + mm.getDescription());
        }
        writer.println("    RatingType: " + ratingType);
        writer.println("    Flags: " + flags);
        if (extras != null) {
            writer.println("    Extras:");
            for (String key : extras.keySet()) {
                writer.println("      " + key + "=" + extras.get(key));
            }
        }
        if (queueTitle != null) {
            writer.println("    QueueTitle: " + queueTitle);
        }
        if (queue != null && !queue.isEmpty()) {
            writer.println("    Queue:");
            for (QueueItem qi : queue) {
                writer.println("      " + qi);
            }
        }
        if (pi != null) {
            writer.println("    sessionActivity: " + sessionActivity);
        }
    }

    private final class MediaControllerRecord extends MediaController.Callback {
        public final MediaController controller;

        public boolean sentRemote;
        public String name;

        private MediaControllerRecord(MediaController controller) {
            this.controller = controller;
        }

        private String cb(String method) {
            return method + " " + controller.getPackageName() + " ";
        }

        @Override
        public void onAudioInfoChanged(PlaybackInfo info) {
            if (D.BUG) {
                Log.d(TAG, cb("onAudioInfoChanged") + Util.playbackInfoToString(info)
                        + " sentRemote=" + sentRemote);
            }
            final boolean remote = isRemote(info);
            if (!remote && sentRemote) {
                mCallbacks.onRemoteRemoved(controller.getSessionToken());
                sentRemote = false;
            } else if (remote) {
                updateRemoteH(controller.getSessionToken(), name, info);
                sentRemote = true;
            }
        }

        @Override
        public void onExtrasChanged(Bundle extras) {
            if (D.BUG) Log.d(TAG, cb("onExtrasChanged") + extras);
        }

        @Override
        public void onMetadataChanged(MediaMetadata metadata) {
            if (D.BUG) Log.d(TAG, cb("onMetadataChanged") + Util.mediaMetadataToString(metadata));
        }

        @Override
        public void onPlaybackStateChanged(PlaybackState state) {
            if (D.BUG) Log.d(TAG, cb("onPlaybackStateChanged") + Util.playbackStateToString(state));
        }

        @Override
        public void onQueueChanged(List<QueueItem> queue) {
            if (D.BUG) Log.d(TAG, cb("onQueueChanged") + queue);
        }

        @Override
        public void onQueueTitleChanged(CharSequence title) {
            if (D.BUG) Log.d(TAG, cb("onQueueTitleChanged") + title);
        }

        @Override
        public void onSessionDestroyed() {
            if (D.BUG) Log.d(TAG, cb("onSessionDestroyed"));
        }

        @Override
        public void onSessionEvent(String event, Bundle extras) {
            if (D.BUG) Log.d(TAG, cb("onSessionEvent") + "event=" + event + " extras=" + extras);
        }
    }

    private final OnActiveSessionsChangedListener mSessionsListener =
            new OnActiveSessionsChangedListener() {
                @Override
                public void onActiveSessionsChanged(List<MediaController> controllers) {
                    onActiveSessionsUpdatedH(controllers);
                }
            };

    private final IRemoteVolumeController mRvc = new IRemoteVolumeController.Stub() {
        @Override
        public void remoteVolumeChanged(Token sessionToken, int flags)
                throws RemoteException {
            mHandler.obtainMessage(H.REMOTE_VOLUME_CHANGED, flags, 0,
                    sessionToken).sendToTarget();
        }

        @Override
        public void updateRemoteController(final Token sessionToken)
                throws RemoteException {
            mHandler.obtainMessage(H.UPDATE_REMOTE_CONTROLLER, sessionToken).sendToTarget();
        }
    };

    private final class H extends Handler {
        private static final int UPDATE_SESSIONS = 1;
        private static final int REMOTE_VOLUME_CHANGED = 2;
        private static final int UPDATE_REMOTE_CONTROLLER = 3;

        private H(Looper looper) {
            super(looper);
        }

        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case UPDATE_SESSIONS:
                    onActiveSessionsUpdatedH(mMgr.getActiveSessions(null));
                    break;
                case REMOTE_VOLUME_CHANGED:
                    onRemoteVolumeChangedH((Token) msg.obj, msg.arg1);
                    break;
                case UPDATE_REMOTE_CONTROLLER:
                    onUpdateRemoteControllerH((Token) msg.obj);
                    break;
            }
        }
    }

    /**
     * Callback for remote media sessions
     */
    public interface Callbacks {
        /**
         * Invoked when remote media session is updated
         */
        void onRemoteUpdate(Token token, String name, PlaybackInfo pi);

        /**
         * Invoked when remote media session is removed
         */
        void onRemoteRemoved(Token t);

        /**
         * Invoked when remote volume is changed
         */
        void onRemoteVolumeChanged(Token token, int flags);
    }

}
