/*
 * Copyright 2018 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.packageinstaller;

import android.annotation.NonNull;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageItemInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.res.Resources;
import android.graphics.drawable.Icon;
import android.net.Uri;
import android.os.Bundle;
import android.provider.Settings;
import android.util.Log;

/**
 * A util class that handle and post new app installed notifications.
 */
class PackageInstalledNotificationUtils {
    private static final String TAG = PackageInstalledNotificationUtils.class.getSimpleName();

    private static final String NEW_APP_INSTALLED_CHANNEL_ID_PREFIX = "INSTALLER:";
    private static final String META_DATA_INSTALLER_NOTIFICATION_SMALL_ICON_KEY =
            "com.android.packageinstaller.notification.smallIcon";
    private static final String META_DATA_INSTALLER_NOTIFICATION_COLOR_KEY =
            "com.android.packageinstaller.notification.color";

    private static final float DEFAULT_MAX_LABEL_SIZE_PX = 500f;

    private final Context mContext;
    private final NotificationManager mNotificationManager;

    private final String mInstallerPackage;
    private final String mInstallerAppLabel;
    private final Icon mInstallerAppSmallIcon;
    private final Integer mInstallerAppColor;

    private final String mInstalledPackage;
    private final String mInstalledAppLabel;
    private final Icon mInstalledAppLargeIcon;

    private final String mChannelId;

    PackageInstalledNotificationUtils(@NonNull Context context, @NonNull String installerPackage,
            @NonNull String installedPackage) {
        mContext = context;
        mNotificationManager = context.getSystemService(NotificationManager.class);
        ApplicationInfo installerAppInfo;
        ApplicationInfo installedAppInfo;

        try {
            installerAppInfo = context.getPackageManager().getApplicationInfo(installerPackage,
                    PackageManager.GET_META_DATA);
        } catch (PackageManager.NameNotFoundException e) {
            // Should not happen
            throw new IllegalStateException("Unable to get application info: " + installerPackage);
        }
        try {
            installedAppInfo = context.getPackageManager().getApplicationInfo(installedPackage,
                    PackageManager.GET_META_DATA);
        } catch (PackageManager.NameNotFoundException e) {
            // Should not happen
            throw new IllegalStateException("Unable to get application info: " + installedPackage);
        }
        mInstallerPackage = installerPackage;
        mInstallerAppLabel = getAppLabel(context, installerAppInfo, installerPackage);
        mInstallerAppSmallIcon = getAppNotificationIcon(context, installerAppInfo);
        mInstallerAppColor = getAppNotificationColor(context, installerAppInfo);

        mInstalledPackage = installedPackage;
        mInstalledAppLabel = getAppLabel(context, installedAppInfo, installerPackage);
        mInstalledAppLargeIcon = getAppLargeIcon(installedAppInfo);

        mChannelId = NEW_APP_INSTALLED_CHANNEL_ID_PREFIX + installerPackage;
    }

    /**
     * Get app label from app's manifest.
     *
     * @param context     A context of the current app
     * @param appInfo     Application info of targeted app
     * @param packageName Package name of targeted app
     * @return The label of targeted application, or package name if label is not found
     */
    private static String getAppLabel(@NonNull Context context, @NonNull ApplicationInfo appInfo,
            @NonNull String packageName) {
        CharSequence label = appInfo.loadSafeLabel(context.getPackageManager(),
                DEFAULT_MAX_LABEL_SIZE_PX,
                PackageItemInfo.SAFE_LABEL_FLAG_TRIM
                        | PackageItemInfo.SAFE_LABEL_FLAG_FIRST_LINE).toString();
        if (label != null) {
            return label.toString();
        }
        return packageName;
    }

