// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

package org.chromium.chrome.browser.download;

import static android.app.DownloadManager.ACTION_NOTIFICATION_CLICKED;
import static android.app.DownloadManager.EXTRA_NOTIFICATION_CLICK_DOWNLOAD_IDS;

import static org.chromium.chrome.browser.download.DownloadNotificationService.ACTION_DOWNLOAD_CANCEL;
import static org.chromium.chrome.browser.download.DownloadNotificationService.ACTION_DOWNLOAD_OPEN;
import static org.chromium.chrome.browser.download.DownloadNotificationService.ACTION_DOWNLOAD_PAUSE;
import static org.chromium.chrome.browser.download.DownloadNotificationService.ACTION_DOWNLOAD_RESUME;
import static org.chromium.chrome.browser.download.DownloadNotificationService.EXTRA_DOWNLOAD_CONTENTID_ID;
import static org.chromium.chrome.browser.download.DownloadNotificationService.EXTRA_DOWNLOAD_CONTENTID_NAMESPACE;
import static org.chromium.chrome.browser.download.DownloadNotificationService.EXTRA_DOWNLOAD_FILE_PATH;
import static org.chromium.chrome.browser.download.DownloadNotificationService.EXTRA_DOWNLOAD_STATE_AT_CANCEL;
import static org.chromium.chrome.browser.download.DownloadNotificationService.EXTRA_IS_OFF_THE_RECORD;
import static org.chromium.chrome.browser.download.DownloadNotificationService.EXTRA_IS_SUPPORTED_MIME_TYPE;
import static org.chromium.chrome.browser.download.DownloadNotificationService.EXTRA_NOTIFICATION_BUNDLE_ICON_ID;

import android.app.Notification;
import android.app.PendingIntent;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.support.v4.app.NotificationCompat;
import android.text.TextUtils;

import com.google.ipc.invalidation.util.Preconditions;

import org.chromium.chrome.R;
import org.chromium.chrome.browser.media.MediaViewerUtils;
import org.chromium.chrome.browser.notifications.ChromeNotificationBuilder;
import org.chromium.chrome.browser.notifications.NotificationBuilderFactory;
import org.chromium.chrome.browser.notifications.NotificationConstants;
import org.chromium.chrome.browser.notifications.NotificationMetadata;
import org.chromium.chrome.browser.notifications.NotificationUmaTracker;
import org.chromium.chrome.browser.notifications.PendingIntentProvider;
import org.chromium.chrome.browser.notifications.channels.ChannelDefinitions;
import org.chromium.chrome.browser.util.UrlUtilities;
import org.chromium.components.offline_items_collection.ContentId;
import org.chromium.components.offline_items_collection.LegacyHelpers;
import org.chromium.components.offline_items_collection.OfflineItem;
import org.chromium.components.offline_items_collection.PendingState;
import org.chromium.components.url_formatter.UrlFormatter;

/**
 * Creates and updates notifications related to downloads.
 */
public final class DownloadNotificationFactory {
    // Limit file name to 25 characters. TODO(qinmin): use different limit for different devices?
    public static final int MAX_FILE_NAME_LENGTH = 25;

    // Limit the origin length so that the eTLD+1 cannot be hidden. If the origin exceeds this
    // length the eTLD+1 is extracted and shown.
    public static final int MAX_ORIGIN_LENGTH = 40;

