/*
 * Copyright (C) 2018 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 android.annotation.IntDef;
import android.annotation.NonNull;
import android.app.Notification;
import android.app.NotificationChannel;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.proto.ProtoOutputStream;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Objects;

/**
 * ZenPolicy determines whether to allow certain notifications and their corresponding sounds to
 * play when a device is in Do Not Disturb mode.
 * ZenPolicy also dictates the visual effects of notifications that are intercepted when
 * a device is in Do Not Disturb mode.
 */
public final class ZenPolicy implements Parcelable {
    private ArrayList<Integer> mPriorityCategories;
    private ArrayList<Integer> mVisualEffects;
    private @PeopleType int mPriorityMessages = PEOPLE_TYPE_UNSET;
    private @PeopleType int mPriorityCalls = PEOPLE_TYPE_UNSET;
    private @ConversationSenders int mConversationSenders = CONVERSATION_SENDERS_UNSET;

    /** @hide */
    @IntDef(prefix = { "PRIORITY_CATEGORY_" }, value = {
            PRIORITY_CATEGORY_REMINDERS,
            PRIORITY_CATEGORY_EVENTS,
            PRIORITY_CATEGORY_MESSAGES,
            PRIORITY_CATEGORY_CALLS,
            PRIORITY_CATEGORY_REPEAT_CALLERS,
            PRIORITY_CATEGORY_ALARMS,
            PRIORITY_CATEGORY_MEDIA,
            PRIORITY_CATEGORY_SYSTEM,
            PRIORITY_CATEGORY_CONVERSATIONS,
    })
    @Retention(RetentionPolicy.SOURCE)
    public @interface PriorityCategory {}

    /** @hide */
    public static final int PRIORITY_CATEGORY_REMINDERS = 0;
    /** @hide */
    public static final int PRIORITY_CATEGORY_EVENTS = 1;
    /** @hide */
    public static final int PRIORITY_CATEGORY_MESSAGES = 2;
    /** @hide */
    public static final int PRIORITY_CATEGORY_CALLS = 3;
    /** @hide */
    public static final int PRIORITY_CATEGORY_REPEAT_CALLERS = 4;
    /** @hide */
    public static final int PRIORITY_CATEGORY_ALARMS = 5;
    /** @hide */
    public static final int PRIORITY_CATEGORY_MEDIA = 6;
    /** @hide */
    public static final int PRIORITY_CATEGORY_SYSTEM = 7;
    /** @hide */
    public static final int PRIORITY_CATEGORY_CONVERSATIONS = 8;

    /** @hide */
    @IntDef(prefix = { "VISUAL_EFFECT_" }, value = {
            VISUAL_EFFECT_FULL_SCREEN_INTENT,
            VISUAL_EFFECT_LIGHTS,
            VISUAL_EFFECT_PEEK,
            VISUAL_EFFECT_STATUS_BAR,
            VISUAL_EFFECT_BADGE,
            VISUAL_EFFECT_AMBIENT,
            VISUAL_EFFECT_NOTIFICATION_LIST,
    })
    @Retention(RetentionPolicy.SOURCE)
    public @interface VisualEffect {}

    /** @hide */
    public static final int VISUAL_EFFECT_FULL_SCREEN_INTENT = 0;
    /** @hide */
    public static final int VISUAL_EFFECT_LIGHTS = 1;
    /** @hide */
    public static final int VISUAL_EFFECT_PEEK = 2;
    /** @hide */
    public static final int VISUAL_EFFECT_STATUS_BAR = 3;
    /** @hide */
    public static final int VISUAL_EFFECT_BADGE = 4;
    /** @hide */
    public static final int VISUAL_EFFECT_AMBIENT = 5;
    /** @hide */
    public static final int VISUAL_EFFECT_NOTIFICATION_LIST = 6;

    /** @hide */
    @IntDef(prefix = { "PEOPLE_TYPE_" }, value = {
            PEOPLE_TYPE_UNSET,
            PEOPLE_TYPE_ANYONE,
            PEOPLE_TYPE_CONTACTS,
            PEOPLE_TYPE_STARRED,
            PEOPLE_TYPE_NONE,
    })
    @Retention(RetentionPolicy.SOURCE)
    public @interface PeopleType {}

    /**
     * Used to indicate no preference for the type of people that can bypass dnd for either
     * calls or messages.
     */
    public static final int PEOPLE_TYPE_UNSET = 0;

    /**
     * Used to indicate all calls or messages can bypass dnd.
     */
    public static final int PEOPLE_TYPE_ANYONE = 1;

    /**
     * Used to indicate calls or messages from contacts can bypass dnd.
     */
    public static final int PEOPLE_TYPE_CONTACTS = 2;

    /**
     * Used to indicate calls or messages from starred contacts can bypass dnd.
     */
    public static final int PEOPLE_TYPE_STARRED = 3;

    /**
     * Used to indicate no calls or messages can bypass dnd.
     */
    public static final int PEOPLE_TYPE_NONE = 4;


    /** @hide */
    @IntDef(prefix = { "CONVERSATION_SENDERS_" }, value = {
            CONVERSATION_SENDERS_UNSET,
            CONVERSATION_SENDERS_ANYONE,
            CONVERSATION_SENDERS_IMPORTANT,
            CONVERSATION_SENDERS_NONE,
    })
    @Retention(RetentionPolicy.SOURCE)
    public @interface ConversationSenders {}