    /**
     * The app icon from app's manifest.
     *
     * @param appInfo Application info of targeted app
     * @return App icon of targeted app, or Android default app icon if icon is not found
     */
    private static Icon getAppLargeIcon(@NonNull ApplicationInfo appInfo) {
        if (appInfo.icon != 0) {
            return Icon.createWithResource(appInfo.packageName, appInfo.icon);
        } else {
            return Icon.createWithResource("android", android.R.drawable.sym_def_app_icon);
        }
    }

    /**
     * Get notification icon from installer's manifest meta-data.
     *
     * @param context A context of the current app
     * @param appInfo Installer application info
     * @return Notification icon that listed in installer's manifest meta-data.
     * If icon is not found in meta-data, then it returns Android default download icon.
     */
    private static Icon getAppNotificationIcon(@NonNull Context context,
            @NonNull ApplicationInfo appInfo) {
        if (appInfo.metaData == null) {
            return Icon.createWithResource(context, R.drawable.ic_file_download);
        }

        int iconResId = appInfo.metaData.getInt(
                META_DATA_INSTALLER_NOTIFICATION_SMALL_ICON_KEY, 0);
        if (iconResId != 0) {
            return Icon.createWithResource(appInfo.packageName, iconResId);
        }
        return Icon.createWithResource(context, R.drawable.ic_file_download);
    }

    /**
     * Get notification color from installer's manifest meta-data.
     *
     * @param context A context of the current app
     * @param appInfo Installer application info
     * @return Notification color that listed in installer's manifest meta-data, or null if
     * meta-data is not found.
     */
    private static Integer getAppNotificationColor(@NonNull Context context,
            @NonNull ApplicationInfo appInfo) {
        if (appInfo.metaData == null) {
            return null;
        }

        int colorResId = appInfo.metaData.getInt(
                META_DATA_INSTALLER_NOTIFICATION_COLOR_KEY, 0);
        if (colorResId != 0) {
            try {
                PackageManager pm = context.getPackageManager();
                Resources resources = pm.getResourcesForApplication(appInfo.packageName);
                return resources.getColor(colorResId, context.getTheme());
            } catch (PackageManager.NameNotFoundException e) {
                Log.e(TAG, "Error while loading notification color: " + colorResId + " for "
                        + appInfo.packageName);
            }
        }
        return null;
    }

    private static Intent getAppDetailIntent(@NonNull String packageName) {
        Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
        intent.setData(Uri.fromParts("package", packageName, null));
        return intent;
    }

    private static Intent resolveIntent(@NonNull Context context, @NonNull Intent i) {
        ResolveInfo result = context.getPackageManager().resolveActivity(i, 0);
        if (result == null) {
            return null;
        }
        return new Intent(i.getAction()).setClassName(result.activityInfo.packageName,
                result.activityInfo.name);
    }

    private static Intent getAppStoreLink(@NonNull Context context,
            @NonNull String installerPackageName, @NonNull String packageName) {
        Intent intent = new Intent(Intent.ACTION_SHOW_APP_INFO)
                .setPackage(installerPackageName);

        Intent result = resolveIntent(context, intent);
        if (result != null) {
            result.putExtra(Intent.EXTRA_PACKAGE_NAME, packageName);
            return result;
        }
        return null;
    }

    /**
     * Create notification channel for showing apps installed notifications.
     */
    private void createChannel() {
        NotificationChannel channel = new NotificationChannel(mChannelId, mInstallerAppLabel,
                NotificationManager.IMPORTANCE_DEFAULT);
        channel.setDescription(
                mContext.getString(R.string.app_installed_notification_channel_description));
        channel.enableVibration(false);
        channel.setSound(null, null);
        channel.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE);
        channel.setBlockable(true);

