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

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

import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.media.session.MediaSession;
import android.os.Build;
import android.os.UserHandle;
import android.provider.Settings;
import android.service.notification.StatusBarNotification;
import android.telecom.TelecomManager;
import android.support.test.runner.AndroidJUnit4;
import android.test.suitebuilder.annotation.SmallTest;

import com.android.server.UiServiceTestCase;

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;
import java.util.Collections;
import java.util.List;

@SmallTest
@RunWith(AndroidJUnit4.class)
public class NotificationComparatorTest extends UiServiceTestCase {
    @Mock Context mContext;
    @Mock TelecomManager mTm;
    @Mock RankingHandler handler;
    @Mock PackageManager mPm;

    private final String callPkg = "com.android.server.notification";
    private final int callUid = 10;
    private String smsPkg;
    private final int smsUid = 11;
    private final String pkg2 = "pkg2";
    private final int uid2 = 1111111;
    private static final String TEST_CHANNEL_ID = "test_channel_id";

    private NotificationRecord mRecordMinCall;
    private NotificationRecord mRecordHighCall;
    private NotificationRecord mRecordDefaultMedia;
    private NotificationRecord mRecordEmail;
    private NotificationRecord mRecordInlineReply;
    private NotificationRecord mRecordSms;
    private NotificationRecord mRecordStarredContact;
    private NotificationRecord mRecordContact;
    private NotificationRecord mRecordUrgent;
    private NotificationRecord mRecordCheater;
    private NotificationRecord mRecordCheaterColorized;
    private NotificationRecord mNoMediaSessionMedia;

    @Before
    public void setUp() {
        MockitoAnnotations.initMocks(this);
        int userId = UserHandle.myUserId();

        when(mContext.getResources()).thenReturn(getContext().getResources());
        when(mContext.getContentResolver()).thenReturn(getContext().getContentResolver());
        when(mContext.getPackageManager()).thenReturn(mPm);
        when(mContext.getSystemService(eq(Context.TELECOM_SERVICE))).thenReturn(mTm);
        when(mTm.getDefaultDialerPackage()).thenReturn(callPkg);
        final ApplicationInfo legacy = new ApplicationInfo();
        legacy.targetSdkVersion = Build.VERSION_CODES.N_MR1;
        try {
            when(mPm.getApplicationInfoAsUser(anyString(), anyInt(), anyInt())).thenReturn(legacy);
            when(mContext.getApplicationInfo()).thenReturn(legacy);
        } catch (PackageManager.NameNotFoundException e) {
            // let's hope not
        }

        smsPkg = Settings.Secure.getString(mContext.getContentResolver(),
                Settings.Secure.SMS_DEFAULT_APPLICATION);

        Notification n1 = new Notification.Builder(mContext, TEST_CHANNEL_ID)
                .setCategory(Notification.CATEGORY_CALL)
                .setFlag(Notification.FLAG_FOREGROUND_SERVICE, true)
                .build();
        mRecordMinCall = new NotificationRecord(mContext, new StatusBarNotification(callPkg,
                callPkg, 1, "minCall", callUid, callUid, n1,
                new UserHandle(userId), "", 2000), getDefaultChannel());
        mRecordMinCall.setUserImportance(NotificationManager.IMPORTANCE_MIN);

        Notification n2 = new Notification.Builder(mContext, TEST_CHANNEL_ID)
                .setCategory(Notification.CATEGORY_CALL)
                .setFlag(Notification.FLAG_FOREGROUND_SERVICE, true)
                .setColorized(true /* colorized */)
                .build();
        mRecordHighCall = new NotificationRecord(mContext, new StatusBarNotification(callPkg,
                callPkg, 1, "highcall", callUid, callUid, n2,
                new UserHandle(userId), "", 1999), getDefaultChannel());
        mRecordHighCall.setUserImportance(NotificationManager.IMPORTANCE_HIGH);

        Notification n3 = new Notification.Builder(mContext, TEST_CHANNEL_ID)
                .setStyle(new Notification.MediaStyle()
                        .setMediaSession(new MediaSession.Token(null)))
                .build();
        mRecordDefaultMedia = new NotificationRecord(mContext, new StatusBarNotification(pkg2,
                pkg2, 1, "media", uid2, uid2, n3, new UserHandle(userId),
                "", 1499), getDefaultChannel());
        mRecordDefaultMedia.setUserImportance(NotificationManager.IMPORTANCE_DEFAULT);

        Notification n4 = new Notification.Builder(mContext, TEST_CHANNEL_ID)
                .setStyle(new Notification.MessagingStyle("sender!")).build();
        mRecordInlineReply = new NotificationRecord(mContext, new StatusBarNotification(pkg2,
                pkg2, 1, "inlinereply", uid2, uid2, n4, new UserHandle(userId),
                "", 1599), getDefaultChannel());
        mRecordInlineReply.setUserImportance(NotificationManager.IMPORTANCE_HIGH);
        mRecordInlineReply.setPackagePriority(Notification.PRIORITY_MAX);

        Notification n5 = new Notification.Builder(mContext, TEST_CHANNEL_ID)
                .setCategory(Notification.CATEGORY_MESSAGE).build();
        mRecordSms = new NotificationRecord(mContext, new StatusBarNotification(smsPkg,
                smsPkg, 1, "sms", smsUid, smsUid, n5, new UserHandle(userId),
                "", 1299), getDefaultChannel());
        mRecordSms.setUserImportance(NotificationManager.IMPORTANCE_DEFAULT);

        Notification n6 = new Notification.Builder(mContext, TEST_CHANNEL_ID).build();
        mRecordStarredContact = new NotificationRecord(mContext, new StatusBarNotification(pkg2,
                pkg2, 1, "starred", uid2, uid2, n6, new UserHandle(userId),
                "", 1259), getDefaultChannel());
        mRecordStarredContact.setContactAffinity(ValidateNotificationPeople.STARRED_CONTACT);
        mRecordStarredContact.setUserImportance(NotificationManager.IMPORTANCE_DEFAULT);

        Notification n7 = new Notification.Builder(mContext, TEST_CHANNEL_ID).build();
        mRecordContact = new NotificationRecord(mContext, new StatusBarNotification(pkg2,
                pkg2, 1, "contact", uid2, uid2, n7, new UserHandle(userId),
                "", 1259), getDefaultChannel());
        mRecordContact.setContactAffinity(ValidateNotificationPeople.VALID_CONTACT);
        mRecordContact.setUserImportance(NotificationManager.IMPORTANCE_DEFAULT);

        Notification n8 = new Notification.Builder(mContext, TEST_CHANNEL_ID).build();
        mRecordUrgent = new NotificationRecord(mContext, new StatusBarNotification(pkg2,
                pkg2, 1, "urgent", uid2, uid2, n8, new UserHandle(userId),
                "", 1258), getDefaultChannel());
        mRecordUrgent.setUserImportance(NotificationManager.IMPORTANCE_HIGH);

        Notification n9 = new Notification.Builder(mContext, TEST_CHANNEL_ID)
                .setCategory(Notification.CATEGORY_MESSAGE)
                .setFlag(Notification.FLAG_ONGOING_EVENT
                        |Notification.FLAG_FOREGROUND_SERVICE, true)
                .build();
        mRecordCheater = new NotificationRecord(mContext, new StatusBarNotification(pkg2,
                pkg2, 1, "cheater", uid2, uid2, n9, new UserHandle(userId),
                "", 9258), getDefaultChannel());
        mRecordCheater.setUserImportance(NotificationManager.IMPORTANCE_LOW);
        mRecordCheater.setPackagePriority(Notification.PRIORITY_MAX);

        Notification n10 = new Notification.Builder(mContext, TEST_CHANNEL_ID)
                .setStyle(new Notification.InboxStyle().setSummaryText("message!")).build();
        mRecordEmail = new NotificationRecord(mContext, new StatusBarNotification(pkg2,
                pkg2, 1, "email", uid2, uid2, n10, new UserHandle(userId),
                "", 1599), getDefaultChannel());
        mRecordEmail.setUserImportance(NotificationManager.IMPORTANCE_HIGH);

        Notification n11 = new Notification.Builder(mContext, TEST_CHANNEL_ID)
                .setCategory(Notification.CATEGORY_MESSAGE)
                .setColorized(true)
                .build();
        mRecordCheaterColorized = new NotificationRecord(mContext, new StatusBarNotification(pkg2,
                pkg2, 1, "cheater", uid2, uid2, n11, new UserHandle(userId),
                "", 9258), getDefaultChannel());
        mRecordCheaterColorized.setUserImportance(NotificationManager.IMPORTANCE_LOW);

        Notification n12 = new Notification.Builder(mContext, TEST_CHANNEL_ID)
                .setCategory(Notification.CATEGORY_MESSAGE)
                .setColorized(true)
                .setStyle(new Notification.MediaStyle())
                .build();
        mNoMediaSessionMedia = new NotificationRecord(mContext, new StatusBarNotification(
                pkg2, pkg2, 1, "cheater", uid2, uid2, n12, new UserHandle(userId),
                "", 9258), getDefaultChannel());
        mNoMediaSessionMedia.setUserImportance(NotificationManager.IMPORTANCE_DEFAULT);
    }

