/*
 * Copyright (C) 2008 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 android.service.notification;

import static android.app.NotificationChannel.PLACEHOLDER_CONVERSATION_ID;

import android.annotation.NonNull;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.Person;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.metrics.LogMaker;
import android.os.Build;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.UserHandle;
import android.provider.Settings;
import android.text.TextUtils;

import com.android.internal.logging.InstanceId;
import com.android.internal.logging.nano.MetricsProto;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;

import java.util.ArrayList;

/**
 * Class encapsulating a Notification. Sent by the NotificationManagerService to clients including
 * the status bar and any {@link android.service.notification.NotificationListenerService}s.
 */
public class StatusBarNotification implements Parcelable {
    static final int MAX_LOG_TAG_LENGTH = 36;

    @UnsupportedAppUsage
    private final String pkg;
    @UnsupportedAppUsage
    private final int id;
    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
    private final String tag;
    private final String key;
    private String groupKey;
    private String overrideGroupKey;

    @UnsupportedAppUsage
    private final int uid;
    private final String opPkg;
    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
    private final int initialPid;
    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
    private final Notification notification;
    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
    private final UserHandle user;
    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
    private final long postTime;
    // A small per-notification ID, used for statsd logging.
    private InstanceId mInstanceId;  // Not final, see setInstanceId()

    private Context mContext; // used for inflation & icon expansion

    /** @hide */
    public StatusBarNotification(String pkg, String opPkg, int id,
            String tag, int uid, int initialPid, Notification notification, UserHandle user,
            String overrideGroupKey, long postTime) {
        if (pkg == null) throw new NullPointerException();
        if (notification == null) throw new NullPointerException();

        this.pkg = pkg;
        this.opPkg = opPkg;
        this.id = id;
        this.tag = tag;
        this.uid = uid;
        this.initialPid = initialPid;
        this.notification = notification;
        this.user = user;
        this.postTime = postTime;
        this.overrideGroupKey = overrideGroupKey;
        this.key = key();
        this.groupKey = groupKey();
    }

    /**
     * @deprecated Non-system apps should not need to create StatusBarNotifications.
     */
    @Deprecated
    public StatusBarNotification(String pkg, String opPkg, int id, String tag, int uid,
            int initialPid, int score, Notification notification, UserHandle user,
            long postTime) {
        if (pkg == null) throw new NullPointerException();
        if (notification == null) throw new NullPointerException();

        this.pkg = pkg;
        this.opPkg = opPkg;
        this.id = id;
        this.tag = tag;
        this.uid = uid;
        this.initialPid = initialPid;
        this.notification = notification;
        this.user = user;
        this.postTime = postTime;
        this.key = key();
        this.groupKey = groupKey();
    }

    public StatusBarNotification(Parcel in) {
        this.pkg = in.readString();
        this.opPkg = in.readString();
        this.id = in.readInt();
        if (in.readInt() != 0) {
            this.tag = in.readString();
        } else {
            this.tag = null;
        }
        this.uid = in.readInt();
        this.initialPid = in.readInt();
        this.notification = new Notification(in);
        this.user = UserHandle.readFromParcel(in);
        this.postTime = in.readLong();
        if (in.readInt() != 0) {
            this.overrideGroupKey = in.readString();
        }
        if (in.readInt() != 0) {
            this.mInstanceId = InstanceId.CREATOR.createFromParcel(in);
        }
        this.key = key();
        this.groupKey = groupKey();
    }

    private String key() {
        String sbnKey = user.getIdentifier() + "|" + pkg + "|" + id + "|" + tag + "|" + uid;
        if (overrideGroupKey != null && getNotification().isGroupSummary()) {
            sbnKey = sbnKey + "|" + overrideGroupKey;
        }
        return sbnKey;
    }

    private String groupKey() {
        if (overrideGroupKey != null) {
            return user.getIdentifier() + "|" + pkg + "|" + "g:" + overrideGroupKey;
        }
        final String group = getNotification().getGroup();
        final String sortKey = getNotification().getSortKey();
        if (group == null && sortKey == null) {
            // a group of one
            return key;
        }
        return user.getIdentifier() + "|" + pkg + "|" +
                (group == null
                        ? "c:" + notification.getChannelId()
                        : "g:" + group);
    }

    /**
     * Returns true if this notification is part of a group.
     */
    public boolean isGroup() {
        if (overrideGroupKey != null || isAppGroup()) {
            return true;
        }
        return false;
    }

    /**
     * Returns true if application asked that this notification be part of a group.
     */
    public boolean isAppGroup() {
        if (getNotification().getGroup() != null || getNotification().getSortKey() != null) {
            return true;
        }
        return false;
    }