    /**
     * Used to indicate no preference for the type of conversations that can bypass dnd.
     */
    public static final int CONVERSATION_SENDERS_UNSET = 0;

    /**
     * Used to indicate all conversations can bypass dnd.
     */
    public static final int CONVERSATION_SENDERS_ANYONE = 1;

    /**
     * Used to indicate important conversations can bypass dnd.
     */
    public static final int CONVERSATION_SENDERS_IMPORTANT = 2;

    /**
     * Used to indicate no conversations can bypass dnd.
     */
    public static final int CONVERSATION_SENDERS_NONE = 3;

    /** @hide */
    @IntDef(prefix = { "STATE_" }, value = {
            STATE_UNSET,
            STATE_ALLOW,
            STATE_DISALLOW,
    })
    @Retention(RetentionPolicy.SOURCE)
    public @interface State {}

    /**
     * Indicates no preference for whether a type of sound or visual effect is or isn't allowed
     * to play/show when DND is active.  Will default to the current set policy.
     */
    public static final int STATE_UNSET = 0;

    /**
     * Indicates a type of sound or visual effect is allowed to play/show when DND is active.
     */
    public static final int STATE_ALLOW = 1;

    /**
     * Indicates a type of sound or visual effect is not allowed to play/show when DND is active.
     */
    public static final int STATE_DISALLOW = 2;

    /** @hide */
    public ZenPolicy() {
        mPriorityCategories = new ArrayList<>(Collections.nCopies(9, 0));
        mVisualEffects = new ArrayList<>(Collections.nCopies(7, 0));
    }

    /**
     * Conversation type that can bypass DND.
     * @return {@link #CONVERSATION_SENDERS_UNSET}, {@link #CONVERSATION_SENDERS_ANYONE},
     * {@link #CONVERSATION_SENDERS_IMPORTANT}, {@link #CONVERSATION_SENDERS_NONE}.
     */
    public @PeopleType int getPriorityConversationSenders() {
        return mConversationSenders;
    }

    /**
     * Message senders that can bypass DND.
     * @return {@link #PEOPLE_TYPE_UNSET}, {@link #PEOPLE_TYPE_ANYONE},
     * {@link #PEOPLE_TYPE_CONTACTS}, {@link #PEOPLE_TYPE_STARRED} or {@link #PEOPLE_TYPE_NONE}
     */
    public @PeopleType int getPriorityMessageSenders() {
        return mPriorityMessages;
    }

    /**
     * Callers that can bypass DND.
     * @return {@link #PEOPLE_TYPE_UNSET}, {@link #PEOPLE_TYPE_ANYONE},
     * {@link #PEOPLE_TYPE_CONTACTS}, {@link #PEOPLE_TYPE_STARRED} or {@link #PEOPLE_TYPE_NONE}
     */
    public @PeopleType int getPriorityCallSenders() {
        return mPriorityCalls;
    }

    /**
     * Whether this policy wants to allow conversation notifications
     * (see {@link NotificationChannel#getConversationId()}) to play sounds and visually appear
     * or to intercept them when DND is active.
     * @return {@link #STATE_UNSET}, {@link #STATE_ALLOW} or {@link #STATE_DISALLOW}
     */
    public @State int getPriorityCategoryConversations() {
        return mPriorityCategories.get(PRIORITY_CATEGORY_CONVERSATIONS);
    }

    /**
     * Whether this policy wants to allow notifications with category
     * {@link Notification#CATEGORY_REMINDER} to play sounds and visually appear
     * or to intercept them when DND is active.
     * @return {@link #STATE_UNSET}, {@link #STATE_ALLOW} or {@link #STATE_DISALLOW}
     */
    public @State int getPriorityCategoryReminders() {
        return mPriorityCategories.get(PRIORITY_CATEGORY_REMINDERS);
    }

    /**
     * Whether this policy wants to allow notifications with category
     * {@link Notification#CATEGORY_EVENT} to play sounds and visually appear
     * or to intercept them when DND is active.
     * @return {@link #STATE_UNSET}, {@link #STATE_ALLOW} or {@link #STATE_DISALLOW}
     */
    public @State int getPriorityCategoryEvents() {
        return mPriorityCategories.get(PRIORITY_CATEGORY_EVENTS);
    }

    /**
     * Whether this policy wants to allow notifications with category
     * {@link Notification#CATEGORY_MESSAGE} to play sounds and visually appear
     * or to intercept them when DND is active.  Types of message senders that are allowed
     * are specified by {@link #getPriorityMessageSenders}.
     * @return {@link #STATE_UNSET}, {@link #STATE_ALLOW} or {@link #STATE_DISALLOW}
     */
    public @State int getPriorityCategoryMessages() {
        return mPriorityCategories.get(PRIORITY_CATEGORY_MESSAGES);
    }

    /**
     * Whether this policy wants to allow notifications with category
     * {@link Notification#CATEGORY_CALL} to play sounds and visually appear
     * or to intercept them when DND is active.  Types of callers that are allowed
     * are specified by {@link #getPriorityCallSenders()}.
     * @return {@link #STATE_UNSET}, {@link #STATE_ALLOW} or {@link #STATE_DISALLOW}
     */
    public @State int getPriorityCategoryCalls() {
        return mPriorityCategories.get(PRIORITY_CATEGORY_CALLS);
    }

