/*
 * Copyright (C) 2017 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.systemui.pip.tv;

import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.ParceledListSlice;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.media.MediaMetadata;
import android.media.session.MediaController;
import android.media.session.PlaybackState;
import android.text.TextUtils;
import android.util.Log;

import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
import com.android.systemui.R;
import com.android.systemui.util.NotificationChannels;

/**
 * A notification that informs users that PIP is running and also provides PIP controls.
 * <p>Once it's created, it will manage the PIP notification UI by itself except for handling
 * configuration changes.
 */
public class PipNotification {
    private static final String TAG = "PipNotification";
    private static final String NOTIFICATION_TAG = PipNotification.class.getSimpleName();
    private static final boolean DEBUG = PipManager.DEBUG;

    private static final String ACTION_MENU = "PipNotification.menu";
    private static final String ACTION_CLOSE = "PipNotification.close";

    private final PipManager mPipManager = PipManager.getInstance();

    private final NotificationManager mNotificationManager;
    private final Notification.Builder mNotificationBuilder;

    private MediaController mMediaController;
    private String mDefaultTitle;
    private int mDefaultIconResId;

    private boolean mNotified;
    private String mTitle;
    private Bitmap mArt;

    private PipManager.Listener mPipListener = new PipManager.Listener() {
        @Override
        public void onPipEntered() {
            updateMediaControllerMetadata();
            notifyPipNotification();
        }

        @Override
        public void onPipActivityClosed() {
            dismissPipNotification();
        }

        @Override
        public void onShowPipMenu() {
            // no-op.
        }

        @Override
        public void onPipMenuActionsChanged(ParceledListSlice actions) {
            // no-op.
        }

        @Override
        public void onMoveToFullscreen() {
            dismissPipNotification();
        }

        @Override
        public void onPipResizeAboutToStart() {
            // no-op.
        }
    };

    private MediaController.Callback mMediaControllerCallback = new MediaController.Callback() {
        @Override
        public void onPlaybackStateChanged(PlaybackState state) {
            if (updateMediaControllerMetadata() && mNotified) {
                // update notification
                notifyPipNotification();
            }
        }
    };

    private final PipManager.MediaListener mPipMediaListener = new PipManager.MediaListener() {
        @Override
        public void onMediaControllerChanged() {
            MediaController newController = mPipManager.getMediaController();
            if (mMediaController == newController) {
                return;
            }
            if (mMediaController != null) {
                mMediaController.unregisterCallback(mMediaControllerCallback);
            }
            mMediaController = newController;
            if (mMediaController != null) {
                mMediaController.registerCallback(mMediaControllerCallback);
            }
            if (updateMediaControllerMetadata() && mNotified) {
                // update notification
                notifyPipNotification();
            }
        }
    };

    private final BroadcastReceiver mEventReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            if (DEBUG) {
                Log.d(TAG, "Received " + intent.getAction() + " from the notification UI");
            }
            switch (intent.getAction()) {
                case ACTION_MENU:
                    mPipManager.showPictureInPictureMenu();
                    break;
                case ACTION_CLOSE:
                    mPipManager.closePip();
                    break;
            }
        }
    };

    public PipNotification(Context context) {
        mNotificationManager = (NotificationManager) context.getSystemService(
                Context.NOTIFICATION_SERVICE);

        mNotificationBuilder = new Notification.Builder(context, NotificationChannels.TVPIP)
                .setLocalOnly(true)
                .setOngoing(false)
                .setCategory(Notification.CATEGORY_SYSTEM)
                .extend(new Notification.TvExtender()
                        .setContentIntent(createPendingIntent(context, ACTION_MENU))
                        .setDeleteIntent(createPendingIntent(context, ACTION_CLOSE)));

        mPipManager.addListener(mPipListener);
        mPipManager.addMediaListener(mPipMediaListener);

        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction(ACTION_MENU);
        intentFilter.addAction(ACTION_CLOSE);
        context.registerReceiver(mEventReceiver, intentFilter);

        onConfigurationChanged(context);
    }

    /**
     * Called by {@link PipManager} when the configuration is changed.
     */
    void onConfigurationChanged(Context context) {
        Resources res = context.getResources();
        mDefaultTitle = res.getString(R.string.pip_notification_unknown_title);
        mDefaultIconResId = R.drawable.pip_icon;
        if (mNotified) {
            // update notification
            notifyPipNotification();
        }
    }

    private void notifyPipNotification() {
        mNotified = true;
        mNotificationBuilder
                .setShowWhen(true)
                .setWhen(System.currentTimeMillis())
                .setSmallIcon(mDefaultIconResId)
                .setContentTitle(!TextUtils.isEmpty(mTitle) ? mTitle : mDefaultTitle);
        if (mArt != null) {
            mNotificationBuilder.setStyle(new Notification.BigPictureStyle()
                    .bigPicture(mArt));
        } else {
            mNotificationBuilder.setStyle(null);
        }
        mNotificationManager.notify(NOTIFICATION_TAG, SystemMessage.NOTE_TV_PIP,
                mNotificationBuilder.build());
    }

    private void dismissPipNotification() {
        mNotified = false;
        mNotificationManager.cancel(NOTIFICATION_TAG, SystemMessage.NOTE_TV_PIP);
    }

    private boolean updateMediaControllerMetadata() {
        String title = null;
        Bitmap art = null;
        if (mPipManager.getMediaController() != null) {
            MediaMetadata metadata = mPipManager.getMediaController().getMetadata();
            if (metadata != null) {
                title = metadata.getString(MediaMetadata.METADATA_KEY_DISPLAY_TITLE);
                if (TextUtils.isEmpty(title)) {
                    title = metadata.getString(MediaMetadata.METADATA_KEY_TITLE);
                }
                art = metadata.getBitmap(MediaMetadata.METADATA_KEY_ALBUM_ART);
                if (art == null) {
                    art = metadata.getBitmap(MediaMetadata.METADATA_KEY_ART);
                }
            }
        }
        if (!TextUtils.equals(title, mTitle) || art != mArt) {
            mTitle = title;
            mArt = art;
            return true;
        }
        return false;
    }

    private static PendingIntent createPendingIntent(Context context, String action) {
        return PendingIntent.getBroadcast(context, 0,
                new Intent(action), PendingIntent.FLAG_CANCEL_CURRENT);
    }
}