    public void writeToParcel(Parcel out, int flags) {
        out.writeString(this.pkg);
        out.writeString(this.opPkg);
        out.writeInt(this.id);
        if (this.tag != null) {
            out.writeInt(1);
            out.writeString(this.tag);
        } else {
            out.writeInt(0);
        }
        out.writeInt(this.uid);
        out.writeInt(this.initialPid);
        this.notification.writeToParcel(out, flags);
        user.writeToParcel(out, flags);
        out.writeLong(this.postTime);
        if (this.overrideGroupKey != null) {
            out.writeInt(1);
            out.writeString(this.overrideGroupKey);
        } else {
            out.writeInt(0);
        }
        if (this.mInstanceId != null) {
            out.writeInt(1);
            mInstanceId.writeToParcel(out, flags);
        } else {
            out.writeInt(0);
        }
    }

    public int describeContents() {
        return 0;
    }

    public static final @android.annotation.NonNull
            Parcelable.Creator<StatusBarNotification> CREATOR =
            new Parcelable.Creator<StatusBarNotification>() {
                public StatusBarNotification createFromParcel(Parcel parcel) {
                    return new StatusBarNotification(parcel);
                }

            public StatusBarNotification[] newArray(int size) {
                return new StatusBarNotification[size];
            }
    };

    /**
     * @hide
     */
    public StatusBarNotification cloneLight() {
        final Notification no = new Notification();
        this.notification.cloneInto(no, false); // light copy
        return cloneShallow(no);
    }

    @Override
    public StatusBarNotification clone() {
        return cloneShallow(this.notification.clone());
    }

    /**
     * @param notification Some kind of clone of this.notification.
     * @return A shallow copy of self, with notification in place of this.notification.
     */
    StatusBarNotification cloneShallow(Notification notification) {
        StatusBarNotification result = new StatusBarNotification(this.pkg, this.opPkg,
                this.id, this.tag, this.uid, this.initialPid,
                notification, this.user, this.overrideGroupKey, this.postTime);
        result.setInstanceId(this.mInstanceId);
        return result;
    }

    @Override
    public String toString() {
        return String.format(
                "StatusBarNotification(pkg=%s user=%s id=%d tag=%s key=%s: %s)",
                this.pkg, this.user, this.id, this.tag,
                this.key, this.notification);
    }

    /**
     * Convenience method to check the notification's flags for
     * {@link Notification#FLAG_ONGOING_EVENT}.
     */
    public boolean isOngoing() {
        return (notification.flags & Notification.FLAG_ONGOING_EVENT) != 0;
    }

    /**
     * Convenience method to check the notification's flags for
     * either {@link Notification#FLAG_ONGOING_EVENT} or
     * {@link Notification#FLAG_NO_CLEAR}.
     */
    public boolean isClearable() {
        return ((notification.flags & Notification.FLAG_ONGOING_EVENT) == 0)
                && ((notification.flags & Notification.FLAG_NO_CLEAR) == 0);
    }

    /**
     * Returns a userid for whom this notification is intended.
     *
     * @deprecated Use {@link #getUser()} instead.
     */
    @Deprecated
    public int getUserId() {
        return this.user.getIdentifier();
    }

    /**
     * Like {@link #getUserId()} but handles special users.
     * @hide
     */
    public int getNormalizedUserId() {
        int userId = getUserId();
        if (userId == UserHandle.USER_ALL) {
            userId = UserHandle.USER_SYSTEM;
        }
        return userId;
    }

    /** The package that the notification belongs to. */
    public String getPackageName() {
        return pkg;
    }

    /** The id supplied to {@link android.app.NotificationManager#notify(int, Notification)}. */
    public int getId() {
        return id;
    }

    /**
     * The tag supplied to {@link android.app.NotificationManager#notify(int, Notification)},
     * or null if no tag was specified.
     */
    public String getTag() {
        return tag;
    }

    /**
     * The notifying app's ({@link #getPackageName()}'s) uid.
     */
    public int getUid() {
        return uid;
    }

    /**
     * The package that posted the notification.
     * <p> Might be different from {@link #getPackageName()} if the app owning the notification has
     * a {@link NotificationManager#setNotificationDelegate(String) notification delegate}.
     */
    public @NonNull String getOpPkg() {
        return opPkg;
    }

    /** @hide */
    @UnsupportedAppUsage
    public int getInitialPid() {
        return initialPid;
    }

    /**
     * The {@link android.app.Notification} supplied to
     * {@link android.app.NotificationManager#notify(int, Notification)}.
     */
    public Notification getNotification() {
        return notification;
    }

    /**
     * The {@link android.os.UserHandle} for whom this notification is intended.
     */
    public UserHandle getUser() {
        return user;
    }

    /**
     * The time (in {@link System#currentTimeMillis} time) the notification was posted,
     * which may be different than {@link android.app.Notification#when}.
     */
    public long getPostTime() {
        return postTime;
    }

    /**
     * A unique instance key for this notification record.
     */
    public String getKey() {
        return key;
    }

    /**
     * A key that indicates the group with which this message ranks.
     */
    public String getGroupKey() {
        return groupKey;
    }