    /**
     * Whether this policy wants to allow repeat callers (notifications with category
     * {@link Notification#CATEGORY_CALL} that have recently called) to play sounds and
     * visually appear or to intercept them when DND is active.
     * @return {@link #STATE_UNSET}, {@link #STATE_ALLOW} or {@link #STATE_DISALLOW}
     */
    public @State int getPriorityCategoryRepeatCallers() {
        return mPriorityCategories.get(PRIORITY_CATEGORY_REPEAT_CALLERS);
    }

    /**
     * Whether this policy wants to allow notifications with category
     * {@link Notification#CATEGORY_ALARM} to play sounds and visually appear
     * or to intercept them when DND is active.
     * When alarms are {@link #STATE_DISALLOW disallowed}, the alarm stream will be muted when DND
     * is active.
     * @return {@link #STATE_UNSET}, {@link #STATE_ALLOW} or {@link #STATE_DISALLOW}
     */
    public @State int getPriorityCategoryAlarms() {
        return mPriorityCategories.get(PRIORITY_CATEGORY_ALARMS);
    }

    /**
     * Whether this policy wants to allow media notifications to play sounds and visually appear
     * or to intercept them when DND is active.
     * When media is {@link #STATE_DISALLOW disallowed}, the media stream will be muted when DND is
     * active.
     * @return {@link #STATE_UNSET}, {@link #STATE_ALLOW} or {@link #STATE_DISALLOW}
     */
    public @State int getPriorityCategoryMedia() {
        return mPriorityCategories.get(PRIORITY_CATEGORY_MEDIA);
    }

    /**
     * Whether this policy wants to allow system sounds when DND is active.
     * When system is {@link #STATE_DISALLOW}, the system stream will be muted when DND is active.
     * @return {@link #STATE_UNSET}, {@link #STATE_ALLOW} or {@link #STATE_DISALLOW}
     */
    public @State int getPriorityCategorySystem() {
        return mPriorityCategories.get(PRIORITY_CATEGORY_SYSTEM);
    }

    /**
     * Whether this policy allows {@link Notification#fullScreenIntent full screen intents} from
     * notifications intercepted by DND.
     */
    public @State int getVisualEffectFullScreenIntent() {
        return mVisualEffects.get(VISUAL_EFFECT_FULL_SCREEN_INTENT);
    }

    /**
     * Whether this policy allows {@link NotificationChannel#shouldShowLights() notification
     * lights} from notifications intercepted by DND.
     */
    public @State int getVisualEffectLights() {
        return mVisualEffects.get(VISUAL_EFFECT_LIGHTS);
    }

    /**
     * Whether this policy allows peeking from notifications intercepted by DND.
     */
    public @State int getVisualEffectPeek() {
        return mVisualEffects.get(VISUAL_EFFECT_PEEK);
    }

    /**
     * Whether this policy allows notifications intercepted by DND from appearing in the status bar
     * on devices that support status bars.
     */
    public @State int getVisualEffectStatusBar() {
        return mVisualEffects.get(VISUAL_EFFECT_STATUS_BAR);
    }

    /**
     * Whether this policy allows {@link NotificationChannel#canShowBadge() badges} from
     * notifications intercepted by DND on devices that support badging.
     */
    public @State int getVisualEffectBadge() {
        return mVisualEffects.get(VISUAL_EFFECT_BADGE);
    }

    /**
     * Whether this policy allows notifications intercepted by DND from appearing on ambient
     * displays on devices that support ambient display.
     */
    public @State int getVisualEffectAmbient() {
        return mVisualEffects.get(VISUAL_EFFECT_AMBIENT);
    }

    /**
     * Whether this policy allows notifications intercepted by DND from appearing in notification
     * list views like the notification shade or lockscreen on devices that support those
     * views.
     */
    public @State int getVisualEffectNotificationList() {
        return mVisualEffects.get(VISUAL_EFFECT_NOTIFICATION_LIST);
    }

    /**
     * Whether this policy hides all visual effects
     * @hide
     */
    public boolean shouldHideAllVisualEffects() {
        for (int i = 0; i < mVisualEffects.size(); i++) {
            if (mVisualEffects.get(i) != STATE_DISALLOW) {
                return false;
            }
        }
        return true;
    }

    /**
     * Whether this policy shows all visual effects
     * @hide
     */
    public boolean shouldShowAllVisualEffects() {
        for (int i = 0; i < mVisualEffects.size(); i++) {
            if (mVisualEffects.get(i) != STATE_ALLOW) {
                return false;
            }
        }
        return true;
    }

    /**
     * Builder class for {@link ZenPolicy} objects.
     * Provides a convenient way to set the various fields of a {@link ZenPolicy}.  If a field
     * is not set, it is (@link STATE_UNSET} and will not change the current set policy.
     */
    public static final class Builder {
        private ZenPolicy mZenPolicy;

        public Builder() {
            mZenPolicy = new ZenPolicy();
        }

        /**
         * @hide
         */
        public Builder(ZenPolicy policy) {
            if (policy != null) {
                mZenPolicy = policy.copy();
            } else {
                mZenPolicy = new ZenPolicy();
            }
        }

