/*
 * 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 android.app;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.UserIdInt;
import android.graphics.drawable.Icon;
import android.os.Parcel;
import android.os.Parcelable;
import android.text.TextUtils;
import android.util.Slog;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;
import java.util.Set;

/**
 * @hide
 */
public final class NotificationHistory implements Parcelable {

    /**
     * A historical notification. Any new fields added here should also be added to
     * {@link #readNotificationFromParcel} and
     * {@link #writeNotificationToParcel(HistoricalNotification, Parcel, int)}.
     */
    public static final class HistoricalNotification {
        private String mPackage;
        private String mChannelName;
        private String mChannelId;
        private int mUid;
        private @UserIdInt int mUserId;
        private long mPostedTimeMs;
        private String mTitle;
        private String mText;
        private Icon mIcon;
        private String mConversationId;

        private HistoricalNotification() {}

        public String getPackage() {
            return mPackage;
        }

        public String getChannelName() {
            return mChannelName;
        }

        public String getChannelId() {
            return mChannelId;
        }

        public int getUid() {
            return mUid;
        }

        public int getUserId() {
            return mUserId;
        }

        public long getPostedTimeMs() {
            return mPostedTimeMs;
        }

        public String getTitle() {
            return mTitle;
        }

        public String getText() {
            return mText;
        }

        public Icon getIcon() {
            return mIcon;
        }

        public String getKey() {
            return mPackage + "|" + mUid + "|" + mPostedTimeMs;
        }

        public String getConversationId() {
            return mConversationId;
        }

        @Override
        public String toString() {
            return "HistoricalNotification{" +
                    "key='" + getKey() + '\'' +
                    ", mChannelName='" + mChannelName + '\'' +
                    ", mChannelId='" + mChannelId + '\'' +
                    ", mUserId=" + mUserId +
                    ", mUid=" + mUid +
                    ", mTitle='" + mTitle + '\'' +
                    ", mText='" + mText + '\'' +
                    ", mIcon=" + mIcon +
                    ", mPostedTimeMs=" + mPostedTimeMs +
                    ", mConversationId=" + mConversationId +
                    '}';
        }

        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;
            HistoricalNotification that = (HistoricalNotification) o;
            boolean iconsAreSame = getIcon() == null && that.getIcon() == null
                    || (getIcon() != null && that.getIcon() != null
                    && getIcon().sameAs(that.getIcon()));
            return getUid() == that.getUid() &&
                    getUserId() == that.getUserId() &&
                    getPostedTimeMs() == that.getPostedTimeMs() &&
                    Objects.equals(getPackage(), that.getPackage()) &&
                    Objects.equals(getChannelName(), that.getChannelName()) &&
                    Objects.equals(getChannelId(), that.getChannelId()) &&
                    Objects.equals(getTitle(), that.getTitle()) &&
                    Objects.equals(getText(), that.getText()) &&
                    Objects.equals(getConversationId(), that.getConversationId()) &&
                    iconsAreSame;
        }

        @Override
        public int hashCode() {
            return Objects.hash(getPackage(), getChannelName(), getChannelId(), getUid(),
                    getUserId(),
                    getPostedTimeMs(), getTitle(), getText(), getIcon(), getConversationId());
        }

        public static final class Builder {
            private String mPackage;
            private String mChannelName;
            private String mChannelId;
            private int mUid;
            private @UserIdInt int mUserId;
            private long mPostedTimeMs;
            private String mTitle;
            private String mText;
            private Icon mIcon;
            private String mConversationId;

            public Builder() {}

            public Builder setPackage(String aPackage) {
                mPackage = aPackage;
                return this;
            }

            public Builder setChannelName(String channelName) {
                mChannelName = channelName;
                return this;
            }

            public Builder setChannelId(String channelId) {
                mChannelId = channelId;
                return this;
            }

            public Builder setUid(int uid) {
                mUid = uid;
                return this;
            }

            public Builder setUserId(int userId) {
                mUserId = userId;
                return this;
            }

            public Builder setPostedTimeMs(long postedTimeMs) {
                mPostedTimeMs = postedTimeMs;
                return this;
            }