    /**
     * The ID passed to setGroup(), or the override, or null.
     *
     * @hide
     */
    public String getGroup() {
        if (overrideGroupKey != null) {
            return overrideGroupKey;
        }
        return getNotification().getGroup();
    }

    /**
     * Sets the override group key.
     */
    public void setOverrideGroupKey(String overrideGroupKey) {
        this.overrideGroupKey = overrideGroupKey;
        groupKey = groupKey();
    }

    /**
     * Returns the override group key.
     */
    public String getOverrideGroupKey() {
        return overrideGroupKey;
    }

    /**
     * @hide
     */
    public void clearPackageContext() {
        mContext = null;
    }

    /**
     * @hide
     */
    public InstanceId getInstanceId() {
        return mInstanceId;
    }

    /**
     * @hide
     */
    public void setInstanceId(InstanceId instanceId) {
        mInstanceId = instanceId;
    }

    /**
     * @hide
     */
    @UnsupportedAppUsage
    public Context getPackageContext(Context context) {
        if (mContext == null) {
            try {
                ApplicationInfo ai = context.getPackageManager()
                        .getApplicationInfoAsUser(pkg, PackageManager.MATCH_UNINSTALLED_PACKAGES,
                                getUserId());
                mContext = context.createApplicationContext(ai,
                        Context.CONTEXT_RESTRICTED);
            } catch (PackageManager.NameNotFoundException e) {
                mContext = null;
            }
        }
        if (mContext == null) {
            mContext = context;
        }
        return mContext;
    }

    /**
     * Returns a LogMaker that contains all basic information of the notification.
     *
     * @hide
     */
    public LogMaker getLogMaker() {
        LogMaker logMaker = new LogMaker(MetricsEvent.VIEW_UNKNOWN).setPackageName(getPackageName())
                .addTaggedData(MetricsEvent.NOTIFICATION_ID, getId())
                .addTaggedData(MetricsEvent.NOTIFICATION_TAG, getTag())
                .addTaggedData(MetricsEvent.FIELD_NOTIFICATION_CHANNEL_ID, getChannelIdLogTag())
                .addTaggedData(MetricsEvent.FIELD_NOTIFICATION_GROUP_ID, getGroupLogTag())
                .addTaggedData(MetricsEvent.FIELD_NOTIFICATION_GROUP_SUMMARY,
                        getNotification().isGroupSummary() ? 1 : 0)
                .addTaggedData(MetricsProto.MetricsEvent.FIELD_NOTIFICATION_CATEGORY,
                        getNotification().category);
        if (getNotification().extras != null) {
            // Log the style used, if present.  We only log the hash here, as notification log
            // events are frequent, while there are few styles (hence low chance of collisions).
            String template = getNotification().extras.getString(Notification.EXTRA_TEMPLATE);
            if (template != null && !template.isEmpty()) {
                logMaker.addTaggedData(MetricsEvent.FIELD_NOTIFICATION_STYLE,
                        template.hashCode());
            }
            ArrayList<Person> people = getNotification().extras.getParcelableArrayList(
                    Notification.EXTRA_PEOPLE_LIST);
            if (people != null && !people.isEmpty()) {
                logMaker.addTaggedData(MetricsEvent.FIELD_NOTIFICATION_PEOPLE, people.size());
            }
        }
        return logMaker;
    }

    /**
     * @hide
     */
    public String getShortcutId(Context context) {
        String conversationId = getNotification().getShortcutId();
        if (TextUtils.isEmpty(conversationId)
                && (Settings.Global.getInt(context.getContentResolver(),
                Settings.Global.REQUIRE_SHORTCUTS_FOR_CONVERSATIONS, 0) == 0)
                && getNotification().getNotificationStyle() == Notification.MessagingStyle.class) {
            conversationId = getId() + getTag() + PLACEHOLDER_CONVERSATION_ID;
        }
        return conversationId;
    }

    /**
     *  Returns a probably-unique string based on the notification's group name,
     *  with no more than MAX_LOG_TAG_LENGTH characters.
     * @return String based on group name of notification.
     * @hide
     */
    public String getGroupLogTag() {
        return shortenTag(getGroup());
    }

    /**
     *  Returns a probably-unique string based on the notification's channel ID,
     *  with no more than MAX_LOG_TAG_LENGTH characters.
     * @return String based on channel ID of notification.
     * @hide
     */
    public String getChannelIdLogTag() {
        if (notification.getChannelId() == null) {
            return null;
        }
        return shortenTag(notification.getChannelId());
    }

    // Make logTag with max size MAX_LOG_TAG_LENGTH.
    // For shorter or equal tags, returns the tag.
    // For longer tags, truncate the tag and append a hash of the full tag to
    // fill the maximum size.
    private String shortenTag(String logTag) {
        if (logTag == null || logTag.length() <= MAX_LOG_TAG_LENGTH) {
            return logTag;
        }
        String hash = Integer.toHexString(logTag.hashCode());
        return logTag.substring(0, MAX_LOG_TAG_LENGTH - hash.length() - 1) + "-"
                + hash;
    }
}