        /**
         * Builds the current ZenPolicy.
         */
        public @NonNull ZenPolicy build() {
            return mZenPolicy.copy();
        }

        /**
         * Allows all notifications to bypass DND and unmutes all streams.
         */
        public @NonNull Builder allowAllSounds() {
            for (int i = 0; i < mZenPolicy.mPriorityCategories.size(); i++) {
                mZenPolicy.mPriorityCategories.set(i, STATE_ALLOW);
            }
            mZenPolicy.mPriorityMessages = PEOPLE_TYPE_ANYONE;
            mZenPolicy.mPriorityCalls = PEOPLE_TYPE_ANYONE;
            mZenPolicy.mConversationSenders = CONVERSATION_SENDERS_ANYONE;
            return this;
        }

        /**
         * Intercepts all notifications and prevents them from playing sounds
         * when DND is active. Also mutes alarm, system and media streams.
         * Notification channels can still play sounds only if they
         * {@link NotificationChannel#canBypassDnd can bypass DND}. If no channels can bypass DND,
         * the ringer stream is also muted.
         */
        public @NonNull Builder disallowAllSounds() {
            for (int i = 0; i < mZenPolicy.mPriorityCategories.size(); i++) {
                mZenPolicy.mPriorityCategories.set(i, STATE_DISALLOW);
            }
            mZenPolicy.mPriorityMessages = PEOPLE_TYPE_NONE;
            mZenPolicy.mPriorityCalls = PEOPLE_TYPE_NONE;
            mZenPolicy.mConversationSenders = CONVERSATION_SENDERS_NONE;
            return this;
        }

        /**
         * Allows notifications intercepted by DND to show on all surfaces when DND is active.
         */
        public @NonNull Builder showAllVisualEffects() {
            for (int i = 0; i < mZenPolicy.mVisualEffects.size(); i++) {
                mZenPolicy.mVisualEffects.set(i, STATE_ALLOW);
            }
            return this;
        }

        /**
         * Disallows notifications intercepted by DND from showing when DND is active.
         */
        public @NonNull Builder hideAllVisualEffects() {
            for (int i = 0; i < mZenPolicy.mVisualEffects.size(); i++) {
                mZenPolicy.mVisualEffects.set(i, STATE_DISALLOW);
            }
            return this;
        }

        /**
         * Unsets a priority category, neither allowing or disallowing. When applying this policy,
         * unset categories will default to the current applied policy.
         * @hide
         */
        public @NonNull Builder unsetPriorityCategory(@PriorityCategory int category) {
            mZenPolicy.mPriorityCategories.set(category, STATE_UNSET);

            if (category == PRIORITY_CATEGORY_MESSAGES) {
                mZenPolicy.mPriorityMessages = STATE_UNSET;
            } else if (category == PRIORITY_CATEGORY_CALLS) {
                mZenPolicy.mPriorityCalls = STATE_UNSET;
            } else if (category == PRIORITY_CATEGORY_CONVERSATIONS) {
                mZenPolicy.mConversationSenders = STATE_UNSET;
            }

            return this;
        }

        /**
         * Unsets a visual effect, neither allowing or disallowing. When applying this policy,
         * unset effects will default to the current applied policy.
         * @hide
         */
        public @NonNull Builder unsetVisualEffect(@VisualEffect int effect) {
            mZenPolicy.mVisualEffects.set(effect, STATE_UNSET);
            return this;
        }

        /**
         * Whether to allow notifications with category {@link Notification#CATEGORY_REMINDER}
         * to play sounds and visually appear or to intercept them when DND is active.
         */
        public @NonNull Builder allowReminders(boolean allow) {
            mZenPolicy.mPriorityCategories.set(PRIORITY_CATEGORY_REMINDERS,
                    allow ? STATE_ALLOW : STATE_DISALLOW);
            return this;
        }

        /**
         * Whether to allow notifications with category {@link Notification#CATEGORY_EVENT}
         * to play sounds and visually appear or to intercept them when DND is active.
         */
        public @NonNull Builder allowEvents(boolean allow) {
            mZenPolicy.mPriorityCategories.set(PRIORITY_CATEGORY_EVENTS,
                    allow ? STATE_ALLOW : STATE_DISALLOW);
            return this;
        }

        /**
         * Whether to allow conversation notifications
         * (see {@link NotificationChannel#setConversationId(String, String)})
         * that match audienceType to play sounds and visually appear or to intercept
         * them when DND is active.
         * @param audienceType callers that are allowed to bypass DND
         */
        public @NonNull  Builder allowConversations(@ConversationSenders int audienceType) {
            if (audienceType == STATE_UNSET) {
                return unsetPriorityCategory(PRIORITY_CATEGORY_CONVERSATIONS);
            }

            if (audienceType == CONVERSATION_SENDERS_NONE) {
                mZenPolicy.mPriorityCategories.set(PRIORITY_CATEGORY_CONVERSATIONS, STATE_DISALLOW);
            } else if (audienceType == CONVERSATION_SENDERS_ANYONE
                    || audienceType == CONVERSATION_SENDERS_IMPORTANT) {
                mZenPolicy.mPriorityCategories.set(PRIORITY_CATEGORY_CONVERSATIONS, STATE_ALLOW);
            } else {
                return this;
            }

            mZenPolicy.mConversationSenders = audienceType;
            return this;
        }

