/*
 * 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 android.location.cts.fine;

import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.database.ContentObserver;
import android.net.wifi.WifiManager;
import android.os.Handler;
import android.os.HandlerThread;
import android.platform.test.annotations.AppModeFull;
import android.provider.Settings;
import android.support.test.uiautomator.By;
import android.support.test.uiautomator.UiDevice;
import android.support.test.uiautomator.UiObject2;
import android.support.test.uiautomator.UiObjectNotFoundException;
import android.support.test.uiautomator.UiScrollable;
import android.support.test.uiautomator.UiSelector;
import android.support.test.uiautomator.Until;
import android.test.AndroidTestCase;

import com.android.compatibility.common.util.CddTest;
import com.android.compatibility.common.util.FeatureUtil;
import com.android.compatibility.common.util.PollingCheck;

import androidx.test.platform.app.InstrumentationRegistry;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

/**
 * Tests if system settings app provides scanning settings.
 */
@AppModeFull(reason = "Test cases don't apply for Instant apps")
public class ScanningSettingsTest extends AndroidTestCase {
    private static final String TAG = "ScanningSettingsTest";

    private static final int TIMEOUT = 8_000;  // 8 seconds
    private static final String SETTINGS_PACKAGE = "com.android.settings";

    private static final String WIFI_SCANNING_TITLE_RES =
            "location_scanning_wifi_always_scanning_title";
    private static final String BLUETOOTH_SCANNING_TITLE_RES =
            "location_scanning_bluetooth_always_scanning_title";

    private UiDevice mDevice;
    private Context mContext;
    private String mLauncherPackage;
    private PackageManager mPackageManager;

    @Override
    protected void setUp() throws Exception {
        super.setUp();
        // Can't use assumeTrue / assumeFalse because this is not a junit test, and so doesn't
        // support using these keywords to trigger assumption failure and skip test.
        if (FeatureUtil.isTV() || FeatureUtil.isAutomotive() || FeatureUtil.isWatch()) {
            // TV, auto, and watch do not support the setting options of WIFI scanning and Bluetooth
            // scanning
            return;
        }
        mContext = InstrumentationRegistry.getInstrumentation().getContext();
        mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());

