/*
 * Copyright (C) 2015 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.systemui.statusbar.phone;

import android.app.Notification;
import android.service.notification.StatusBarNotification;

import com.android.systemui.statusbar.ExpandableNotificationRow;
import com.android.systemui.statusbar.NotificationData;
import com.android.systemui.statusbar.StatusBarState;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

/**
 * A class to handle notifications and their corresponding groups.
 */
public class NotificationGroupManager {

    private final HashMap<String, NotificationGroup> mGroupMap = new HashMap<>();
    private OnGroupChangeListener mListener;
    private int mBarState = -1;

    public void setOnGroupChangeListener(OnGroupChangeListener listener) {
        mListener = listener;
    }

    public boolean isGroupExpanded(StatusBarNotification sbn) {
        NotificationGroup group = mGroupMap.get(sbn.getGroupKey());
        if (group == null) {
            return false;
        }
        return group.expanded;
    }

    public void setGroupExpanded(StatusBarNotification sbn, boolean expanded) {
        NotificationGroup group = mGroupMap.get(sbn.getGroupKey());
        if (group == null) {
            return;
        }
        setGroupExpanded(group, expanded);
    }

    private void setGroupExpanded(NotificationGroup group, boolean expanded) {
        group.expanded = expanded;
        if (group.summary != null) {
            mListener.onGroupExpansionChanged(group.summary.row, expanded);
        }
    }

    public void onEntryRemoved(NotificationData.Entry removed) {
        onEntryRemovedInternal(removed, removed.notification);
    }

    /**
     * An entry was removed.
     *
     * @param removed the removed entry
     * @param sbn the notification the entry has, which doesn't need to be the same as it's internal
     *            notification
     */
    private void onEntryRemovedInternal(NotificationData.Entry removed,
            final StatusBarNotification sbn) {
        Notification notif = sbn.getNotification();
        String groupKey = sbn.getGroupKey();
        final NotificationGroup group = mGroupMap.get(groupKey);
        if (notif.isGroupSummary()) {
            group.summary = null;
        } else {
            group.children.remove(removed);
        }
        if (group.children.isEmpty()) {
            if (group.summary == null) {
                mGroupMap.remove(groupKey);
            } else {
                if (group.expanded) {
                    // only the summary is left. Change it to unexpanded in a few ms. We do this to
                    // avoid raceconditions
                    removed.row.post(new Runnable() {
                        @Override
                        public void run() {
                            if (group.children.isEmpty()) {
                                setGroupExpanded(sbn, false);
                            }
                        }
                    });
                } else {
                    group.summary.row.updateExpandButton();
                }
            }
        }
    }

    public void onEntryAdded(NotificationData.Entry added) {
        StatusBarNotification sbn = added.notification;
        Notification notif = sbn.getNotification();
        String groupKey = sbn.getGroupKey();
        NotificationGroup group = mGroupMap.get(groupKey);
        if (group == null) {
            group = new NotificationGroup();
            mGroupMap.put(groupKey, group);
        }
        if (notif.isGroupSummary()) {
            group.summary = added;
            group.expanded = added.row.areChildrenExpanded();
            if (!group.children.isEmpty()) {
                mListener.onGroupCreatedFromChildren(group);
            }
        } else {
            group.children.add(added);
            if (group.summary != null && group.children.size() == 1 && !group.expanded) {
                group.summary.row.updateExpandButton();
            }
        }
    }

    public void onEntryUpdated(NotificationData.Entry entry,
            StatusBarNotification oldNotification) {
        if (mGroupMap.get(oldNotification.getGroupKey()) != null) {
            onEntryRemovedInternal(entry, oldNotification);
        }
        onEntryAdded(entry);
    }

    public boolean isVisible(StatusBarNotification sbn) {
        if (!sbn.getNotification().isGroupChild()) {
            return true;
        }
        NotificationGroup group = mGroupMap.get(sbn.getGroupKey());
        if (group != null && group.expanded) {
            return true;
        }
        return false;
    }

    public boolean hasGroupChildren(StatusBarNotification sbn) {
        if (areGroupsProhibited()) {
            return false;
        }
        if (!sbn.getNotification().isGroupSummary()) {
            return false;
        }
        NotificationGroup group = mGroupMap.get(sbn.getGroupKey());
        if (group == null) {
            return false;
        }
        return !group.children.isEmpty();
    }

    public void setStatusBarState(int newState) {
        if (mBarState == newState) {
            return;
        }
        boolean prohibitedBefore = areGroupsProhibited();
        mBarState = newState;
        boolean nowProhibited = areGroupsProhibited();
        if (nowProhibited != prohibitedBefore) {
            if (nowProhibited) {
                for (NotificationGroup group : mGroupMap.values()) {
                    if (group.expanded) {
                        setGroupExpanded(group, false);
                    }
                }
            }
            mListener.onGroupsProhibitedChanged();
        }
    }

    private boolean areGroupsProhibited() {
        return mBarState == StatusBarState.KEYGUARD;
    }

    /**
     * @return whether a given notification is a child in a group which has a summary
     */
    public boolean isChildInGroupWithSummary(StatusBarNotification sbn) {
        if (!sbn.getNotification().isGroupChild()) {
            return false;
        }
        NotificationGroup group = mGroupMap.get(sbn.getGroupKey());
        if (group == null || group.summary == null) {
            return false;
        }
        return true;
    }

    public ExpandableNotificationRow getGroupSummary(StatusBarNotification sbn) {
        NotificationGroup group = mGroupMap.get(sbn.getGroupKey());
        return group == null ? null
                : group.summary == null ? null
                : group.summary.row;
    }

    public static class NotificationGroup {
        public final HashSet<NotificationData.Entry> children = new HashSet<>();
        public NotificationData.Entry summary;
        public boolean expanded;
    }

    public interface OnGroupChangeListener {
        /**
         * The expansion of a group has changed.
         *
         * @param changedRow the row for which the expansion has changed, which is also the summary
         * @param expanded a boolean indicating the new expanded state
         */
        void onGroupExpansionChanged(ExpandableNotificationRow changedRow, boolean expanded);

        /**
         * Children group policy has changed and children may no be prohibited or allowed.
         */
        void onGroupsProhibitedChanged();

        /**
         * A group of children just received a summary notification and should therefore become
         * children of it.
         *
         * @param group the group created
         */
        void onGroupCreatedFromChildren(NotificationGroup group);
    }
}