        /**
         * Whether to allow notifications with category {@link Notification#CATEGORY_MESSAGE}
         * that match audienceType to play sounds and visually appear or to intercept
         * them when DND is active.
         * @param audienceType message senders that are allowed to bypass DND
         */
        public @NonNull Builder allowMessages(@PeopleType int audienceType) {
            if (audienceType == STATE_UNSET) {
                return unsetPriorityCategory(PRIORITY_CATEGORY_MESSAGES);
            }

            if (audienceType == PEOPLE_TYPE_NONE) {
                mZenPolicy.mPriorityCategories.set(PRIORITY_CATEGORY_MESSAGES, STATE_DISALLOW);
            } else if (audienceType == PEOPLE_TYPE_ANYONE || audienceType == PEOPLE_TYPE_CONTACTS
                    || audienceType == PEOPLE_TYPE_STARRED) {
                mZenPolicy.mPriorityCategories.set(PRIORITY_CATEGORY_MESSAGES, STATE_ALLOW);
            } else {
                return this;
            }

            mZenPolicy.mPriorityMessages = audienceType;
            return this;
        }

        /**
         * Whether to allow notifications with category {@link Notification#CATEGORY_CALL}
         * that match audienceType to play sounds and visually appear or to intercept
         * them when DND is active.
         * @param audienceType callers that are allowed to bypass DND
         */
        public @NonNull  Builder allowCalls(@PeopleType int audienceType) {
            if (audienceType == STATE_UNSET) {
                return unsetPriorityCategory(PRIORITY_CATEGORY_CALLS);
            }

            if (audienceType == PEOPLE_TYPE_NONE) {
                mZenPolicy.mPriorityCategories.set(PRIORITY_CATEGORY_CALLS, STATE_DISALLOW);
            } else if (audienceType == PEOPLE_TYPE_ANYONE || audienceType == PEOPLE_TYPE_CONTACTS
                    || audienceType == PEOPLE_TYPE_STARRED) {
                mZenPolicy.mPriorityCategories.set(PRIORITY_CATEGORY_CALLS, STATE_ALLOW);
            } else {
                return this;
            }

            mZenPolicy.mPriorityCalls = audienceType;
            return this;
        }

        /**
         * Whether to allow repeat callers (notifications with category
         * {@link Notification#CATEGORY_CALL} that have recently called
         * to play sounds and visually appear.
         */
        public @NonNull Builder allowRepeatCallers(boolean allow) {
            mZenPolicy.mPriorityCategories.set(PRIORITY_CATEGORY_REPEAT_CALLERS,
                    allow ? STATE_ALLOW : STATE_DISALLOW);
            return this;
        }

        /**
         * Whether to allow notifications with category {@link Notification#CATEGORY_ALARM}
         * to play sounds and visually appear or to intercept them when DND is active.
         * Disallowing alarms will mute the alarm stream when DND is active.
         */
        public @NonNull Builder allowAlarms(boolean allow) {
            mZenPolicy.mPriorityCategories.set(PRIORITY_CATEGORY_ALARMS,
                    allow ? STATE_ALLOW : STATE_DISALLOW);
            return this;
        }

        /**
         * Whether to allow media notifications to play sounds and visually
         * appear or to intercept them when DND is active.
         * Disallowing media will mute the media stream when DND is active.
         */
        public @NonNull Builder allowMedia(boolean allow) {
            mZenPolicy.mPriorityCategories.set(PRIORITY_CATEGORY_MEDIA,
                    allow ? STATE_ALLOW : STATE_DISALLOW);
            return this;
        }

        /**
         * Whether to allow system sounds to play when DND is active.
         * Disallowing system sounds will mute the system stream when DND is active.
         */
        public @NonNull Builder allowSystem(boolean allow) {
            mZenPolicy.mPriorityCategories.set(PRIORITY_CATEGORY_SYSTEM,
                    allow ? STATE_ALLOW : STATE_DISALLOW);
            return this;
        }

        /**
         * Whether to allow {@link PriorityCategory} sounds to play when DND is active.
         * @hide
         */
        public @NonNull Builder allowCategory(@PriorityCategory int category, boolean allow) {
            switch (category) {
                case PRIORITY_CATEGORY_ALARMS:
                    allowAlarms(allow);
                    break;
                case PRIORITY_CATEGORY_MEDIA:
                    allowMedia(allow);
                    break;
                case PRIORITY_CATEGORY_SYSTEM:
                    allowSystem(allow);
                    break;
                case PRIORITY_CATEGORY_REMINDERS:
                    allowReminders(allow);
                    break;
                case PRIORITY_CATEGORY_EVENTS:
                    allowEvents(allow);
                    break;
                case PRIORITY_CATEGORY_REPEAT_CALLERS:
                    allowRepeatCallers(allow);
                    break;
            }
            return this;
        }

        /**
         * Whether {@link Notification#fullScreenIntent full screen intents} that are intercepted
         * by DND are shown.
         */
        public @NonNull Builder showFullScreenIntent(boolean show) {
            mZenPolicy.mVisualEffects.set(VISUAL_EFFECT_FULL_SCREEN_INTENT,
                    show ? STATE_ALLOW : STATE_DISALLOW);
            return this;
        }

