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

import static android.app.AppOpsManager.OP_ACCEPT_HANDOVER;
import static android.app.AppOpsManager.OP_CAMERA;
import static android.app.Notification.CATEGORY_ALARM;
import static android.app.Notification.CATEGORY_CALL;
import static android.app.Notification.CATEGORY_EVENT;
import static android.app.Notification.CATEGORY_MESSAGE;
import static android.app.Notification.CATEGORY_REMINDER;

import static junit.framework.Assert.assertEquals;

import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

import android.Manifest;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.PendingIntent;
import android.content.Intent;
import android.content.pm.IPackageManager;
import android.content.pm.PackageManager;
import android.graphics.drawable.Icon;
import android.media.session.MediaSession;
import android.os.Bundle;
import android.service.notification.NotificationListenerService;
import android.service.notification.NotificationListenerService.Ranking;
import android.service.notification.SnoozeCriterion;
import android.service.notification.StatusBarNotification;
import android.support.test.annotation.UiThreadTest;
import android.support.test.filters.SmallTest;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper.RunWithLooper;
import android.util.ArraySet;

import com.android.systemui.Dependency;
import com.android.systemui.ForegroundServiceController;
import com.android.systemui.InitController;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.statusbar.NotificationTestHelper;
import com.android.systemui.statusbar.notification.NotificationData.KeyguardEnvironment;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
import com.android.systemui.statusbar.phone.NotificationGroupManager;
import com.android.systemui.statusbar.phone.ShadeController;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;

import java.util.ArrayList;

@SmallTest
@RunWith(AndroidTestingRunner.class)
@RunWithLooper(setAsMainLooper = true)
public class NotificationDataTest extends SysuiTestCase {

    private static final int UID_NORMAL = 123;
    private static final int UID_ALLOW_DURING_SETUP = 456;
    private static final String TEST_HIDDEN_NOTIFICATION_KEY = "testHiddenNotificationKey";
    private static final String TEST_EXEMPT_DND_VISUAL_SUPPRESSION_KEY = "exempt";
    private static final NotificationChannel NOTIFICATION_CHANNEL =
            new NotificationChannel("id", "name", NotificationChannel.USER_LOCKED_IMPORTANCE);

    private final StatusBarNotification mMockStatusBarNotification =
            mock(StatusBarNotification.class);
    @Mock
    ForegroundServiceController mFsc;
    @Mock
    NotificationData.KeyguardEnvironment mEnvironment;

    private final IPackageManager mMockPackageManager = mock(IPackageManager.class);
    private NotificationData mNotificationData;
    private ExpandableNotificationRow mRow;

    @Before
    public void setUp() throws Exception {
        MockitoAnnotations.initMocks(this);
        when(mMockStatusBarNotification.getUid()).thenReturn(UID_NORMAL);

        when(mMockPackageManager.checkUidPermission(
                eq(Manifest.permission.NOTIFICATION_DURING_SETUP),
                eq(UID_NORMAL)))
                .thenReturn(PackageManager.PERMISSION_DENIED);
        when(mMockPackageManager.checkUidPermission(
                eq(Manifest.permission.NOTIFICATION_DURING_SETUP),
                eq(UID_ALLOW_DURING_SETUP)))
                .thenReturn(PackageManager.PERMISSION_GRANTED);

        mDependency.injectTestDependency(ForegroundServiceController.class, mFsc);
        mDependency.injectTestDependency(NotificationGroupManager.class,
                new NotificationGroupManager());
        mDependency.injectMockDependency(ShadeController.class);
        mDependency.injectTestDependency(KeyguardEnvironment.class, mEnvironment);
        when(mEnvironment.isDeviceProvisioned()).thenReturn(true);
        when(mEnvironment.isNotificationForCurrentProfiles(any())).thenReturn(true);
        mNotificationData = new TestableNotificationData();
        Dependency.get(InitController.class).executePostInitTasks();
        mNotificationData.updateRanking(mock(NotificationListenerService.RankingMap.class));
        mRow = new NotificationTestHelper(getContext()).createRow();
    }

