/*
 * 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.settings.search;

import static com.google.common.truth.Truth.assertThat;

import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyBoolean;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.anyString;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.only;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;

import android.accessibilityservice.AccessibilityServiceInfo;
import android.app.Activity;
import android.app.Application;
import android.app.LoaderManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.Loader;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
import android.database.ContentObserver;
import android.hardware.input.InputManager;
import android.net.Uri;
import android.os.Bundle;
import android.print.PrintManager;
import android.print.PrintServicesLoader;
import android.printservice.PrintServiceInfo;
import android.provider.Settings;
import android.provider.UserDictionary;
import android.view.inputmethod.InputMethodInfo;

import com.android.internal.content.PackageMonitor;
import com.android.settings.SettingsRobolectricTestRunner;
import com.android.settings.TestConfig;
import com.android.settings.accessibility.AccessibilitySettings;
import com.android.settings.inputmethod.AvailableVirtualKeyboardFragment;
import com.android.settings.inputmethod.PhysicalKeyboardFragment;
import com.android.settings.inputmethod.VirtualKeyboardFragment;
import com.android.settings.language.LanguageAndInputSettings;
import com.android.settings.print.PrintSettingsFragment;
import com.android.settings.search2.DatabaseIndexingManager;
import com.android.settings.testutils.DatabaseTestUtils;
import com.android.settings.testutils.shadow.ShadowActivityWithLoadManager;
import com.android.settings.testutils.shadow.ShadowContextImplWithRegisterReceiver;
import com.android.settings.testutils.shadow.ShadowInputManager;
import com.android.settings.testutils.shadow.ShadowInputMethodManagerWithMethodList;
import com.android.settings.testutils.shadow.ShadowPackageMonitor;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.Robolectric;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
import org.robolectric.internal.ShadowExtractor;
import org.robolectric.res.builder.RobolectricPackageManager;
import org.robolectric.shadows.ShadowAccessibilityManager;
import org.robolectric.shadows.ShadowApplication;
import org.robolectric.shadows.ShadowContentResolver;
import org.xmlpull.v1.XmlPullParserException;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;

@RunWith(SettingsRobolectricTestRunner.class)
@Config(
        manifest = TestConfig.MANIFEST_PATH,
        sdk = TestConfig.SDK_VERSION,
        shadows = {
                ShadowActivityWithLoadManager.class,
                ShadowContextImplWithRegisterReceiver.class,
                ShadowInputManager.class,
                ShadowInputMethodManagerWithMethodList.class,
                ShadowPackageMonitor.class,
        }
)
public class DynamicIndexableContentMonitorTest {

    private static final int LOADER_ID = 1234;
    private static final String A11Y_PACKAGE_1 = "a11y-1";
    private static final String A11Y_PACKAGE_2 = "a11y-2";
    private static final String IME_PACKAGE_1 = "ime-1";
    private static final String IME_PACKAGE_2 = "ime-2";

    @Mock
    private LoaderManager mLoaderManager;
    @Mock
    private DatabaseIndexingManager mIndexManager;

    private Activity mActivity;
    private InputManager mInputManager;

    private ShadowContextImplWithRegisterReceiver mShadowContextImpl;
    private ShadowActivityWithLoadManager mShadowActivity;
    private ShadowAccessibilityManager mShadowAccessibilityManager;
    private ShadowInputMethodManagerWithMethodList mShadowInputMethodManager;
    private RobolectricPackageManager mRobolectricPackageManager;

    private final DynamicIndexableContentMonitor mMonitor = new DynamicIndexableContentMonitor();

    @Before
    public void setUp() {
        MockitoAnnotations.initMocks(this);
        mActivity = Robolectric.buildActivity(Activity.class).get();
        mInputManager = InputManager.getInstance();

        // Robolectric shadows.
        mShadowContextImpl = (ShadowContextImplWithRegisterReceiver) ShadowExtractor.extract(
                ((Application) ShadowApplication.getInstance().getApplicationContext())
                .getBaseContext());
        mShadowActivity = (ShadowActivityWithLoadManager) ShadowExtractor.extract(mActivity);
        mShadowAccessibilityManager = (ShadowAccessibilityManager) ShadowExtractor.extract(
                mActivity.getSystemService(Context.ACCESSIBILITY_SERVICE));
        mShadowInputMethodManager = (ShadowInputMethodManagerWithMethodList) ShadowExtractor
                .extract(mActivity.getSystemService(Context.INPUT_METHOD_SERVICE));
        mRobolectricPackageManager = RuntimeEnvironment.getRobolectricPackageManager();

        // Setup shadows.
        mShadowContextImpl.setSystemService(Context.PRINT_SERVICE, mock(PrintManager.class));
        mShadowContextImpl.setSystemService(Context.INPUT_SERVICE, mInputManager);
        mShadowActivity.setLoaderManager(mLoaderManager);
        mShadowAccessibilityManager.setInstalledAccessibilityServiceList(Collections.emptyList());
        mShadowInputMethodManager.setInputMethodList(Collections.emptyList());
        mRobolectricPackageManager.setSystemFeature(PackageManager.FEATURE_PRINTING, true);
        mRobolectricPackageManager.setSystemFeature(PackageManager.FEATURE_INPUT_METHODS, true);
    }

    @After
    public void shutDown() {
        mMonitor.unregister(mActivity, LOADER_ID);
        // BroadcastReceiver must be unregistered.
        assertThat(extractPackageMonitor()).isNull();

        DynamicIndexableContentMonitor.resetForTesting();
        mRobolectricPackageManager.reset();

        DatabaseTestUtils.clearDb();
    }

    @Test
    public void testLockedUser() {
        mMonitor.register(mActivity, LOADER_ID, mIndexManager, false /* isUserUnlocked */);

        // No loader procedure happens.
        verify(mLoaderManager, never()).initLoader(
                anyInt(), any(Bundle.class), any(LoaderManager.LoaderCallbacks.class));
        // No indexing happens.
        verify(mIndexManager, never()).updateFromClassNameResource(
                anyString(), anyBoolean());

        mMonitor.unregister(mActivity, LOADER_ID);

        // No destroy loader should happen.
        verify(mLoaderManager, never()).destroyLoader(anyInt());
    }

    @Test
    public void testWithNoPrintingFeature() {
        mRobolectricPackageManager.setSystemFeature(PackageManager.FEATURE_PRINTING, false);

        mMonitor.register(mActivity, LOADER_ID, mIndexManager, true /* isUserUnlocked */);

        // No loader procedure happens.
        verify(mLoaderManager, never()).initLoader(
                anyInt(), any(Bundle.class), any(LoaderManager.LoaderCallbacks.class));
        verifyNoIndexing(PrintSettingsFragment.class);

        mMonitor.unregister(mActivity, LOADER_ID);

        // No destroy loader should happen.
        verify(mLoaderManager, never()).destroyLoader(anyInt());
        // BroadcastReceiver must be unregistered.
        assertThat(extractPackageMonitor()).isNull();

        // To suppress spurious test fail in {@link #shutDown()}.
        mMonitor.register(mActivity, LOADER_ID, mIndexManager, true /* isUserUnlocked */);
    }

    @Test
    public void testPrinterServiceIndex() {
        mMonitor.register(mActivity, LOADER_ID, mIndexManager, true /* isUserUnlocked */);

        // Loader procedure happens.
        verify(mLoaderManager, only()).initLoader(LOADER_ID, null, mMonitor);

        // Loading print services happens.
        final Loader<List<PrintServiceInfo>> loader =
                mMonitor.onCreateLoader(LOADER_ID, null /* args */);
        assertThat(loader).isInstanceOf(PrintServicesLoader.class);
        verifyNoIndexing(PrintSettingsFragment.class);

        mMonitor.onLoadFinished(loader, Collections.emptyList());

        verifyIncrementalIndexing(PrintSettingsFragment.class);
    }

    @Test
    public void testInputDevicesMonitor() {
        mMonitor.register(mActivity, LOADER_ID, mIndexManager, true /* isUserUnlocked */);

        // Rebuild indexing should happen.
        verifyIncrementalIndexing(PhysicalKeyboardFragment.class);
        // Input monitor should be registered to InputManager.
        final InputManager.InputDeviceListener listener = extactInputDeviceListener();
        assertThat(listener).isNotNull();

        /*
         * Nothing happens on successive register calls.
         */
        mMonitor.unregister(mActivity, LOADER_ID);
        reset(mIndexManager);

        mMonitor.register(mActivity, LOADER_ID, mIndexManager, true /* isUserUnlocked */);

        verifyNoIndexing(PhysicalKeyboardFragment.class);
        assertThat(extactInputDeviceListener()).isEqualTo(listener);

        /*
         * A device is added.
         */
        reset(mIndexManager);

        listener.onInputDeviceAdded(1 /* deviceId */);

        verifyIncrementalIndexing(PhysicalKeyboardFragment.class);

        /*
         * A device is removed.
         */
        reset(mIndexManager);

        listener.onInputDeviceRemoved(2 /* deviceId */);

        verifyIncrementalIndexing(PhysicalKeyboardFragment.class);

        /*
         * A device is changed.
         */
        reset(mIndexManager);

        listener.onInputDeviceChanged(3 /* deviceId */);

        verifyIncrementalIndexing(PhysicalKeyboardFragment.class);
    }

    @Test
    public void testAccessibilityServicesMonitor() throws Exception {
        mMonitor.register(mActivity, LOADER_ID, mIndexManager, true /* isUserUnlocked */);

        verifyIncrementalIndexing(AccessibilitySettings.class);

        /*
         * When an accessibility service package is installed, incremental indexing happen.
         */
        reset(mIndexManager);

        installAccessibilityService(A11Y_PACKAGE_1);

        verifyIncrementalIndexing(AccessibilitySettings.class);

        /*
         * When another accessibility service package is installed, incremental indexing happens.
         */
        reset(mIndexManager);

        installAccessibilityService(A11Y_PACKAGE_2);

        verifyIncrementalIndexing(AccessibilitySettings.class);

        /*
         * When an accessibility service is disabled, rebuild indexing happens.
         */
        reset(mIndexManager);

        disableInstalledPackage(A11Y_PACKAGE_1);

        verifyIncrementalIndexing(AccessibilitySettings.class);

        /*
         * When an accessibility service is enabled, incremental indexing happens.
         */
        reset(mIndexManager);

        enableInstalledPackage(A11Y_PACKAGE_1);

        verifyIncrementalIndexing(AccessibilitySettings.class);

        /*
         * When an accessibility service package is uninstalled, rebuild indexing happens.
         */
        reset(mIndexManager);

        uninstallAccessibilityService(A11Y_PACKAGE_1);

        verifyIncrementalIndexing(AccessibilitySettings.class);

        /*
         * When an input method service package is installed, nothing happens.
         */
        reset(mIndexManager);

        installInputMethodService(IME_PACKAGE_1);

        verifyNoIndexing(AccessibilitySettings.class);
    }

    @Test
    public void testInputMethodServicesMonitor() throws Exception {
        mMonitor.register(mActivity, LOADER_ID, mIndexManager, true /* isUserUnlocked */);

        verifyIncrementalIndexing(VirtualKeyboardFragment.class);
        verifyIncrementalIndexing(AvailableVirtualKeyboardFragment.class);

        final Uri enabledInputMethodsContentUri = Settings.Secure.getUriFor(
                Settings.Secure.ENABLED_INPUT_METHODS);
        // Content observer should be registered.
        final ContentObserver observer = extractContentObserver(enabledInputMethodsContentUri);
        assertThat(observer).isNotNull();

        /*
         * When an input method service package is installed, incremental indexing happen.
         */
        reset(mIndexManager);

        installInputMethodService(IME_PACKAGE_1);

        verifyIncrementalIndexing(VirtualKeyboardFragment.class);
        verifyIncrementalIndexing(AvailableVirtualKeyboardFragment.class);

        /*
         * When another input method service package is installed, incremental indexing happens.
         */
        reset(mIndexManager);

        installInputMethodService(IME_PACKAGE_2);

        verifyIncrementalIndexing(VirtualKeyboardFragment.class);
        verifyIncrementalIndexing(AvailableVirtualKeyboardFragment.class);

        /*
         * When an input method service is disabled, rebuild indexing happens.
         */
        reset(mIndexManager);

        disableInstalledPackage(IME_PACKAGE_1);

        verifyIncrementalIndexing(VirtualKeyboardFragment.class);
        verifyIncrementalIndexing(AvailableVirtualKeyboardFragment.class);

        /*
         * When an input method service is enabled, incremental indexing happens.
         */
        reset(mIndexManager);

        enableInstalledPackage(IME_PACKAGE_1);

        verifyIncrementalIndexing(VirtualKeyboardFragment.class);
        verifyIncrementalIndexing(AvailableVirtualKeyboardFragment.class);

        /*
         * When an input method service package is uninstalled, rebuild indexing happens.
         */
        reset(mIndexManager);

        uninstallInputMethodService(IME_PACKAGE_1);

        verifyIncrementalIndexing(VirtualKeyboardFragment.class);
        verifyIncrementalIndexing(AvailableVirtualKeyboardFragment.class);

        /*
         * When an accessibility service package is installed, nothing happens.
         */
        reset(mIndexManager);

        installAccessibilityService(A11Y_PACKAGE_1);

        verifyNoIndexing(VirtualKeyboardFragment.class);
        verifyNoIndexing(AvailableVirtualKeyboardFragment.class);

        /*
         * When enabled IMEs list is changed, rebuild indexing happens.
         */
        reset(mIndexManager);

        observer.onChange(false /* selfChange */, enabledInputMethodsContentUri);

        verifyIncrementalIndexing(VirtualKeyboardFragment.class);
        verifyIncrementalIndexing(AvailableVirtualKeyboardFragment.class);
    }

    @Test
    public void testUserDictionaryChangeMonitor() throws Exception {
        mMonitor.register(mActivity, LOADER_ID, mIndexManager, true /* isUserUnlocked */);

        // Content observer should be registered.
        final ContentObserver observer = extractContentObserver(UserDictionary.Words.CONTENT_URI);
        assertThat(observer).isNotNull();

        verifyIncrementalIndexing(LanguageAndInputSettings.class);

        /*
         * When user dictionary content is changed, rebuild indexing happens.
         */
        reset(mIndexManager);

        observer.onChange(false /* selfChange */, UserDictionary.Words.CONTENT_URI);

        verifyIncrementalIndexing(LanguageAndInputSettings.class);
    }

    /*
     * Verification helpers.
     */

    private void verifyNoIndexing(Class<?> indexingClass) {
        verify(mIndexManager, never()).updateFromClassNameResource(eq(indexingClass.getName()),
                anyBoolean());
    }

    private void verifyIncrementalIndexing(Class<?> indexingClass) {
        verify(mIndexManager, times(1)).updateFromClassNameResource(indexingClass.getName(),
                true /* includeInSearchResults */);
        verify(mIndexManager, never()).updateFromClassNameResource(indexingClass.getName(),
                false /* includeInSearchResults */);
    }

    /*
     * Testing helper methods.
     */

    private InputManager.InputDeviceListener extactInputDeviceListener() {
        List<InputManager.InputDeviceListener> listeners = ((ShadowInputManager) ShadowExtractor
                .extract(mInputManager))
                .getRegisteredInputDeviceListeners();
        InputManager.InputDeviceListener inputDeviceListener = null;
        for (InputManager.InputDeviceListener listener : listeners) {
            if (isUnderTest(listener)) {
                if (inputDeviceListener != null) {
                    assertThat(listener).isEqualTo(inputDeviceListener);
                } else {
                    inputDeviceListener = listener;
                }
            }
        }
        return inputDeviceListener;
    }

    private PackageMonitor extractPackageMonitor() {
        List<ShadowApplication.Wrapper> receivers = ShadowApplication.getInstance()
                .getRegisteredReceivers();
        PackageMonitor packageMonitor = null;
        for (ShadowApplication.Wrapper wrapper : receivers) {
            BroadcastReceiver receiver = wrapper.getBroadcastReceiver();
            if (isUnderTest(receiver) && receiver instanceof PackageMonitor) {
                if (packageMonitor != null) {
                    assertThat(receiver).isEqualTo(packageMonitor);
                } else {
                    packageMonitor = (PackageMonitor) receiver;
                }
            }
        }
        return packageMonitor;
    }

    private ContentObserver extractContentObserver(Uri uri) {
        ShadowContentResolver contentResolver = (ShadowContentResolver) ShadowExtractor
                .extract(mActivity.getContentResolver());
        Collection<ContentObserver> observers = contentResolver.getContentObservers(uri);
        ContentObserver contentObserver = null;
        for (ContentObserver observer : observers) {
            if (isUnderTest(observer)) {
                if (contentObserver != null) {
                    assertThat(observer).isEqualTo(contentObserver);
                } else {
                    contentObserver = observer;
                }
            }
        }
        return contentObserver;
    }

    private void enableInstalledPackage(String packageName) {
        ((PackageManager) mRobolectricPackageManager).setApplicationEnabledSetting(
                packageName, PackageManager.COMPONENT_ENABLED_STATE_DEFAULT, 0 /* flags */);
        extractPackageMonitor().onPackageModified(packageName);
        Robolectric.flushBackgroundThreadScheduler();
    }

    private void disableInstalledPackage(String packageName) {
        ((PackageManager) mRobolectricPackageManager).setApplicationEnabledSetting(
                packageName, PackageManager.COMPONENT_ENABLED_STATE_DISABLED, 0 /* flags */);
        extractPackageMonitor().onPackageModified(packageName);
        Robolectric.flushBackgroundThreadScheduler();
    }

    private void installAccessibilityService(String packageName) throws Exception {
        final AccessibilityServiceInfo serviceToAdd = buildAccessibilityServiceInfo(packageName);

        final List<AccessibilityServiceInfo> services = new ArrayList<>();
        services.addAll(mShadowAccessibilityManager.getInstalledAccessibilityServiceList());
        services.add(serviceToAdd);
        mShadowAccessibilityManager.setInstalledAccessibilityServiceList(services);

        final Intent intent = DynamicIndexableContentMonitor
                .getAccessibilityServiceIntent(packageName);
        mRobolectricPackageManager.addResolveInfoForIntent(intent, serviceToAdd.getResolveInfo());
        mRobolectricPackageManager.addPackage(packageName);

        extractPackageMonitor()
                .onPackageAppeared(packageName, PackageMonitor.PACKAGE_PERMANENT_CHANGE);
        Robolectric.flushBackgroundThreadScheduler();
    }

    private void uninstallAccessibilityService(String packageName) throws Exception {
        final AccessibilityServiceInfo serviceToRemove = buildAccessibilityServiceInfo(packageName);

        final List<AccessibilityServiceInfo> services = new ArrayList<>();
        services.addAll(mShadowAccessibilityManager.getInstalledAccessibilityServiceList());
        services.remove(serviceToRemove);
        mShadowAccessibilityManager.setInstalledAccessibilityServiceList(services);

        final Intent intent = DynamicIndexableContentMonitor
                .getAccessibilityServiceIntent(packageName);
        mRobolectricPackageManager.removeResolveInfosForIntent(intent, packageName);
        mRobolectricPackageManager.removePackage(packageName);

        extractPackageMonitor()
                .onPackageDisappeared(packageName, PackageMonitor.PACKAGE_PERMANENT_CHANGE);
        Robolectric.flushBackgroundThreadScheduler();
    }

    private void installInputMethodService(String packageName) throws Exception {
        final ResolveInfo resolveInfoToAdd = buildResolveInfo(packageName, "imeService");
        final InputMethodInfo serviceToAdd = buildInputMethodInfo(resolveInfoToAdd);

        final List<InputMethodInfo> services = new ArrayList<>();
        services.addAll(mShadowInputMethodManager.getInputMethodList());
        services.add(serviceToAdd);
        mShadowInputMethodManager.setInputMethodList(services);

        final Intent intent = DynamicIndexableContentMonitor.getIMEServiceIntent(packageName);
        mRobolectricPackageManager.addResolveInfoForIntent(intent, resolveInfoToAdd);
        mRobolectricPackageManager.addPackage(packageName);

        extractPackageMonitor()
                .onPackageAppeared(packageName, PackageMonitor.PACKAGE_PERMANENT_CHANGE);
        Robolectric.flushBackgroundThreadScheduler();
    }

    private void uninstallInputMethodService(String packageName) throws Exception {
        final ResolveInfo resolveInfoToRemove = buildResolveInfo(packageName, "imeService");
        final InputMethodInfo serviceToRemove = buildInputMethodInfo(resolveInfoToRemove);

        final List<InputMethodInfo> services = new ArrayList<>();
        services.addAll(mShadowInputMethodManager.getInputMethodList());
        services.remove(serviceToRemove);
        mShadowInputMethodManager.setInputMethodList(services);

        final Intent intent = DynamicIndexableContentMonitor.getIMEServiceIntent(packageName);
        mRobolectricPackageManager.removeResolveInfosForIntent(intent, packageName);
        mRobolectricPackageManager.removePackage(packageName);

        extractPackageMonitor()
                .onPackageDisappeared(packageName, PackageMonitor.PACKAGE_PERMANENT_CHANGE);
        Robolectric.flushBackgroundThreadScheduler();
    }

    private AccessibilityServiceInfo buildAccessibilityServiceInfo(String packageName)
            throws IOException, XmlPullParserException {
        return new AccessibilityServiceInfo(
                buildResolveInfo(packageName, "A11yService"), mActivity);
    }

    private static InputMethodInfo buildInputMethodInfo(ResolveInfo resolveInfo) {
        return new InputMethodInfo(resolveInfo, false /* isAuxIme */, "SettingsActivity",
                null /* subtypes */,  0 /* defaultResId */, false /* forceDefault */);
    }

    private static ResolveInfo buildResolveInfo(String packageName, String className) {
        final ResolveInfo resolveInfo = new ResolveInfo();
        resolveInfo.serviceInfo = new ServiceInfo();
        resolveInfo.serviceInfo.packageName = packageName;
        resolveInfo.serviceInfo.name = className;
        // To workaround that RobolectricPackageManager.removeResolveInfosForIntent() only works
        // for activity/broadcast resolver.
        resolveInfo.activityInfo = new ActivityInfo();
        resolveInfo.activityInfo.packageName = packageName;
        resolveInfo.activityInfo.name = className;

        return resolveInfo;
    }

    private static boolean isUnderTest(Object object) {
        return object.getClass().getName().startsWith(
                DynamicIndexableContentMonitor.class.getName());
    }
}