        /**
         * Whether {@link NotificationChannel#shouldShowLights() notification lights} from
         * notifications intercepted by DND are blocked.
         */
        public @NonNull Builder showLights(boolean show) {
            mZenPolicy.mVisualEffects.set(VISUAL_EFFECT_LIGHTS,
                    show ? STATE_ALLOW : STATE_DISALLOW);
            return this;
        }

        /**
         * Whether notifications intercepted by DND are prevented from peeking.
         */
        public @NonNull Builder showPeeking(boolean show) {
            mZenPolicy.mVisualEffects.set(VISUAL_EFFECT_PEEK,
                    show ? STATE_ALLOW : STATE_DISALLOW);
            return this;
        }

        /**
         * Whether notifications intercepted by DND are prevented from appearing in the status bar
         * on devices that support status bars.
         */
        public @NonNull Builder showStatusBarIcons(boolean show) {
            mZenPolicy.mVisualEffects.set(VISUAL_EFFECT_STATUS_BAR,
                    show ? STATE_ALLOW : STATE_DISALLOW);
            return this;
        }

        /**
         * Whether {@link NotificationChannel#canShowBadge() badges} from
         * notifications intercepted by DND are allowed on devices that support badging.
         */
        public @NonNull Builder showBadges(boolean show) {
            mZenPolicy.mVisualEffects.set(VISUAL_EFFECT_BADGE,
                    show ? STATE_ALLOW : STATE_DISALLOW);
            return this;
        }

        /**
         * Whether notification intercepted by DND are prevented from appearing on ambient displays
         * on devices that support ambient display.
         */
        public @NonNull Builder showInAmbientDisplay(boolean show) {
            mZenPolicy.mVisualEffects.set(VISUAL_EFFECT_AMBIENT,
                    show ? STATE_ALLOW : STATE_DISALLOW);
            return this;
        }

        /**
         * Whether notification intercepted by DND are prevented from appearing in notification
         * list views like the notification shade or lockscreen on devices that support those
         * views.
         */
        public @NonNull Builder showInNotificationList(boolean show) {
            mZenPolicy.mVisualEffects.set(VISUAL_EFFECT_NOTIFICATION_LIST,
                    show ? STATE_ALLOW : STATE_DISALLOW);
            return this;
        }

