/*
 * 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();
    }

    /** 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;
    }
}