    @Test
    @UiThreadTest
    public void testShowNotificationEvenIfUnprovisioned_FalseIfNoExtra() {
        initStatusBarNotification(false);
        when(mMockStatusBarNotification.getUid()).thenReturn(UID_ALLOW_DURING_SETUP);

        assertFalse(
                NotificationData.showNotificationEvenIfUnprovisioned(
                        mMockPackageManager,
                        mMockStatusBarNotification));
    }

    @Test
    @UiThreadTest
    public void testShowNotificationEvenIfUnprovisioned_FalseIfNoPermission() {
        initStatusBarNotification(true);

        assertFalse(
                NotificationData.showNotificationEvenIfUnprovisioned(
                        mMockPackageManager,
                        mMockStatusBarNotification));
    }

    @Test
    @UiThreadTest
    public void testShowNotificationEvenIfUnprovisioned_TrueIfHasPermissionAndExtra() {
        initStatusBarNotification(true);
        when(mMockStatusBarNotification.getUid()).thenReturn(UID_ALLOW_DURING_SETUP);

        assertTrue(
                NotificationData.showNotificationEvenIfUnprovisioned(
                        mMockPackageManager,
                        mMockStatusBarNotification));
    }

    @Test
    public void testChannelSetWhenAdded() {
        mNotificationData.add(mRow.getEntry());
        assertEquals(NOTIFICATION_CHANNEL, mRow.getEntry().channel);
    }

    @Test
    public void testAllRelevantNotisTaggedWithAppOps() throws Exception {
        mNotificationData.add(mRow.getEntry());
        ExpandableNotificationRow row2 = new NotificationTestHelper(getContext()).createRow();
        mNotificationData.add(row2.getEntry());
        ExpandableNotificationRow diffPkg =
                new NotificationTestHelper(getContext()).createRow("pkg", 4000);
        mNotificationData.add(diffPkg.getEntry());

        ArraySet<Integer> expectedOps = new ArraySet<>();
        expectedOps.add(OP_CAMERA);
        expectedOps.add(OP_ACCEPT_HANDOVER);

        for (int op : expectedOps) {
            mNotificationData.updateAppOp(op, NotificationTestHelper.UID,
                    NotificationTestHelper.PKG, mRow.getEntry().key, true);
            mNotificationData.updateAppOp(op, NotificationTestHelper.UID,
                    NotificationTestHelper.PKG, row2.getEntry().key, true);
        }
        for (int op : expectedOps) {
            assertTrue(mRow.getEntry().key + " doesn't have op " + op,
                    mNotificationData.get(mRow.getEntry().key).mActiveAppOps.contains(op));
            assertTrue(row2.getEntry().key + " doesn't have op " + op,
                    mNotificationData.get(row2.getEntry().key).mActiveAppOps.contains(op));
            assertFalse(diffPkg.getEntry().key + " has op " + op,
                    mNotificationData.get(diffPkg.getEntry().key).mActiveAppOps.contains(op));
        }
    }

    @Test
    public void testAppOpsRemoval() throws Exception {
        mNotificationData.add(mRow.getEntry());
        ExpandableNotificationRow row2 = new NotificationTestHelper(getContext()).createRow();
        mNotificationData.add(row2.getEntry());

        ArraySet<Integer> expectedOps = new ArraySet<>();
        expectedOps.add(OP_CAMERA);
        expectedOps.add(OP_ACCEPT_HANDOVER);

        for (int op : expectedOps) {
            mNotificationData.updateAppOp(op, NotificationTestHelper.UID,
                    NotificationTestHelper.PKG, row2.getEntry().key, true);
        }

        expectedOps.remove(OP_ACCEPT_HANDOVER);
        mNotificationData.updateAppOp(OP_ACCEPT_HANDOVER, NotificationTestHelper.UID,
                NotificationTestHelper.PKG, row2.getEntry().key, false);

        assertTrue(mRow.getEntry().key + " doesn't have op " + OP_CAMERA,
                mNotificationData.get(mRow.getEntry().key).mActiveAppOps.contains(OP_CAMERA));
        assertTrue(row2.getEntry().key + " doesn't have op " + OP_CAMERA,
                mNotificationData.get(row2.getEntry().key).mActiveAppOps.contains(OP_CAMERA));
        assertFalse(mRow.getEntry().key + " has op " + OP_ACCEPT_HANDOVER,
                mNotificationData.get(mRow.getEntry().key)
                        .mActiveAppOps.contains(OP_ACCEPT_HANDOVER));
        assertFalse(row2.getEntry().key + " has op " + OP_ACCEPT_HANDOVER,
                mNotificationData.get(row2.getEntry().key)
                        .mActiveAppOps.contains(OP_ACCEPT_HANDOVER));
    }