        mPackageManager = mContext.getPackageManager();
        final Intent launcherIntent = new Intent(Intent.ACTION_MAIN);
        launcherIntent.addCategory(Intent.CATEGORY_HOME);
        mLauncherPackage = mPackageManager.resolveActivity(launcherIntent,
                PackageManager.MATCH_DEFAULT_ONLY).activityInfo.packageName;
    }

    @CddTest(requirement = "7.4.2/C-2-1")
    public void testWifiScanningSettings() throws Exception {
        if (FeatureUtil.isTV() || FeatureUtil.isAutomotive() || FeatureUtil.isWatch()) {
            return;
        }
        launchLocationServicesSettings();
        launchScanningSettingsFragment(WIFI_SCANNING_TITLE_RES);

        final Resources res = mPackageManager.getResourcesForApplication(SETTINGS_PACKAGE);
        final int resId = res.getIdentifier(WIFI_SCANNING_TITLE_RES, "string", SETTINGS_PACKAGE);
        final UiObject2 pref = mDevice.findObject(By.text(res.getString(resId)));

        final WifiManager wifiManager = mContext.getSystemService(WifiManager.class);

        final boolean checked = wifiManager.isScanAlwaysAvailable();

        // Click the preference to toggle the setting.
        pref.click();
        PollingCheck.check(
                "Scan Always Available wasn't toggled from " + checked + " to " + !checked,
                TIMEOUT,
                () -> !checked == wifiManager.isScanAlwaysAvailable()
        );

        // Click the preference again to toggle the setting back.
        pref.click();
        PollingCheck.check(
                "Scan Always Available wasn't toggled from " + !checked + " to " + checked,
                TIMEOUT,
                () -> checked == wifiManager.isScanAlwaysAvailable()
        );
    }

    @CddTest(requirement = "7.4.3/C-4-1")
    public void testBleScanningSettings() throws PackageManager.NameNotFoundException {
        if (FeatureUtil.isTV() || FeatureUtil.isAutomotive() || FeatureUtil.isWatch()) {
            return;
        }
        launchLocationServicesSettings();
        launchScanningSettingsFragment(BLUETOOTH_SCANNING_TITLE_RES);

        toggleSettingAndVerify(BLUETOOTH_SCANNING_TITLE_RES,
                Settings.Global.BLE_SCAN_ALWAYS_AVAILABLE);
    }

    private void launchLocationServicesSettings() {
        // Start from the home screen
        mDevice.pressHome();
        mDevice.wait(Until.hasObject(By.pkg(mLauncherPackage).depth(0)), TIMEOUT);

        final Intent intent = new Intent(Settings.ACTION_LOCATION_SCANNING_SETTINGS);
        // Clear out any previous instances
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
        mContext.startActivity(intent);

        // Wait for the app to appear
        mDevice.wait(Until.hasObject(By.pkg(SETTINGS_PACKAGE).depth(0)), TIMEOUT);
    }

    private void launchScanningSettingsFragment(String name)
            throws PackageManager.NameNotFoundException {
        final Resources res = mPackageManager.getResourcesForApplication(SETTINGS_PACKAGE);
        int resId = res.getIdentifier(name, "string", SETTINGS_PACKAGE);
        UiScrollable uiScrollable = new UiScrollable(new UiSelector().scrollable(true));
        try {
            uiScrollable.scrollTextIntoView(res.getString(resId));
        } catch (UiObjectNotFoundException e) {
            // Scrolling can fail if the UI is not scrollable
        }

        // Wait for the preference to appear
        mDevice.wait(Until.hasObject(By.text(res.getString(resId))), TIMEOUT);

        UiObject2 pref = mDevice.findObject(By.text(res.getString(resId)));
        // Click the preference to show the Scanning fragment
        pref.click();

        // Wait for the Scanning fragment to appear
        mDevice.wait(Until.hasObject(By.pkg(SETTINGS_PACKAGE).depth(1)), TIMEOUT);
    }

    private void clickAndWaitForSettingChange(UiObject2 pref, ContentResolver resolver,
            String settingKey) {
        final CountDownLatch latch = new CountDownLatch(1);
        final HandlerThread handlerThread = new HandlerThread(TAG);
        handlerThread.start();
        final ContentObserver observer = new ContentObserver(
                new Handler(handlerThread.getLooper())) {
            @Override
            public void onChange(boolean selfChange) {
                super.onChange(selfChange);
                latch.countDown();
            }
        };
        resolver.registerContentObserver(Settings.Global.getUriFor(settingKey), false, observer);
        pref.click();
        try {
            latch.await(TIMEOUT, TimeUnit.MILLISECONDS);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        handlerThread.quit();
        resolver.unregisterContentObserver(observer);
        assertEquals(0, latch.getCount());
    }

    private void toggleSettingAndVerify(String prefTitleRes, String settingKey)
            throws PackageManager.NameNotFoundException {
        final Resources res = mPackageManager.getResourcesForApplication(SETTINGS_PACKAGE);
        final int resId = res.getIdentifier(prefTitleRes, "string", SETTINGS_PACKAGE);
        final UiObject2 pref = mDevice.findObject(By.text(res.getString(resId)));
        final ContentResolver resolver = mContext.getContentResolver();
        final boolean checked = Settings.Global.getInt(resolver, settingKey, 0) == 1;

        // Click the preference to toggle the setting.
        clickAndWaitForSettingChange(pref, resolver, settingKey);
        assertEquals(!checked, Settings.Global.getInt(resolver, settingKey, 0) == 1);

        // Click the preference again to toggle the setting back.
        clickAndWaitForSettingChange(pref, resolver, settingKey);
        assertEquals(checked, Settings.Global.getInt(resolver, settingKey, 0) == 1);
    }
}