    @Test
    public void testOrdering() throws Exception {
        final List<NotificationRecord> expected = new ArrayList<>();
        expected.add(mRecordHighCall);
        expected.add(mRecordDefaultMedia);
        expected.add(mRecordInlineReply);
        expected.add(mRecordSms);
        expected.add(mRecordStarredContact);
        expected.add(mRecordContact);
        expected.add(mRecordEmail);
        expected.add(mRecordUrgent);
        expected.add(mNoMediaSessionMedia);
        expected.add(mRecordCheater);
        expected.add(mRecordCheaterColorized);
        expected.add(mRecordMinCall);

        List<NotificationRecord> actual = new ArrayList<>();
        actual.addAll(expected);
        Collections.shuffle(actual);

        Collections.sort(actual, new NotificationComparator(mContext));

        assertEquals(expected, actual);
    }

    @Test
    public void testMessaging() throws Exception {
        NotificationComparator comp = new NotificationComparator(mContext);
        assertTrue(comp.isImportantMessaging(mRecordInlineReply));
        assertTrue(comp.isImportantMessaging(mRecordSms));
        assertFalse(comp.isImportantMessaging(mRecordEmail));
        assertFalse(comp.isImportantMessaging(mRecordCheater));
    }

    @Test
    public void testPeople() throws Exception {
        NotificationComparator comp = new NotificationComparator(mContext);
        assertTrue(comp.isImportantPeople(mRecordStarredContact));
        assertTrue(comp.isImportantPeople(mRecordContact));
    }

    private NotificationChannel getDefaultChannel() {
        return new NotificationChannel(NotificationChannel.DEFAULT_CHANNEL_ID, "name",
                NotificationManager.IMPORTANCE_LOW);
    }
}
