/*
 * 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 com.android.server.notification;

import static android.app.role.RoleManager.ROLE_DIALER;
import static android.app.role.RoleManager.ROLE_EMERGENCY;
import static android.app.role.RoleManager.ROLE_SMS;
import static android.content.pm.PackageManager.MATCH_ALL;

import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertTrue;

import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import android.app.ActivityManager;
import android.app.AppOpsManager;
import android.app.IActivityManager;
import android.app.IUriGrantsManager;
import android.app.admin.DevicePolicyManagerInternal;
import android.app.role.RoleManager;
import android.app.usage.UsageStatsManagerInternal;
import android.companion.ICompanionDeviceManager;
import android.content.Context;
import android.content.pm.IPackageManager;
import android.content.pm.PackageManager;
import android.content.pm.UserInfo;
import android.os.Looper;
import android.os.UserHandle;
import android.os.UserManager;
import android.test.suitebuilder.annotation.SmallTest;
import android.testing.AndroidTestingRunner;
import android.testing.TestableContext;
import android.testing.TestableLooper.RunWithLooper;
import android.util.ArraySet;
import android.util.AtomicFile;
import android.util.Pair;

import com.android.server.LocalServices;
import com.android.server.UiServiceTestCase;
import com.android.server.lights.LightsManager;
import com.android.server.notification.NotificationManagerService.NotificationAssistants;
import com.android.server.notification.NotificationManagerService.NotificationListeners;
import com.android.server.uri.UriGrantsManagerInternal;
import com.android.server.wm.WindowManagerInternal;

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

@SmallTest
@RunWith(AndroidTestingRunner.class)
@RunWithLooper
public class RoleObserverTest extends UiServiceTestCase {
    private TestableNotificationManagerService mService;
    private NotificationManagerService.RoleObserver mRoleObserver;

    private TestableContext mContext = spy(getContext());

    @Mock
    private PreferencesHelper mPreferencesHelper;
    @Mock
    private IPackageManager mPm;
    @Mock
    private UserManager mUm;
    @Mock
    private Executor mExecutor;
    @Mock
    private RoleManager mRoleManager;

    private List<UserInfo> mUsers;

    private static class TestableNotificationManagerService extends NotificationManagerService {

        TestableNotificationManagerService(Context context) {
            super(context);
        }

        @Override
        protected void handleSavePolicyFile() {
            return;
        }

        @Override
        protected void loadPolicyFile() {
            return;
        }
    }

    @Before
    public void setUp() throws Exception {
        MockitoAnnotations.initMocks(this);

        LocalServices.removeServiceForTest(WindowManagerInternal.class);
        LocalServices.addService(WindowManagerInternal.class, mock(WindowManagerInternal.class));
        mContext.addMockSystemService(AppOpsManager.class, mock(AppOpsManager.class));

        mUsers = new ArrayList<>();
        mUsers.add(new UserInfo(0, "system", 0));
        mUsers.add(new UserInfo(10, "second", 0));
        when(mUm.getUsers()).thenReturn(mUsers);

        mService = new TestableNotificationManagerService(mContext);
        mRoleObserver = mService.new RoleObserver(mRoleManager, mPm, mExecutor);

        try {
            mService.init(mService.new WorkerHandler(mock(Looper.class)),
                    mock(RankingHandler.class),
                    mock(IPackageManager.class), mock(PackageManager.class),
                    mock(LightsManager.class),
                    mock(NotificationListeners.class), mock(NotificationAssistants.class),
                    mock(ConditionProviders.class), mock(ICompanionDeviceManager.class),
                    mock(SnoozeHelper.class), mock(NotificationUsageStats.class),
                    mock(AtomicFile.class), mock(ActivityManager.class),
                    mock(GroupHelper.class), mock(IActivityManager.class),
                    mock(UsageStatsManagerInternal.class),
                    mock(DevicePolicyManagerInternal.class), mock(IUriGrantsManager.class),
                    mock(UriGrantsManagerInternal.class),
                    mock(AppOpsManager.class), mUm, mock(NotificationHistoryManager.class));
        } catch (SecurityException e) {
            if (!e.getMessage().contains("Permission Denial: not allowed to send broadcast")) {
                throw e;
            }
        }
        mService.setPreferencesHelper(mPreferencesHelper);
    }

    @Test
    public void testInit() throws Exception {
        List<String> dialer0 = new ArrayList<>();
        dialer0.add("dialer");
        List<String> emer0 = new ArrayList<>();
        emer0.add("emergency");

        ArraySet<Pair<String, Integer>> dialer0Pair = new ArraySet<>();
        dialer0Pair.add(new Pair("dialer", 30));
        when(mPm.getPackageUid("dialer", MATCH_ALL, 0)).thenReturn(30);

        ArraySet<Pair<String, Integer>> emer0Pair = new ArraySet<>();
        emer0Pair.add(new Pair("emergency", 40));
        when(mPm.getPackageUid("emergency", MATCH_ALL, 0)).thenReturn(40);


        when(mRoleManager.getRoleHoldersAsUser(
                ROLE_DIALER,
                mUsers.get(0).getUserHandle())).
                thenReturn(dialer0);
        when(mRoleManager.getRoleHoldersAsUser(
                ROLE_EMERGENCY,
                mUsers.get(0).getUserHandle())).
                thenReturn(emer0);

        mRoleObserver.init();

        // verify internal records of current state of the world
        assertTrue(mRoleObserver.isApprovedPackageForRoleForUser(
                ROLE_DIALER, dialer0.get(0), mUsers.get(0).id));
        assertFalse(mRoleObserver.isApprovedPackageForRoleForUser(
                ROLE_DIALER, dialer0.get(0), mUsers.get(1).id));

        assertTrue(mRoleObserver.isApprovedPackageForRoleForUser(
                ROLE_EMERGENCY, emer0.get(0), mUsers.get(0).id));
        assertFalse(mRoleObserver.isApprovedPackageForRoleForUser(
                ROLE_EMERGENCY, emer0.get(0), mUsers.get(1).id));

        // make sure we're listening to updates
        verify(mRoleManager, times(1)).addOnRoleHoldersChangedListenerAsUser(
                eq(mExecutor), any(), eq(UserHandle.ALL));

        // make sure we told pref helper about the state of the world
        verify(mPreferencesHelper, times(1)).updateDefaultApps(0, null, dialer0Pair);
        verify(mPreferencesHelper, times(1)).updateDefaultApps(0, null, emer0Pair);
    }

    @Test
    public void testSwapDefault() throws Exception {
        List<String> dialer0 = new ArrayList<>();
        dialer0.add("dialer");

        when(mRoleManager.getRoleHoldersAsUser(
                ROLE_DIALER,
                mUsers.get(0).getUserHandle())).
                thenReturn(dialer0);

        mRoleObserver.init();

        List<String> newDefault = new ArrayList<>();
        newDefault.add("phone");

        ArraySet<Pair<String, Integer>> newDefaultPair = new ArraySet<>();
        newDefaultPair.add(new Pair("phone", 30));
        when(mPm.getPackageUid("phone", MATCH_ALL, 0)).thenReturn(30);

        when(mRoleManager.getRoleHoldersAsUser(
                ROLE_DIALER,
                mUsers.get(0).getUserHandle())).
                thenReturn(newDefault);

        mRoleObserver.onRoleHoldersChanged(ROLE_DIALER, UserHandle.of(0));

        verify(mPreferencesHelper, times(1)).updateDefaultApps(
                0, new ArraySet<>(dialer0), newDefaultPair);
    }

    @Test
    public void testSwapDefault_multipleOverlappingApps() throws Exception {
        List<String> dialer0 = new ArrayList<>();
        dialer0.add("dialer");
        dialer0.add("phone");

        when(mRoleManager.getRoleHoldersAsUser(
                ROLE_DIALER,
                mUsers.get(0).getUserHandle())).
                thenReturn(dialer0);

        mRoleObserver.init();

        assertTrue(mRoleObserver.isApprovedPackageForRoleForUser(ROLE_DIALER, "phone", 0));
        assertFalse(mRoleObserver.isApprovedPackageForRoleForUser(ROLE_DIALER, "emerPhone", 0));
        assertTrue(mRoleObserver.isApprovedPackageForRoleForUser(ROLE_DIALER, "dialer", 0));

        List<String> newDefault = new ArrayList<>();
        newDefault.add("phone");
        newDefault.add("emerPhone");

        when(mRoleManager.getRoleHoldersAsUser(
                ROLE_DIALER,
                mUsers.get(0).getUserHandle())).
                thenReturn(newDefault);

        ArraySet<String> expectedRemove = new ArraySet<>();
        expectedRemove.add("dialer");

        ArraySet<Pair<String, Integer>> expectedAddPair = new ArraySet<>();
        expectedAddPair.add(new Pair("emerPhone", 30));
        when(mPm.getPackageUid("emerPhone", MATCH_ALL, 0)).thenReturn(30);

        mRoleObserver.onRoleHoldersChanged(ROLE_DIALER, UserHandle.of(0));

        verify(mPreferencesHelper, times(1)).updateDefaultApps(
                0, expectedRemove, expectedAddPair);

        assertTrue(mRoleObserver.isApprovedPackageForRoleForUser(ROLE_DIALER, "phone", 0));
        assertTrue(mRoleObserver.isApprovedPackageForRoleForUser(ROLE_DIALER, "emerPhone", 0));
        assertFalse(mRoleObserver.isApprovedPackageForRoleForUser(ROLE_DIALER, "dialer", 0));
    }

    @Test
    public void testSwapDefault_newUser() throws Exception {
        List<String> dialer0 = new ArrayList<>();
        dialer0.add("dialer");

        when(mRoleManager.getRoleHoldersAsUser(
                ROLE_DIALER,
                mUsers.get(0).getUserHandle())).
                thenReturn(dialer0);

        mRoleObserver.init();

        List<String> dialer10 = new ArrayList<>();
        dialer10.add("phone");

        when(mRoleManager.getRoleHoldersAsUser(
                ROLE_DIALER,
                mUsers.get(1).getUserHandle())).
                thenReturn(dialer10);

        ArraySet<Pair<String, Integer>> expectedAddPair = new ArraySet<>();
        expectedAddPair.add(new Pair("phone", 30));
        when(mPm.getPackageUid("phone", MATCH_ALL, 10)).thenReturn(30);

        mRoleObserver.onRoleHoldersChanged(ROLE_DIALER, UserHandle.of(10));

        ArraySet<String> expectedRemove = new ArraySet<>();
        ArraySet<String> expectedAdd = new ArraySet<>();
        expectedAdd.add("phone");

        verify(mPreferencesHelper, times(1)).updateDefaultApps(
                10, expectedRemove, expectedAddPair);

        assertTrue(mRoleObserver.isApprovedPackageForRoleForUser(ROLE_DIALER, "phone", 10));
        assertTrue(mRoleObserver.isApprovedPackageForRoleForUser(ROLE_DIALER, "dialer", 0));
    }
}