        /**
         * Whether notifications intercepted by DND are prevented from appearing for
         * {@link VisualEffect}
         * @hide
         */
        public @NonNull Builder showVisualEffect(@VisualEffect int effect, boolean show) {
            switch (effect) {
                case VISUAL_EFFECT_FULL_SCREEN_INTENT:
                    showFullScreenIntent(show);
                    break;
                case VISUAL_EFFECT_LIGHTS:
                    showLights(show);
                    break;
                case VISUAL_EFFECT_PEEK:
                    showPeeking(show);
                    break;
                case VISUAL_EFFECT_STATUS_BAR:
                    showStatusBarIcons(show);
                    break;
                case VISUAL_EFFECT_BADGE:
                    showBadges(show);
                    break;
                case VISUAL_EFFECT_AMBIENT:
                    showInAmbientDisplay(show);
                    break;
                case VISUAL_EFFECT_NOTIFICATION_LIST:
                    showInNotificationList(show);
                    break;
            }
            return this;
        }
    }

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

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeList(mPriorityCategories);
        dest.writeList(mVisualEffects);
        dest.writeInt(mPriorityCalls);
        dest.writeInt(mPriorityMessages);
        dest.writeInt(mConversationSenders);
    }

    public static final @android.annotation.NonNull Parcelable.Creator<ZenPolicy> CREATOR =
            new Parcelable.Creator<ZenPolicy>() {
        @Override
        public ZenPolicy createFromParcel(Parcel source) {
            ZenPolicy policy = new ZenPolicy();
            policy.mPriorityCategories = source.readArrayList(Integer.class.getClassLoader());
            policy.mVisualEffects = source.readArrayList(Integer.class.getClassLoader());
            policy.mPriorityCalls = source.readInt();
            policy.mPriorityMessages = source.readInt();
            policy.mConversationSenders = source.readInt();
            return policy;
        }

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

    @Override
    public String toString() {
        return new StringBuilder(ZenPolicy.class.getSimpleName())
                .append('{')
                .append("priorityCategories=[").append(priorityCategoriesToString())
                .append("], visualEffects=[").append(visualEffectsToString())
                .append("], priorityCallsSenders=").append(peopleTypeToString(mPriorityCalls))
                .append(", priorityMessagesSenders=").append(peopleTypeToString(mPriorityMessages))
                .append(", priorityConversationSenders=").append(
                        conversationTypeToString(mConversationSenders))
                .append('}')
                .toString();
    }


    private String priorityCategoriesToString() {
        StringBuilder builder = new StringBuilder();
        for (int i = 0; i < mPriorityCategories.size(); i++) {
            if (mPriorityCategories.get(i) != STATE_UNSET) {
                builder.append(indexToCategory(i))
                        .append("=")
                        .append(stateToString(mPriorityCategories.get(i)))
                        .append(" ");
            }

        }
        return builder.toString();
    }

    private String visualEffectsToString() {
        StringBuilder builder = new StringBuilder();
        for (int i = 0; i < mVisualEffects.size(); i++) {
            if (mVisualEffects.get(i) != STATE_UNSET) {
                builder.append(indexToVisualEffect(i))
                        .append("=")
                        .append(stateToString(mVisualEffects.get(i)))
                        .append(" ");
            }

        }
        return builder.toString();
    }

    private String indexToVisualEffect(@VisualEffect int visualEffectIndex) {
        switch (visualEffectIndex) {
            case VISUAL_EFFECT_FULL_SCREEN_INTENT:
                return "fullScreenIntent";
            case VISUAL_EFFECT_LIGHTS:
                return "lights";
            case VISUAL_EFFECT_PEEK:
                return "peek";
            case VISUAL_EFFECT_STATUS_BAR:
                return "statusBar";
            case VISUAL_EFFECT_BADGE:
                return "badge";
            case VISUAL_EFFECT_AMBIENT:
                return "ambient";
            case VISUAL_EFFECT_NOTIFICATION_LIST:
                return "notificationList";
        }
        return null;
    }

    private String indexToCategory(@PriorityCategory int categoryIndex) {
        switch (categoryIndex) {
            case PRIORITY_CATEGORY_REMINDERS:
                return "reminders";
            case PRIORITY_CATEGORY_EVENTS:
                return "events";
            case PRIORITY_CATEGORY_MESSAGES:
                return "messages";
            case PRIORITY_CATEGORY_CALLS:
                return "calls";
            case PRIORITY_CATEGORY_REPEAT_CALLERS:
                return "repeatCallers";
            case PRIORITY_CATEGORY_ALARMS:
                return "alarms";
            case PRIORITY_CATEGORY_MEDIA:
                return "media";
            case PRIORITY_CATEGORY_SYSTEM:
                return "system";
            case PRIORITY_CATEGORY_CONVERSATIONS:
                return "convs";
        }
        return null;
    }

    private String stateToString(@State int state) {
        switch (state) {
            case STATE_UNSET:
                return "unset";
            case STATE_DISALLOW:
                return "disallow";
            case STATE_ALLOW:
                return "allow";
        }
        return "invalidState{" + state + "}";
    }

    private String peopleTypeToString(@PeopleType int peopleType) {
        switch (peopleType) {
            case PEOPLE_TYPE_ANYONE:
                return "anyone";
            case PEOPLE_TYPE_CONTACTS:
                return "contacts";
            case PEOPLE_TYPE_NONE:
                return "none";
            case PEOPLE_TYPE_STARRED:
                return "starred_contacts";
            case STATE_UNSET:
                return "unset";
        }
        return "invalidPeopleType{" + peopleType + "}";
    }

    /**
     * @hide
     */
    public static String conversationTypeToString(@ConversationSenders int conversationType) {
        switch (conversationType) {
            case CONVERSATION_SENDERS_ANYONE:
                return "anyone";
            case CONVERSATION_SENDERS_IMPORTANT:
                return "important";
            case CONVERSATION_SENDERS_NONE:
                return "none";
            case CONVERSATION_SENDERS_UNSET:
                return "unset";
        }
        return "invalidConversationType{" + conversationType + "}";
    }

    @Override
    public boolean equals(Object o) {
        if (!(o instanceof ZenPolicy)) return false;
        if (o == this) return true;
        final ZenPolicy other = (ZenPolicy) o;

        return Objects.equals(other.mPriorityCategories, mPriorityCategories)
                && Objects.equals(other.mVisualEffects, mVisualEffects)
                && other.mPriorityCalls == mPriorityCalls
                && other.mPriorityMessages == mPriorityMessages
                && other.mConversationSenders == mConversationSenders;
    }

    @Override
    public int hashCode() {
        return Objects.hash(mPriorityCategories, mVisualEffects, mPriorityCalls, mPriorityMessages,
                mConversationSenders);
    }

    private @ZenPolicy.State int getZenPolicyPriorityCategoryState(@PriorityCategory int
            category) {
        switch (category) {
            case PRIORITY_CATEGORY_REMINDERS:
                return getPriorityCategoryReminders();
            case PRIORITY_CATEGORY_EVENTS:
                return getPriorityCategoryEvents();
            case PRIORITY_CATEGORY_MESSAGES:
                return getPriorityCategoryMessages();
            case PRIORITY_CATEGORY_CALLS:
                return getPriorityCategoryCalls();
            case PRIORITY_CATEGORY_REPEAT_CALLERS:
                return getPriorityCategoryRepeatCallers();
            case PRIORITY_CATEGORY_ALARMS:
                return getPriorityCategoryAlarms();
            case PRIORITY_CATEGORY_MEDIA:
                return getPriorityCategoryMedia();
            case PRIORITY_CATEGORY_SYSTEM:
                return getPriorityCategorySystem();
            case PRIORITY_CATEGORY_CONVERSATIONS:
                return getPriorityCategoryConversations();
        }
        return -1;
    }

    private @ZenPolicy.State int getZenPolicyVisualEffectState(@VisualEffect int effect) {
        switch (effect) {
            case VISUAL_EFFECT_FULL_SCREEN_INTENT:
                return getVisualEffectFullScreenIntent();
            case VISUAL_EFFECT_LIGHTS:
                return getVisualEffectLights();
            case VISUAL_EFFECT_PEEK:
                return getVisualEffectPeek();
            case VISUAL_EFFECT_STATUS_BAR:
                return getVisualEffectStatusBar();
            case VISUAL_EFFECT_BADGE:
                return getVisualEffectBadge();
            case VISUAL_EFFECT_AMBIENT:
                return getVisualEffectAmbient();
            case VISUAL_EFFECT_NOTIFICATION_LIST:
                return getVisualEffectNotificationList();
        }
        return -1;
    }

    /** @hide */
    public boolean isCategoryAllowed(@PriorityCategory int category, boolean defaultVal) {
        switch (getZenPolicyPriorityCategoryState(category)) {
            case ZenPolicy.STATE_ALLOW:
                return true;
            case ZenPolicy.STATE_DISALLOW:
                return false;
            default:
                return defaultVal;
        }
    }

    /** @hide */
    public boolean isVisualEffectAllowed(@VisualEffect int effect, boolean defaultVal) {
        switch (getZenPolicyVisualEffectState(effect)) {
            case ZenPolicy.STATE_ALLOW:
                return true;
            case ZenPolicy.STATE_DISALLOW:
                return false;
            default:
                return defaultVal;
        }
    }

    /**
     * Applies another policy on top of this policy
     * @hide
     */
    public void apply(ZenPolicy policyToApply) {
        if (policyToApply == null) {
            return;
        }

        // apply priority categories
        for (int category = 0; category < mPriorityCategories.size(); category++) {
            if (mPriorityCategories.get(category) == STATE_DISALLOW) {
                // if a priority category is already disallowed by the policy, cannot allow
                continue;
            }

            @State int newState = policyToApply.mPriorityCategories.get(category);
            if (newState != STATE_UNSET) {
                mPriorityCategories.set(category, newState);

                if (category == PRIORITY_CATEGORY_MESSAGES
                        && mPriorityMessages < policyToApply.mPriorityMessages) {
                    mPriorityMessages = policyToApply.mPriorityMessages;
                } else if (category == PRIORITY_CATEGORY_CALLS
                        && mPriorityCalls < policyToApply.mPriorityCalls) {
                    mPriorityCalls = policyToApply.mPriorityCalls;
                } else if (category == PRIORITY_CATEGORY_CONVERSATIONS
                        && mConversationSenders < policyToApply.mConversationSenders) {
                    mConversationSenders = policyToApply.mConversationSenders;
                }
            }
        }

        // apply visual effects
        for (int visualEffect = 0; visualEffect < mVisualEffects.size(); visualEffect++) {
            if (mVisualEffects.get(visualEffect) == STATE_DISALLOW) {
                // if a visual effect is already disallowed by the policy, cannot allow
                continue;
            }

            if (policyToApply.mVisualEffects.get(visualEffect) != STATE_UNSET) {
                mVisualEffects.set(visualEffect, policyToApply.mVisualEffects.get(visualEffect));
            }
        }
    }

    /**
     * @hide
     */
    public void dumpDebug(ProtoOutputStream proto, long fieldId) {
        final long token = proto.start(fieldId);

        proto.write(ZenPolicyProto.REMINDERS, getPriorityCategoryReminders());
        proto.write(ZenPolicyProto.EVENTS, getPriorityCategoryEvents());
        proto.write(ZenPolicyProto.MESSAGES, getPriorityCategoryMessages());
        proto.write(ZenPolicyProto.CALLS, getPriorityCategoryCalls());
        proto.write(ZenPolicyProto.REPEAT_CALLERS, getPriorityCategoryRepeatCallers());
        proto.write(ZenPolicyProto.ALARMS, getPriorityCategoryAlarms());
        proto.write(ZenPolicyProto.MEDIA, getPriorityCategoryMedia());
        proto.write(ZenPolicyProto.SYSTEM, getPriorityCategorySystem());

        proto.write(ZenPolicyProto.FULL_SCREEN_INTENT, getVisualEffectFullScreenIntent());
        proto.write(ZenPolicyProto.LIGHTS, getVisualEffectLights());
        proto.write(ZenPolicyProto.PEEK, getVisualEffectPeek());
        proto.write(ZenPolicyProto.STATUS_BAR, getVisualEffectStatusBar());
        proto.write(ZenPolicyProto.BADGE, getVisualEffectBadge());
        proto.write(ZenPolicyProto.AMBIENT, getVisualEffectAmbient());
        proto.write(ZenPolicyProto.NOTIFICATION_LIST, getVisualEffectNotificationList());

        proto.write(ZenPolicyProto.PRIORITY_MESSAGES, getPriorityMessageSenders());
        proto.write(ZenPolicyProto.PRIORITY_CALLS, getPriorityCallSenders());
        proto.end(token);
    }

    /**
     * Makes deep copy of this ZenPolicy.
     * @hide
     */
    public @NonNull ZenPolicy copy() {
        final Parcel parcel = Parcel.obtain();
        try {
            writeToParcel(parcel, 0);
            parcel.setDataPosition(0);
            return CREATOR.createFromParcel(parcel);
        } finally {
            parcel.recycle();
        }
    }
}