            public Builder setTitle(String title) {
                mTitle = title;
                return this;
            }

            public Builder setText(String text) {
                mText = text;
                return this;
            }

            public Builder setIcon(Icon icon) {
                mIcon = icon;
                return this;
            }

            public Builder setConversationId(String conversationId) {
                mConversationId = conversationId;
                return this;
            }

            public HistoricalNotification build() {
                HistoricalNotification n = new HistoricalNotification();
                n.mPackage = mPackage;
                n.mChannelName = mChannelName;
                n.mChannelId = mChannelId;
                n.mUid = mUid;
                n.mUserId = mUserId;
                n.mPostedTimeMs = mPostedTimeMs;
                n.mTitle = mTitle;
                n.mText = mText;
                n.mIcon = mIcon;
                n.mConversationId = mConversationId;
                return n;
            }
        }
    }

    // Only used when creating the resulting history. Not used for reading/unparceling.
    private List<HistoricalNotification> mNotificationsToWrite = new ArrayList<>();
    // ditto
    private Set<String> mStringsToWrite = new HashSet<>();

    // Mostly used for reading/unparceling events.
    private Parcel mParcel = null;
    private int mHistoryCount;
    private int mIndex = 0;

    // Sorted array of commonly used strings to shrink the size of the parcel. populated from
    // mStringsToWrite on write and the parcel on read.
    private String[] mStringPool;

    /**
     * Construct the iterator from a parcel.
     */
    private NotificationHistory(Parcel in) {
        byte[] bytes = in.readBlob();
        Parcel data = Parcel.obtain();
        data.unmarshall(bytes, 0, bytes.length);
        data.setDataPosition(0);
        mHistoryCount = data.readInt();
        mIndex = data.readInt();
        if (mHistoryCount > 0) {
            mStringPool = data.createStringArray();

            final int listByteLength = data.readInt();
            final int positionInParcel = data.readInt();
            mParcel = Parcel.obtain();
            mParcel.setDataPosition(0);
            mParcel.appendFrom(data, data.dataPosition(), listByteLength);
            mParcel.setDataSize(mParcel.dataPosition());
            mParcel.setDataPosition(positionInParcel);
        }
    }

    /**
     * Create an empty iterator.
     */
    public NotificationHistory() {
        mHistoryCount = 0;
    }

    /**
     * Returns whether or not there are more events to read using {@link #getNextNotification()}.
     *
     * @return true if there are more events, false otherwise.
     */
    public boolean hasNextNotification() {
        return mIndex < mHistoryCount;
    }

    /**
     * Retrieve the next {@link HistoricalNotification} from the collection and put the
     * resulting data into {@code notificationOut}.
     *
     * @return The next {@link HistoricalNotification} or null if there are no more notifications.
     */
    public @Nullable HistoricalNotification getNextNotification() {
        if (!hasNextNotification()) {
            return null;
        }
        HistoricalNotification n = readNotificationFromParcel(mParcel);
        mIndex++;
        if (!hasNextNotification()) {
            mParcel.recycle();
            mParcel = null;
        }
        return n;
    }

    /**
     * Adds all of the pooled strings that have been read from disk
     */
    public void addPooledStrings(@NonNull List<String> strings) {
        mStringsToWrite.addAll(strings);
    }

    /**
     * Builds the pooled strings from pending notifications. Useful if the pooled strings on
     * disk contains strings that aren't relevant to the notifications in our collection.
     */
    public void poolStringsFromNotifications() {
        mStringsToWrite.clear();
        for (int i = 0; i < mNotificationsToWrite.size(); i++) {
            final HistoricalNotification notification = mNotificationsToWrite.get(i);
            mStringsToWrite.add(notification.getPackage());
            mStringsToWrite.add(notification.getChannelName());
            mStringsToWrite.add(notification.getChannelId());
            if (!TextUtils.isEmpty(notification.getConversationId())) {
                mStringsToWrite.add(notification.getConversationId());
            }
        }
    }

    /**
     * Used when populating a history from disk; adds an historical notification.
     */
    public void addNotificationToWrite(@NonNull HistoricalNotification notification) {
        if (notification == null) {
            return;
        }
        mNotificationsToWrite.add(notification);
        mHistoryCount++;
    }

    /**
     * Used when populating a history from disk; adds an historical notification.
     */
    public void addNewNotificationToWrite(@NonNull HistoricalNotification notification) {
        if (notification == null) {
            return;
        }
        mNotificationsToWrite.add(0, notification);
        mHistoryCount++;
    }

    public void addNotificationsToWrite(@NonNull NotificationHistory notificationHistory) {
        for (HistoricalNotification hn : notificationHistory.getNotificationsToWrite()) {
            addNotificationToWrite(hn);
        }
        Collections.sort(mNotificationsToWrite,
                (o1, o2) -> -1 * Long.compare(o1.getPostedTimeMs(), o2.getPostedTimeMs()));
        poolStringsFromNotifications();
    }

    /**
     * Removes a package's historical notifications and regenerates the string pool
     */
    public void removeNotificationsFromWrite(String packageName) {
        for (int i = mNotificationsToWrite.size() - 1; i >= 0; i--) {
            if (packageName.equals(mNotificationsToWrite.get(i).getPackage())) {
                mNotificationsToWrite.remove(i);
            }
        }
        poolStringsFromNotifications();
    }

    /**
     * Removes an individual historical notification and regenerates the string pool
     */
    public boolean removeNotificationFromWrite(String packageName, long postedTime) {
        boolean removed = false;
        for (int i = mNotificationsToWrite.size() - 1; i >= 0; i--) {
            HistoricalNotification hn = mNotificationsToWrite.get(i);
            if (packageName.equals(hn.getPackage())
                    && postedTime == hn.getPostedTimeMs()) {
                removed = true;
                mNotificationsToWrite.remove(i);
            }
        }
        if (removed) {
            poolStringsFromNotifications();
        }

        return removed;
    }

    /**
     * Removes all notifications from a conversation and regenerates the string pool
     */
    public boolean removeConversationFromWrite(String packageName, String conversationId) {
        boolean removed = false;
        for (int i = mNotificationsToWrite.size() - 1; i >= 0; i--) {
            HistoricalNotification hn = mNotificationsToWrite.get(i);
            if (packageName.equals(hn.getPackage())
                    && conversationId.equals(hn.getConversationId())) {
                removed = true;
                mNotificationsToWrite.remove(i);
            }
        }
        if (removed) {
            poolStringsFromNotifications();
        }

        return removed;
    }

    /**
     * Gets pooled strings in order to write them to disk
     */
    public @NonNull String[] getPooledStringsToWrite() {
        String[] stringsToWrite = mStringsToWrite.toArray(new String[]{});
        Arrays.sort(stringsToWrite);
        return stringsToWrite;
    }

    /**
     * Gets the historical notifications in order to write them to disk
     */
    public @NonNull List<HistoricalNotification> getNotificationsToWrite() {
        return mNotificationsToWrite;
    }

    /**
     * Gets the number of notifications in the collection
     */
    public int getHistoryCount() {
        return mHistoryCount;
    }

    private int findStringIndex(String str) {
        final int index = Arrays.binarySearch(mStringPool, str);
        if (index < 0) {
            throw new IllegalStateException("String '" + str + "' is not in the string pool");
        }
        return index;
    }

    /**
     * Writes a single notification to the parcel. Modify this when updating member variables of
     * {@link HistoricalNotification}.
     */
    private void writeNotificationToParcel(HistoricalNotification notification, Parcel p,
            int flags) {
        final int packageIndex;
        if (notification.mPackage != null) {
            packageIndex = findStringIndex(notification.mPackage);
        } else {
            packageIndex = -1;
        }

        final int channelNameIndex;
        if (notification.getChannelName() != null) {
            channelNameIndex = findStringIndex(notification.getChannelName());
        } else {
            channelNameIndex = -1;
        }

        final int channelIdIndex;
        if (notification.getChannelId() != null) {
            channelIdIndex = findStringIndex(notification.getChannelId());
        } else {
            channelIdIndex = -1;
        }

        final int conversationIdIndex;
        if (!TextUtils.isEmpty(notification.getConversationId())) {
            conversationIdIndex = findStringIndex(notification.getConversationId());
        } else {
            conversationIdIndex = -1;
        }

        p.writeInt(packageIndex);
        p.writeInt(channelNameIndex);
        p.writeInt(channelIdIndex);
        p.writeInt(conversationIdIndex);
        p.writeInt(notification.getUid());
        p.writeInt(notification.getUserId());
        p.writeLong(notification.getPostedTimeMs());
        p.writeString(notification.getTitle());
        p.writeString(notification.getText());
        notification.getIcon().writeToParcel(p, flags);
    }

    /**
     * Reads a single notification from the parcel. Modify this when updating member variables of
     * {@link HistoricalNotification}.
     */
    private HistoricalNotification readNotificationFromParcel(Parcel p) {
        HistoricalNotification.Builder notificationOut = new HistoricalNotification.Builder();
        final int packageIndex = p.readInt();
        if (packageIndex >= 0) {
            notificationOut.mPackage = mStringPool[packageIndex];
        } else {
            notificationOut.mPackage = null;
        }

        final int channelNameIndex = p.readInt();
        if (channelNameIndex >= 0) {
            notificationOut.setChannelName(mStringPool[channelNameIndex]);
        } else {
            notificationOut.setChannelName(null);
        }

        final int channelIdIndex = p.readInt();
        if (channelIdIndex >= 0) {
            notificationOut.setChannelId(mStringPool[channelIdIndex]);
        } else {
            notificationOut.setChannelId(null);
        }

        final int conversationIdIndex = p.readInt();
        if (conversationIdIndex >= 0) {
            notificationOut.setConversationId(mStringPool[conversationIdIndex]);
        } else {
            notificationOut.setConversationId(null);
        }

        notificationOut.setUid(p.readInt());
        notificationOut.setUserId(p.readInt());
        notificationOut.setPostedTimeMs(p.readLong());
        notificationOut.setTitle(p.readString());
        notificationOut.setText(p.readString());
        notificationOut.setIcon(Icon.CREATOR.createFromParcel(p));

        return notificationOut.build();
    }

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        Parcel data = Parcel.obtain();
        data.writeInt(mHistoryCount);
        data.writeInt(mIndex);
        if (mHistoryCount > 0) {
            mStringPool = getPooledStringsToWrite();
            data.writeStringArray(mStringPool);

            if (!mNotificationsToWrite.isEmpty()) {
                // typically system_server to a process

                // Write out the events
                Parcel p = Parcel.obtain();
                try {
                    p.setDataPosition(0);
                    for (int i = 0; i < mHistoryCount; i++) {
                        final HistoricalNotification notification = mNotificationsToWrite.get(i);
                        writeNotificationToParcel(notification, p, flags);
                    }

                    final int listByteLength = p.dataPosition();

                    // Write the total length of the data.
                    data.writeInt(listByteLength);

                    // Write our current position into the data.
                    data.writeInt(0);

                    // Write the data.
                    data.appendFrom(p, 0, listByteLength);
                } finally {
                    p.recycle();
                }

            } else if (mParcel != null) {
                // typically process to process as mNotificationsToWrite is not populated on
                // unparcel.

                // Write the total length of the data.
                data.writeInt(mParcel.dataSize());

                // Write out current position into the data.
                data.writeInt(mParcel.dataPosition());

                // Write the data.
                data.appendFrom(mParcel, 0, mParcel.dataSize());
            } else {
                throw new IllegalStateException(
                        "Either mParcel or mNotificationsToWrite must not be null");
            }
        }
        // Data can be too large for a transact. Write the data as a Blob, which will be written to
        // ashmem if too large.
        dest.writeBlob(data.marshall());
    }

    public static final @NonNull Creator<NotificationHistory> CREATOR
            = new Creator<NotificationHistory>() {
        @Override
        public NotificationHistory createFromParcel(Parcel source) {
            return new NotificationHistory(source);
        }

        @Override
        public NotificationHistory[] newArray(int size) {
            return new NotificationHistory[size];
        }
    };
}
