/*
 * 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.systemui.bubbles;

import static com.android.systemui.bubbles.BadgedImageView.DEFAULT_PATH_SIZE;
import static com.android.systemui.bubbles.BadgedImageView.WHITE_SCRIM_ALPHA;
import static com.android.systemui.bubbles.BubbleDebugConfig.TAG_BUBBLES;
import static com.android.systemui.bubbles.BubbleDebugConfig.TAG_WITH_CLASS_NAME;

import android.annotation.NonNull;
import android.app.Notification;
import android.app.Person;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.ShortcutInfo;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Path;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.Icon;
import android.os.AsyncTask;
import android.os.Parcelable;
import android.service.notification.StatusBarNotification;
import android.text.TextUtils;
import android.util.Log;
import android.util.PathParser;
import android.view.LayoutInflater;

import androidx.annotation.Nullable;

import com.android.internal.graphics.ColorUtils;
import com.android.launcher3.icons.BitmapInfo;
import com.android.systemui.R;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;

import java.lang.ref.WeakReference;
import java.util.List;

/**
 * Simple task to inflate views & load necessary info to display a bubble.
 */
public class BubbleViewInfoTask extends AsyncTask<Void, Void, BubbleViewInfoTask.BubbleViewInfo> {
    private static final String TAG = TAG_WITH_CLASS_NAME ? "BubbleViewInfoTask" : TAG_BUBBLES;


    /**
     * Callback to find out when the bubble has been inflated & necessary data loaded.
     */
    public interface Callback {
        /**
         * Called when data has been loaded for the bubble.
         */
        void onBubbleViewsReady(Bubble bubble);
    }

    private Bubble mBubble;
    private WeakReference<Context> mContext;
    private WeakReference<BubbleStackView> mStackView;
    private BubbleIconFactory mIconFactory;
    private Callback mCallback;

    /**
     * Creates a task to load information for the provided {@link Bubble}. Once all info
     * is loaded, {@link Callback} is notified.
     */
    BubbleViewInfoTask(Bubble b,
            Context context,
            BubbleStackView stackView,
            BubbleIconFactory factory,
            Callback c) {
        mBubble = b;
        mContext = new WeakReference<>(context);
        mStackView = new WeakReference<>(stackView);
        mIconFactory = factory;
        mCallback = c;
    }

    @Override
    protected BubbleViewInfo doInBackground(Void... voids) {
        return BubbleViewInfo.populate(mContext.get(), mStackView.get(), mIconFactory, mBubble);
    }

    @Override
    protected void onPostExecute(BubbleViewInfo viewInfo) {
        if (viewInfo != null) {
            mBubble.setViewInfo(viewInfo);
            if (mCallback != null && !isCancelled()) {
                mCallback.onBubbleViewsReady(mBubble);
            }
        }
    }

    /**
     * Info necessary to render a bubble.
     */
    static class BubbleViewInfo {
        BadgedImageView imageView;
        BubbleExpandedView expandedView;
        ShortcutInfo shortcutInfo;
        String appName;
        Bitmap badgedBubbleImage;
        int dotColor;
        Path dotPath;
        Bubble.FlyoutMessage flyoutMessage;

        @Nullable
        static BubbleViewInfo populate(Context c, BubbleStackView stackView,
                BubbleIconFactory iconFactory, Bubble b) {
            BubbleViewInfo info = new BubbleViewInfo();

            // View inflation: only should do this once per bubble
            if (!b.isInflated()) {
                LayoutInflater inflater = LayoutInflater.from(c);
                info.imageView = (BadgedImageView) inflater.inflate(
                        R.layout.bubble_view, stackView, false /* attachToRoot */);

                info.expandedView = (BubbleExpandedView) inflater.inflate(
                        R.layout.bubble_expanded_view, stackView, false /* attachToRoot */);
                info.expandedView.setStackView(stackView);
            }

            StatusBarNotification sbn = b.getEntry().getSbn();
            String packageName = sbn.getPackageName();

            String bubbleShortcutId =  b.getEntry().getBubbleMetadata().getShortcutId();
            if (bubbleShortcutId != null) {
                info.shortcutInfo = b.getEntry().getRanking().getShortcutInfo();
            }

            // App name & app icon
            PackageManager pm = c.getPackageManager();
            ApplicationInfo appInfo;
            Drawable badgedIcon;
            Drawable appIcon;
            try {
                appInfo = pm.getApplicationInfo(
                        packageName,
                        PackageManager.MATCH_UNINSTALLED_PACKAGES
                                | PackageManager.MATCH_DISABLED_COMPONENTS
                                | PackageManager.MATCH_DIRECT_BOOT_UNAWARE
                                | PackageManager.MATCH_DIRECT_BOOT_AWARE);
                if (appInfo != null) {
                    info.appName = String.valueOf(pm.getApplicationLabel(appInfo));
                }
                appIcon = pm.getApplicationIcon(packageName);
                badgedIcon = pm.getUserBadgedIcon(appIcon, sbn.getUser());
            } catch (PackageManager.NameNotFoundException exception) {
                // If we can't find package... don't think we should show the bubble.
                Log.w(TAG, "Unable to find package: " + packageName);
                return null;
            }

            // Badged bubble image
            Drawable bubbleDrawable = iconFactory.getBubbleDrawable(c, info.shortcutInfo,
                    b.getEntry().getBubbleMetadata());
            if (bubbleDrawable == null) {
                // Default to app icon
                bubbleDrawable = appIcon;
            }

            BitmapInfo badgeBitmapInfo = iconFactory.getBadgeBitmap(badgedIcon);
            info.badgedBubbleImage = iconFactory.getBubbleBitmap(bubbleDrawable,
                    badgeBitmapInfo).icon;

            // Dot color & placement
            Path iconPath = PathParser.createPathFromPathData(
                    c.getResources().getString(com.android.internal.R.string.config_icon_mask));
            Matrix matrix = new Matrix();
            float scale = iconFactory.getNormalizer().getScale(bubbleDrawable,
                    null /* outBounds */, null /* path */, null /* outMaskShape */);
            float radius = DEFAULT_PATH_SIZE / 2f;
            matrix.setScale(scale /* x scale */, scale /* y scale */, radius /* pivot x */,
                    radius /* pivot y */);
            iconPath.transform(matrix);
            info.dotPath = iconPath;
            info.dotColor = ColorUtils.blendARGB(badgeBitmapInfo.color,
                    Color.WHITE, WHITE_SCRIM_ALPHA);

            // Flyout
            info.flyoutMessage = extractFlyoutMessage(c, b.getEntry());
            return info;
        }
    }