    @Test
    public void testSuppressSystemAlertNotification() {
        when(mFsc.isSystemAlertWarningNeeded(anyInt(), anyString())).thenReturn(false);
        when(mFsc.isSystemAlertNotification(any())).thenReturn(true);
        StatusBarNotification sbn = mRow.getEntry().notification;
        Bundle bundle = new Bundle();
        bundle.putStringArray(Notification.EXTRA_FOREGROUND_APPS, new String[] {"something"});
        sbn.getNotification().extras = bundle;

        assertTrue(mNotificationData.shouldFilterOut(mRow.getEntry()));
    }

    @Test
    public void testDoNotSuppressSystemAlertNotification() {
        StatusBarNotification sbn = mRow.getEntry().notification;
        Bundle bundle = new Bundle();
        bundle.putStringArray(Notification.EXTRA_FOREGROUND_APPS, new String[] {"something"});
        sbn.getNotification().extras = bundle;

        when(mFsc.isSystemAlertWarningNeeded(anyInt(), anyString())).thenReturn(true);
        when(mFsc.isSystemAlertNotification(any())).thenReturn(true);

        assertFalse(mNotificationData.shouldFilterOut(mRow.getEntry()));

        when(mFsc.isSystemAlertWarningNeeded(anyInt(), anyString())).thenReturn(true);
        when(mFsc.isSystemAlertNotification(any())).thenReturn(false);

        assertFalse(mNotificationData.shouldFilterOut(mRow.getEntry()));

        when(mFsc.isSystemAlertWarningNeeded(anyInt(), anyString())).thenReturn(false);
        when(mFsc.isSystemAlertNotification(any())).thenReturn(false);

        assertFalse(mNotificationData.shouldFilterOut(mRow.getEntry()));
    }

    @Test
    public void testDoNotSuppressMalformedSystemAlertNotification() {
        when(mFsc.isSystemAlertWarningNeeded(anyInt(), anyString())).thenReturn(true);

        // missing extra
        assertFalse(mNotificationData.shouldFilterOut(mRow.getEntry()));

        StatusBarNotification sbn = mRow.getEntry().notification;
        Bundle bundle = new Bundle();
        bundle.putStringArray(Notification.EXTRA_FOREGROUND_APPS, new String[] {});
        sbn.getNotification().extras = bundle;

        // extra missing values
        assertFalse(mNotificationData.shouldFilterOut(mRow.getEntry()));
    }

    @Test
    public void testShouldFilterHiddenNotifications() {
        initStatusBarNotification(false);
        // setup
        when(mFsc.isSystemAlertWarningNeeded(anyInt(), anyString())).thenReturn(false);
        when(mFsc.isSystemAlertNotification(any())).thenReturn(false);

        // test should filter out hidden notifications:
        // hidden
        when(mMockStatusBarNotification.getKey()).thenReturn(TEST_HIDDEN_NOTIFICATION_KEY);
        NotificationData.Entry entry = new NotificationData.Entry(mMockStatusBarNotification);
        assertTrue(mNotificationData.shouldFilterOut(entry));

        // not hidden
        when(mMockStatusBarNotification.getKey()).thenReturn("not hidden");
        entry = new NotificationData.Entry(mMockStatusBarNotification);
        assertFalse(mNotificationData.shouldFilterOut(entry));
    }