    /**
     * Builds a downloads notification based on the status of the download and its information. All
     * changes to this function should consider the difference between normal profile and off the
     * record profile.
     * @param context of the download.
     * @param downloadStatus (in progress, paused, successful, failed, deleted, or summary).
     * @param downloadUpdate information about the download (ie. contentId, fileName, icon,
     * isOffTheRecord, etc).
     * @param notificationId The notification id passed to {@link
     *         android.app.NotificationManager#notify(String, int, Notification)}.
     * @return Notification that is built based on these parameters.
     */
    public static Notification buildNotification(Context context,
            @DownloadNotificationService.DownloadStatus int downloadStatus,
            DownloadUpdate downloadUpdate, int notificationId) {
        ChromeNotificationBuilder builder =
                NotificationBuilderFactory
                        .createChromeNotificationBuilder(true /* preferCompat */,
                                ChannelDefinitions.ChannelId.DOWNLOADS,
                                null /* remoteAppPackageName */,
                                new NotificationMetadata(LegacyHelpers.isLegacyDownload(
                                                                 downloadUpdate.getContentId())
                                                ? NotificationUmaTracker.SystemNotificationType
                                                          .DOWNLOAD_FILES
                                                : NotificationUmaTracker.SystemNotificationType
                                                          .DOWNLOAD_PAGES,
                                        null /* tag */, notificationId))
                        .setLocalOnly(true)
                        .setGroup(NotificationConstants.GROUP_DOWNLOADS)
                        .setAutoCancel(true);

        String contentText;
        int iconId;
        @NotificationUmaTracker.ActionType
        int cancelActionType,
                pauseActionType, resumeActionType;
        if (LegacyHelpers.isLegacyDownload(downloadUpdate.getContentId())) {
            cancelActionType = NotificationUmaTracker.ActionType.DOWNLOAD_CANCEL;
            pauseActionType = NotificationUmaTracker.ActionType.DOWNLOAD_PAUSE;
            resumeActionType = NotificationUmaTracker.ActionType.DOWNLOAD_RESUME;
        } else {
            cancelActionType = NotificationUmaTracker.ActionType.DOWNLOAD_PAGE_CANCEL;
            pauseActionType = NotificationUmaTracker.ActionType.DOWNLOAD_PAGE_PAUSE;
            resumeActionType = NotificationUmaTracker.ActionType.DOWNLOAD_PAGE_RESUME;
        }

        switch (downloadStatus) {
            case DownloadNotificationService.DownloadStatus.IN_PROGRESS:
                Preconditions.checkNotNull(downloadUpdate.getProgress());
                Preconditions.checkNotNull(downloadUpdate.getContentId());
                Preconditions.checkArgument(downloadUpdate.getNotificationId() != -1);

                if (downloadUpdate.getIsDownloadPending()) {
                    contentText =
                            DownloadUtils.getPendingStatusString(downloadUpdate.getPendingState());
                } else {
                    // Incognito mode should hide download progress details like file size.
                    OfflineItem.Progress progress = downloadUpdate.getIsOffTheRecord()
                            ? OfflineItem.Progress.createIndeterminateProgress()
                            : downloadUpdate.getProgress();
                    contentText = DownloadUtils.getProgressTextForNotification(progress);
                }

                iconId = downloadUpdate.getIsDownloadPending()
                        ? R.drawable.ic_download_pending
                        : android.R.drawable.stat_sys_download;

                Intent pauseIntent = buildActionIntent(context, ACTION_DOWNLOAD_PAUSE,
                        downloadUpdate.getContentId(), downloadUpdate.getIsOffTheRecord());
                Intent cancelIntent = buildActionIntent(context, ACTION_DOWNLOAD_CANCEL,
                        downloadUpdate.getContentId(), downloadUpdate.getIsOffTheRecord());
                switch (downloadUpdate.getPendingState()) {
                    case PendingState.NOT_PENDING:
                        cancelIntent.putExtra(EXTRA_DOWNLOAD_STATE_AT_CANCEL,
                                DownloadNotificationUmaHelper.StateAtCancel.DOWNLOADING);
                        break;
                    case PendingState.PENDING_NETWORK:
                        cancelIntent.putExtra(EXTRA_DOWNLOAD_STATE_AT_CANCEL,
                                DownloadNotificationUmaHelper.StateAtCancel.PENDING_NETWORK);
                        break;
                    case PendingState.PENDING_ANOTHER_DOWNLOAD:
                        cancelIntent.putExtra(EXTRA_DOWNLOAD_STATE_AT_CANCEL,
                                DownloadNotificationUmaHelper.StateAtCancel
                                        .PENDING_ANOTHER_DOWNLOAD);
                        break;
                }

                builder.setOngoing(true)
                        .setPriorityBeforeO(NotificationCompat.PRIORITY_HIGH)
                        .setAutoCancel(false)
                        .addAction(R.drawable.ic_pause_white_24dp,
                                context.getResources().getString(
                                        R.string.download_notification_pause_button),
                                buildPendingIntentProvider(
                                        context, pauseIntent, downloadUpdate.getNotificationId()),
                                pauseActionType)
                        .addAction(R.drawable.btn_close_white,
                                context.getResources().getString(
                                        R.string.download_notification_cancel_button),
                                buildPendingIntentProvider(
                                        context, cancelIntent, downloadUpdate.getNotificationId()),
                                cancelActionType);

                if (!downloadUpdate.getIsOffTheRecord())
                    builder.setLargeIcon(downloadUpdate.getIcon());

                if (!downloadUpdate.getIsDownloadPending()) {
                    boolean indeterminate = downloadUpdate.getProgress().isIndeterminate();
                    builder.setProgress(100,
                            indeterminate ? -1 : downloadUpdate.getProgress().getPercentage(),
                            indeterminate);
                }

                if (!downloadUpdate.getProgress().isIndeterminate()
                        && !downloadUpdate.getIsOffTheRecord()
                        && downloadUpdate.getTimeRemainingInMillis() >= 0
                        && !LegacyHelpers.isLegacyOfflinePage(downloadUpdate.getContentId())) {
                    String subText = DownloadUtils.formatRemainingTime(
                            context, downloadUpdate.getTimeRemainingInMillis());
                    setSubText(builder, subText);
                }

                if (downloadUpdate.getStartTime() > 0) {
                    builder.setWhen(downloadUpdate.getStartTime());
                }

                break;
            case DownloadNotificationService.DownloadStatus.PAUSED:
                Preconditions.checkNotNull(downloadUpdate.getContentId());
                Preconditions.checkArgument(downloadUpdate.getNotificationId() != -1);

                contentText =
                        context.getResources().getString(R.string.download_notification_paused);
                iconId = R.drawable.ic_download_pause;

                Intent resumeIntent = buildActionIntent(context, ACTION_DOWNLOAD_RESUME,
                        downloadUpdate.getContentId(), downloadUpdate.getIsOffTheRecord());
                cancelIntent = buildActionIntent(context, ACTION_DOWNLOAD_CANCEL,
                        downloadUpdate.getContentId(), downloadUpdate.getIsOffTheRecord());
                cancelIntent.putExtra(EXTRA_DOWNLOAD_STATE_AT_CANCEL,
                        DownloadNotificationUmaHelper.StateAtCancel.PAUSED);

                builder.setAutoCancel(false)
                        .addAction(R.drawable.ic_file_download_white_24dp,
                                context.getResources().getString(
                                        R.string.download_notification_resume_button),
                                buildPendingIntentProvider(
                                        context, resumeIntent, downloadUpdate.getNotificationId()),
                                resumeActionType)
                        .addAction(R.drawable.btn_close_white,
                                context.getResources().getString(
                                        R.string.download_notification_cancel_button),
                                buildPendingIntentProvider(
                                        context, cancelIntent, downloadUpdate.getNotificationId()),
                                cancelActionType);

                if (!downloadUpdate.getIsOffTheRecord())
                    builder.setLargeIcon(downloadUpdate.getIcon());

                if (downloadUpdate.getIsTransient()) {
                    builder.setDeleteIntent(buildPendingIntentProvider(
                            context, cancelIntent, downloadUpdate.getNotificationId()));
                }

                break;
            case DownloadNotificationService.DownloadStatus.COMPLETED:
                Preconditions.checkArgument(downloadUpdate.getNotificationId() != -1);

                // Don't show file size in incognito mode.
                if (downloadUpdate.getTotalBytes() > 0 && !downloadUpdate.getIsOffTheRecord()) {
                    contentText = context.getResources().getString(
                            R.string.download_notification_completed_with_size,
                            DownloadUtils.getStringForBytes(
                                    context, downloadUpdate.getTotalBytes()));
                } else {
                    contentText = context.getResources().getString(
                            R.string.download_notification_completed);
                }

                iconId = R.drawable.offline_pin;

                if (downloadUpdate.getIsOpenable()) {
                    Intent intent;
                    if (LegacyHelpers.isLegacyDownload(downloadUpdate.getContentId())) {
                        Preconditions.checkNotNull(downloadUpdate.getContentId());
                        Preconditions.checkArgument(downloadUpdate.getSystemDownloadId() != -1);

                        intent = new Intent(ACTION_NOTIFICATION_CLICKED);
                        long[] idArray = {downloadUpdate.getSystemDownloadId()};
                        intent.putExtra(EXTRA_NOTIFICATION_CLICK_DOWNLOAD_IDS, idArray);
                        intent.putExtra(EXTRA_DOWNLOAD_FILE_PATH, downloadUpdate.getFilePath());
                        intent.putExtra(EXTRA_IS_SUPPORTED_MIME_TYPE,
                                downloadUpdate.getIsSupportedMimeType());
                        intent.putExtra(
                                EXTRA_IS_OFF_THE_RECORD, downloadUpdate.getIsOffTheRecord());
                        intent.putExtra(
                                EXTRA_DOWNLOAD_CONTENTID_ID, downloadUpdate.getContentId().id);
                        intent.putExtra(EXTRA_DOWNLOAD_CONTENTID_NAMESPACE,
                                downloadUpdate.getContentId().namespace);
                        intent.putExtra(NotificationConstants.EXTRA_NOTIFICATION_ID,
                                downloadUpdate.getNotificationId());
                        MediaViewerUtils.setOriginalUrlAndReferralExtraToIntent(intent,
                                downloadUpdate.getOriginalUrl(), downloadUpdate.getReferrer());
                    } else {
                        intent = buildActionIntent(context, ACTION_DOWNLOAD_OPEN,
                                downloadUpdate.getContentId(), false);
                    }

                    ComponentName component = new ComponentName(
                            context.getPackageName(), DownloadBroadcastManager.class.getName());
                    intent.setComponent(component);
                    builder.setContentIntent(PendingIntentProvider.getService(context,
                            downloadUpdate.getNotificationId(), intent,
                            PendingIntent.FLAG_UPDATE_CURRENT));
                }

                // It's the job of the service to ensure that the default icon is provided when
                // in incognito mode.
                if (downloadUpdate.getIcon() != null)
                    builder.setLargeIcon(downloadUpdate.getIcon());

                break;
            case DownloadNotificationService.DownloadStatus.FAILED:
                iconId = android.R.drawable.stat_sys_download_done;
                contentText = DownloadUtils.getFailStatusString(downloadUpdate.getFailState());
                break;
            default:
                iconId = -1;
                contentText = "";
                break;
        }

        Bundle extras = new Bundle();
        extras.putInt(EXTRA_NOTIFICATION_BUNDLE_ICON_ID, iconId);
        builder.setSmallIcon(iconId).addExtras(extras);

        // Context text is shown as title in incognito mode as the file name is not shown.
        if (downloadUpdate.getIsOffTheRecord()) {
            builder.setContentTitle(contentText);
        } else {
            builder.setContentText(contentText);
        }

        // Don't show file name in incognito mode.
        if (downloadUpdate.getFileName() != null && !downloadUpdate.getIsOffTheRecord()) {
            builder.setContentTitle(DownloadUtils.getAbbreviatedFileName(
                    downloadUpdate.getFileName(), MAX_FILE_NAME_LENGTH));
        }

        if (!downloadUpdate.getIsTransient() && downloadUpdate.getNotificationId() != -1
                && downloadStatus != DownloadNotificationService.DownloadStatus.COMPLETED
                && downloadStatus != DownloadNotificationService.DownloadStatus.FAILED) {
            Intent downloadHomeIntent = buildActionIntent(
                    context, ACTION_NOTIFICATION_CLICKED, null, downloadUpdate.getIsOffTheRecord());
            builder.setContentIntent(
                    PendingIntentProvider.getService(context, downloadUpdate.getNotificationId(),
                            downloadHomeIntent, PendingIntent.FLAG_UPDATE_CURRENT));
        }

        if (downloadUpdate.getIsOffTheRecord()) {
            // A sub text to inform the users that they are using incognito mode.
            setSubText(builder,
                    context.getResources().getString(
                            R.string.download_notification_incognito_subtext));
        } else if (downloadUpdate.getShouldPromoteOrigin()
                && !TextUtils.isEmpty(downloadUpdate.getOriginalUrl())) {
            // Always show the origin URL if available (for normal profiles).
            String formattedUrl = UrlFormatter.formatUrlForSecurityDisplayOmitScheme(
                    downloadUpdate.getOriginalUrl());

            if (formattedUrl.length() > MAX_ORIGIN_LENGTH) {
                // The origin is too long. Strip down to eTLD+1.
                formattedUrl = UrlUtilities.getDomainAndRegistry(
                        downloadUpdate.getOriginalUrl(), false /* includePrivateRegistries */);
            }
            setSubText(builder, formattedUrl);
        }

        return builder.build();
    }