    /**
     * Returns our best guess for the most relevant text summary of the latest update to this
     * notification, based on its type. Returns null if there should not be an update message.
     */
    @NonNull
    static Bubble.FlyoutMessage extractFlyoutMessage(Context context,
            NotificationEntry entry) {
        final Notification underlyingNotif = entry.getSbn().getNotification();
        final Class<? extends Notification.Style> style = underlyingNotif.getNotificationStyle();

        Bubble.FlyoutMessage bubbleMessage = new Bubble.FlyoutMessage();
        bubbleMessage.isGroupChat = underlyingNotif.extras.getBoolean(
                Notification.EXTRA_IS_GROUP_CONVERSATION);
        try {
            if (Notification.BigTextStyle.class.equals(style)) {
                // Return the big text, it is big so probably important. If it's not there use the
                // normal text.
                CharSequence bigText =
                        underlyingNotif.extras.getCharSequence(Notification.EXTRA_BIG_TEXT);
                bubbleMessage.message = !TextUtils.isEmpty(bigText)
                        ? bigText
                        : underlyingNotif.extras.getCharSequence(Notification.EXTRA_TEXT);
                return bubbleMessage;
            } else if (Notification.MessagingStyle.class.equals(style)) {
                final List<Notification.MessagingStyle.Message> messages =
                        Notification.MessagingStyle.Message.getMessagesFromBundleArray(
                                (Parcelable[]) underlyingNotif.extras.get(
                                        Notification.EXTRA_MESSAGES));

                final Notification.MessagingStyle.Message latestMessage =
                        Notification.MessagingStyle.findLatestIncomingMessage(messages);
                if (latestMessage != null) {
                    bubbleMessage.message = latestMessage.getText();
                    Person sender = latestMessage.getSenderPerson();
                    bubbleMessage.senderName = sender != null
                            ? sender.getName()
                            : null;

                    bubbleMessage.senderAvatar = null;
                    if (sender != null && sender.getIcon() != null) {
                        if (sender.getIcon().getType() == Icon.TYPE_URI
                                || sender.getIcon().getType() == Icon.TYPE_URI_ADAPTIVE_BITMAP) {
                            context.grantUriPermission(context.getPackageName(),
                                    sender.getIcon().getUri(),
                                    Intent.FLAG_GRANT_READ_URI_PERMISSION);
                        }
                        bubbleMessage.senderAvatar = sender.getIcon().loadDrawable(context);
                    }
                    return bubbleMessage;
                }
            } else if (Notification.InboxStyle.class.equals(style)) {
                CharSequence[] lines =
                        underlyingNotif.extras.getCharSequenceArray(Notification.EXTRA_TEXT_LINES);

                // Return the last line since it should be the most recent.
                if (lines != null && lines.length > 0) {
                    bubbleMessage.message = lines[lines.length - 1];
                    return bubbleMessage;
                }
            } else if (Notification.MediaStyle.class.equals(style)) {
                // Return nothing, media updates aren't typically useful as a text update.
                return bubbleMessage;
            } else {
                // Default to text extra.
                bubbleMessage.message =
                        underlyingNotif.extras.getCharSequence(Notification.EXTRA_TEXT);
                return bubbleMessage;
            }
        } catch (ClassCastException | NullPointerException | ArrayIndexOutOfBoundsException e) {
            // No use crashing, we'll just return null and the caller will assume there's no update
            // message.
            e.printStackTrace();
        }

        return bubbleMessage;
    }
}