    @Test
    public void testGetNotificationsForCurrentUser_shouldFilterNonCurrentUserNotifications()
            throws Exception {
        mNotificationData.add(mRow.getEntry());
        ExpandableNotificationRow row2 = new NotificationTestHelper(getContext()).createRow();
        mNotificationData.add(row2.getEntry());

        when(mEnvironment.isNotificationForCurrentProfiles(
                mRow.getEntry().notification)).thenReturn(false);
        when(mEnvironment.isNotificationForCurrentProfiles(
                row2.getEntry().notification)).thenReturn(true);
        ArrayList<NotificationData.Entry> result =
                mNotificationData.getNotificationsForCurrentUser();

        assertEquals(result.size(), 1);
        junit.framework.Assert.assertEquals(result.get(0), row2.getEntry());
    }

    @Test
    public void testIsExemptFromDndVisualSuppression_foreground() {
        initStatusBarNotification(false);
        when(mMockStatusBarNotification.getKey()).thenReturn(
                TEST_EXEMPT_DND_VISUAL_SUPPRESSION_KEY);
        Notification n = mMockStatusBarNotification.getNotification();
        n.flags = Notification.FLAG_FOREGROUND_SERVICE;
        NotificationData.Entry entry = new NotificationData.Entry(mMockStatusBarNotification);

        assertTrue(mNotificationData.isExemptFromDndVisualSuppression(entry));
        assertFalse(mNotificationData.shouldSuppressAmbient(entry));
    }

    @Test
    public void testIsExemptFromDndVisualSuppression_media() {
        initStatusBarNotification(false);
        when(mMockStatusBarNotification.getKey()).thenReturn(
                TEST_EXEMPT_DND_VISUAL_SUPPRESSION_KEY);
        Notification n = mMockStatusBarNotification.getNotification();
        Notification.Builder nb = Notification.Builder.recoverBuilder(mContext, n);
        nb.setStyle(new Notification.MediaStyle().setMediaSession(mock(MediaSession.Token.class)));
        n = nb.build();
        when(mMockStatusBarNotification.getNotification()).thenReturn(n);
        NotificationData.Entry entry = new NotificationData.Entry(mMockStatusBarNotification);

        assertTrue(mNotificationData.isExemptFromDndVisualSuppression(entry));
        assertFalse(mNotificationData.shouldSuppressAmbient(entry));
    }

    @Test
    public void testIsExemptFromDndVisualSuppression_system() {
        initStatusBarNotification(false);
        when(mMockStatusBarNotification.getKey()).thenReturn(
                TEST_EXEMPT_DND_VISUAL_SUPPRESSION_KEY);
        NotificationData.Entry entry = new NotificationData.Entry(mMockStatusBarNotification);
        entry.mIsSystemNotification = true;

        assertTrue(mNotificationData.isExemptFromDndVisualSuppression(entry));
        assertFalse(mNotificationData.shouldSuppressAmbient(entry));
    }

    @Test
    public void testIsNotExemptFromDndVisualSuppression_hiddenCategories() {
        initStatusBarNotification(false);
        when(mMockStatusBarNotification.getKey()).thenReturn(
                TEST_EXEMPT_DND_VISUAL_SUPPRESSION_KEY);
        NotificationData.Entry entry = new NotificationData.Entry(mMockStatusBarNotification);
        entry.mIsSystemNotification = true;
        when(mMockStatusBarNotification.getNotification()).thenReturn(
                new Notification.Builder(mContext, "").setCategory(CATEGORY_CALL).build());

        assertFalse(mNotificationData.isExemptFromDndVisualSuppression(entry));
        assertTrue(mNotificationData.shouldSuppressAmbient(entry));

        when(mMockStatusBarNotification.getNotification()).thenReturn(
                new Notification.Builder(mContext, "").setCategory(CATEGORY_REMINDER).build());

        assertFalse(mNotificationData.isExemptFromDndVisualSuppression(entry));

        when(mMockStatusBarNotification.getNotification()).thenReturn(
                new Notification.Builder(mContext, "").setCategory(CATEGORY_ALARM).build());

        assertFalse(mNotificationData.isExemptFromDndVisualSuppression(entry));

        when(mMockStatusBarNotification.getNotification()).thenReturn(
                new Notification.Builder(mContext, "").setCategory(CATEGORY_EVENT).build());

        assertFalse(mNotificationData.isExemptFromDndVisualSuppression(entry));

        when(mMockStatusBarNotification.getNotification()).thenReturn(
                new Notification.Builder(mContext, "").setCategory(CATEGORY_MESSAGE).build());

        assertFalse(mNotificationData.isExemptFromDndVisualSuppression(entry));
    }