        mNotificationManager.createNotificationChannel(channel);
    }

    /**
     * Returns a pending intent when user clicks on apps installed notification.
     * It should launch the app if possible, otherwise it will return app store's app page.
     * If app store's app page is not available, it will return Android app details page.
     */
    private PendingIntent getInstalledAppLaunchIntent() {
        Intent intent = mContext.getPackageManager().getLaunchIntentForPackage(mInstalledPackage);

        // If installed app does not have a launch intent, bring user to app store page
        if (intent == null) {
            intent = getAppStoreLink(mContext, mInstallerPackage, mInstalledPackage);
        }

        // If app store cannot handle this, bring user to app settings page
        if (intent == null) {
            intent = getAppDetailIntent(mInstalledPackage);
        }

        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        return PendingIntent.getActivity(mContext, 0 /* request code */, intent,
                PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE);
    }

    /**
     * Returns a pending intent that starts installer's launch intent.
     * If it doesn't have a launch intent, it will return installer's Android app details page.
     */
    private PendingIntent getInstallerEntranceIntent() {
        Intent intent = mContext.getPackageManager().getLaunchIntentForPackage(mInstallerPackage);

        // If installer does not have a launch intent, bring user to app settings page
        if (intent == null) {
            intent = getAppDetailIntent(mInstallerPackage);
        }

        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        return PendingIntent.getActivity(mContext, 0 /* request code */, intent,
                PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE);
    }

    /**
     * Returns a notification builder for grouped notifications.
     */
    private Notification.Builder getGroupNotificationBuilder() {
        PendingIntent contentIntent = getInstallerEntranceIntent();

        Bundle extras = new Bundle();
        extras.putString(Notification.EXTRA_SUBSTITUTE_APP_NAME, mInstallerAppLabel);

        Notification.Builder builder =
                new Notification.Builder(mContext, mChannelId)
                        .setSmallIcon(mInstallerAppSmallIcon)
                        .setGroup(mChannelId)
                        .setExtras(extras)
                        .setLocalOnly(true)
                        .setCategory(Notification.CATEGORY_STATUS)
                        .setContentIntent(contentIntent)
                        .setGroupSummary(true);

        if (mInstallerAppColor != null) {
            builder.setColor(mInstallerAppColor);
        }
        return builder;
    }

    /**
     * Returns notification build for individual installed applications.
     */
    private Notification.Builder getAppInstalledNotificationBuilder() {
        PendingIntent contentIntent = getInstalledAppLaunchIntent();

        Bundle extras = new Bundle();
        extras.putString(Notification.EXTRA_SUBSTITUTE_APP_NAME, mInstallerAppLabel);

        String tickerText = String.format(
                mContext.getString(R.string.notification_installation_success_status),
                mInstalledAppLabel);

        Notification.Builder builder =
                new Notification.Builder(mContext, mChannelId)
                        .setAutoCancel(true)
                        .setSmallIcon(mInstallerAppSmallIcon)
                        .setContentTitle(mInstalledAppLabel)
                        .setContentText(mContext.getString(
                                R.string.notification_installation_success_message))
                        .setContentIntent(contentIntent)
                        .setTicker(tickerText)
                        .setCategory(Notification.CATEGORY_STATUS)
                        .setShowWhen(true)
                        .setWhen(System.currentTimeMillis())
                        .setLocalOnly(true)
                        .setGroup(mChannelId)
                        .addExtras(extras)
                        .setStyle(new Notification.BigTextStyle());

        if (mInstalledAppLargeIcon != null) {
            builder.setLargeIcon(mInstalledAppLargeIcon);
        }
        if (mInstallerAppColor != null) {
            builder.setColor(mInstallerAppColor);
        }
        return builder;
    }

    /**
     * Post new app installed notification.
     */
    void postAppInstalledNotification() {
        createChannel();

        // Post app installed notification
        Notification.Builder appNotificationBuilder = getAppInstalledNotificationBuilder();
        mNotificationManager.notify(mInstalledPackage, mInstalledPackage.hashCode(),
                appNotificationBuilder.build());

        // Post installer group notification
        Notification.Builder groupNotificationBuilder = getGroupNotificationBuilder();
        mNotificationManager.notify(mInstallerPackage, mInstallerPackage.hashCode(),
                groupNotificationBuilder.build());
    }
}