    /**
     * Helper method to build a PendingIntent from the provided intent.
     * @param intent Intent to broadcast.
     * @param notificationId ID of the notification.
     */
    private static PendingIntentProvider buildPendingIntentProvider(
            Context context, Intent intent, int notificationId) {
        return PendingIntentProvider.getService(
                context, notificationId, intent, PendingIntent.FLAG_UPDATE_CURRENT);
    }

    /**
     * Helper method to set the sub text on different versions of Android.
     * @param builder The builder to build notification.
     * @param subText A string shown as sub text on the notification.
     */
    private static void setSubText(ChromeNotificationBuilder builder, String subText) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            builder.setSubText(subText);
        } else {
            builder.setContentInfo(subText);
        }
    }

    /**
     * Helper method to build an download action Intent from the provided information.
     * @param context {@link Context} to pull resources from.
     * @param action Download action to perform.
     * @param id The {@link ContentId} of the download.
     * @param isOffTheRecord Whether the download is incognito.
     */
    public static Intent buildActionIntent(
            Context context, String action, ContentId id, boolean isOffTheRecord) {
        ComponentName component = new ComponentName(
                context.getPackageName(), DownloadBroadcastManager.class.getName());
        Intent intent = new Intent(action);
        intent.setComponent(component);
        intent.putExtra(EXTRA_DOWNLOAD_CONTENTID_ID, id != null ? id.id : "");
        intent.putExtra(EXTRA_DOWNLOAD_CONTENTID_NAMESPACE, id != null ? id.namespace : "");
        intent.putExtra(EXTRA_IS_OFF_THE_RECORD, isOffTheRecord);
        return intent;
    }
}