    @Test
    public void testCreateNotificationDataEntry_RankingUpdate() {
        Ranking ranking = mock(Ranking.class);

        ArrayList<Notification.Action> smartActions = new ArrayList<>();
        smartActions.add(createAction());
        when(ranking.getSmartActions()).thenReturn(smartActions);

        when(ranking.getChannel()).thenReturn(NOTIFICATION_CHANNEL);

        when(ranking.getUserSentiment()).thenReturn(Ranking.USER_SENTIMENT_NEGATIVE);

        SnoozeCriterion snoozeCriterion = new SnoozeCriterion("id", "explanation", "confirmation");
        ArrayList<SnoozeCriterion> snoozeCriterions = new ArrayList<>();
        snoozeCriterions.add(snoozeCriterion);
        when(ranking.getSnoozeCriteria()).thenReturn(snoozeCriterions);

        NotificationData.Entry entry =
                new NotificationData.Entry(mMockStatusBarNotification, ranking);

        assertEquals(smartActions, entry.smartActions);
        assertEquals(NOTIFICATION_CHANNEL, entry.channel);
        assertEquals(Ranking.USER_SENTIMENT_NEGATIVE, entry.userSentiment);
        assertEquals(snoozeCriterions, entry.snoozeCriteria);
    }

    private void initStatusBarNotification(boolean allowDuringSetup) {
        Bundle bundle = new Bundle();
        bundle.putBoolean(Notification.EXTRA_ALLOW_DURING_SETUP, allowDuringSetup);
        Notification notification = new Notification.Builder(mContext, "test")
                .addExtras(bundle)
                .build();
        when(mMockStatusBarNotification.getNotification()).thenReturn(notification);
    }

    private class TestableNotificationData extends NotificationData {
        public TestableNotificationData() {
            super();
        }

        @Override
        protected boolean getRanking(String key, Ranking outRanking) {
            super.getRanking(key, outRanking);
            if (key.equals(TEST_HIDDEN_NOTIFICATION_KEY)) {
                outRanking.populate(key, outRanking.getRank(),
                        outRanking.matchesInterruptionFilter(),
                        outRanking.getVisibilityOverride(), outRanking.getSuppressedVisualEffects(),
                        outRanking.getImportance(), outRanking.getImportanceExplanation(),
                        outRanking.getOverrideGroupKey(), outRanking.getChannel(), null, null,
                        outRanking.canShowBadge(), outRanking.getUserSentiment(), true,
                        false, false, null, null);
            } else if (key.equals(TEST_EXEMPT_DND_VISUAL_SUPPRESSION_KEY)) {
                outRanking.populate(key, outRanking.getRank(),
                        outRanking.matchesInterruptionFilter(),
                        outRanking.getVisibilityOverride(), 255,
                        outRanking.getImportance(), outRanking.getImportanceExplanation(),
                        outRanking.getOverrideGroupKey(), outRanking.getChannel(), null, null,
                        outRanking.canShowBadge(), outRanking.getUserSentiment(), true, false,
                        false, null, null);
            } else {
                outRanking.populate(key, outRanking.getRank(),
                        outRanking.matchesInterruptionFilter(),
                        outRanking.getVisibilityOverride(), outRanking.getSuppressedVisualEffects(),
                        outRanking.getImportance(), outRanking.getImportanceExplanation(),
                        outRanking.getOverrideGroupKey(), NOTIFICATION_CHANNEL, null, null,
                        outRanking.canShowBadge(), outRanking.getUserSentiment(), false, false,
                        false, null, null);
            }
            return true;
        }
    }

    private Notification.Action createAction() {
        return new Notification.Action.Builder(
                Icon.createWithResource(getContext(), android.R.drawable.sym_def_app_icon),
                "action",
                PendingIntent.getBroadcast(getContext(), 0, new Intent("Action"), 0)).build();
    }
}
