/*
 * 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.cts.usepermission;

import static junit.framework.Assert.assertEquals;

import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.fail;

import android.Manifest;
import android.app.Activity;
import android.app.Instrumentation;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.net.Uri;
import android.os.Bundle;
import android.os.SystemClock;
import android.provider.Settings;
import android.support.test.uiautomator.By;
import android.support.test.uiautomator.UiDevice;
import android.support.test.uiautomator.UiObject;
import android.support.test.uiautomator.UiObject2;
import android.support.test.uiautomator.UiScrollable;
import android.support.test.uiautomator.UiSelector;
import android.support.test.uiautomator.Until;
import android.util.ArrayMap;
import android.util.Log;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityNodeInfo;
import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction;
import android.widget.ScrollView;
import android.widget.Switch;

import androidx.test.InstrumentationRegistry;
import androidx.test.runner.AndroidJUnit4;

import junit.framework.Assert;

import org.junit.Before;
import org.junit.runner.RunWith;

import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.TimeoutException;

@RunWith(AndroidJUnit4.class)
public abstract class BasePermissionsTest {
    private static final String PLATFORM_PACKAGE_NAME = "android";

    private static final long IDLE_TIMEOUT_MILLIS = 1000;
    private static final long GLOBAL_TIMEOUT_MILLIS = 10000;

    private static final long RETRY_TIMEOUT = 3 * GLOBAL_TIMEOUT_MILLIS;
    private static final String LOG_TAG = "BasePermissionsTest";

    private static Map<String, String> sPermissionToLabelResNameMap = new ArrayMap<>();

    private Context mContext;
    private Resources mPlatformResources;
    private boolean mWatch;

    protected static Instrumentation getInstrumentation() {
        return InstrumentationRegistry.getInstrumentation();
    }

    protected static void assertPermissionRequestResult(BasePermissionActivity.Result result,
            int requestCode, String[] permissions, boolean[] granted) {
        assertEquals(requestCode, result.requestCode);
        for (int i = 0; i < permissions.length; i++) {
            assertEquals(permissions[i], result.permissions[i]);
            assertEquals(granted[i] ? PackageManager.PERMISSION_GRANTED
                    : PackageManager.PERMISSION_DENIED, result.grantResults[i]);

        }
    }

    protected static UiDevice getUiDevice() {
        return UiDevice.getInstance(getInstrumentation());
    }

    protected static Activity launchActivity(String packageName,
            Class<?> clazz, Bundle extras) {
        Intent intent = new Intent(Intent.ACTION_MAIN);
        intent.setClassName(packageName, clazz.getName());
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        if (extras != null) {
            intent.putExtras(extras);
        }
        Activity activity = getInstrumentation().startActivitySync(intent);
        getInstrumentation().waitForIdleSync();

        return activity;
    }

    private void initPermissionToLabelMap(boolean permissionReviewMode) {
        if (!permissionReviewMode) {
            // Contacts
            sPermissionToLabelResNameMap.put(
                    Manifest.permission.READ_CONTACTS, "@android:string/permgrouplab_contacts");
            sPermissionToLabelResNameMap.put(
                    Manifest.permission.WRITE_CONTACTS, "@android:string/permgrouplab_contacts");
            // Calendar
            sPermissionToLabelResNameMap.put(
                    Manifest.permission.READ_CALENDAR, "@android:string/permgrouplab_calendar");
            sPermissionToLabelResNameMap.put(
                    Manifest.permission.WRITE_CALENDAR, "@android:string/permgrouplab_calendar");
            // SMS
            sPermissionToLabelResNameMap.put(
                    Manifest.permission.SEND_SMS, "@android:string/permgrouplab_sms");
            sPermissionToLabelResNameMap.put(
                    Manifest.permission.RECEIVE_SMS, "@android:string/permgrouplab_sms");
            sPermissionToLabelResNameMap.put(
                    Manifest.permission.READ_SMS, "@android:string/permgrouplab_sms");
            sPermissionToLabelResNameMap.put(
                    Manifest.permission.RECEIVE_WAP_PUSH, "@android:string/permgrouplab_sms");
            sPermissionToLabelResNameMap.put(
                    Manifest.permission.RECEIVE_MMS, "@android:string/permgrouplab_sms");
            sPermissionToLabelResNameMap.put(
                    "android.permission.READ_CELL_BROADCASTS", "@android:string/permgrouplab_sms");
            // Storage
            sPermissionToLabelResNameMap.put(
                    Manifest.permission.READ_EXTERNAL_STORAGE,
                    "@android:string/permgrouplab_storage");
            sPermissionToLabelResNameMap.put(
                    Manifest.permission.WRITE_EXTERNAL_STORAGE,
                    "@android:string/permgrouplab_storage");
            // Location
            sPermissionToLabelResNameMap.put(
                    Manifest.permission.ACCESS_FINE_LOCATION,
                    "@android:string/permgrouplab_location");
            sPermissionToLabelResNameMap.put(
                    Manifest.permission.ACCESS_COARSE_LOCATION,
                    "@android:string/permgrouplab_location");
            // Phone
            sPermissionToLabelResNameMap.put(
                    Manifest.permission.READ_PHONE_STATE, "@android:string/permgrouplab_phone");
            sPermissionToLabelResNameMap.put(
                    Manifest.permission.CALL_PHONE, "@android:string/permgrouplab_phone");
            sPermissionToLabelResNameMap.put(
                    "android.permission.ACCESS_IMS_CALL_SERVICE",
                    "@android:string/permgrouplab_phone");
            sPermissionToLabelResNameMap.put(
                    Manifest.permission.READ_CALL_LOG, "@android:string/permgrouplab_phone");
            sPermissionToLabelResNameMap.put(
                    Manifest.permission.WRITE_CALL_LOG, "@android:string/permgrouplab_phone");
            sPermissionToLabelResNameMap.put(
                    Manifest.permission.ADD_VOICEMAIL, "@android:string/permgrouplab_phone");
            sPermissionToLabelResNameMap.put(
                    Manifest.permission.USE_SIP, "@android:string/permgrouplab_phone");
            sPermissionToLabelResNameMap.put(
                    Manifest.permission.PROCESS_OUTGOING_CALLS,
                    "@android:string/permgrouplab_phone");
            // Microphone
            sPermissionToLabelResNameMap.put(
                    Manifest.permission.RECORD_AUDIO, "@android:string/permgrouplab_microphone");
            // Camera
            sPermissionToLabelResNameMap.put(
                    Manifest.permission.CAMERA, "@android:string/permgrouplab_camera");
            // Body sensors
            sPermissionToLabelResNameMap.put(
                    Manifest.permission.BODY_SENSORS, "@android:string/permgrouplab_sensors");
        } else {
            // Contacts
            sPermissionToLabelResNameMap.put(
                    Manifest.permission.READ_CONTACTS, "@android:string/permlab_readContacts");
            sPermissionToLabelResNameMap.put(
                    Manifest.permission.WRITE_CONTACTS, "@android:string/permlab_writeContacts");
            // Calendar
            sPermissionToLabelResNameMap.put(
                    Manifest.permission.READ_CALENDAR, "@android:string/permgrouplab_calendar");
            sPermissionToLabelResNameMap.put(
                    Manifest.permission.WRITE_CALENDAR, "@android:string/permgrouplab_calendar");
            // SMS
            sPermissionToLabelResNameMap.put(
                    Manifest.permission.SEND_SMS, "@android:string/permlab_sendSms");
            sPermissionToLabelResNameMap.put(
                    Manifest.permission.RECEIVE_SMS, "@android:string/permlab_receiveSms");
            sPermissionToLabelResNameMap.put(
                    Manifest.permission.READ_SMS, "@android:string/permlab_readSms");
            sPermissionToLabelResNameMap.put(
                    Manifest.permission.RECEIVE_WAP_PUSH, "@android:string/permlab_receiveWapPush");
            sPermissionToLabelResNameMap.put(
                    Manifest.permission.RECEIVE_MMS, "@android:string/permlab_receiveMms");
            sPermissionToLabelResNameMap.put(
                    "android.permission.READ_CELL_BROADCASTS",
                    "@android:string/permlab_readCellBroadcasts");
            // Storage
            sPermissionToLabelResNameMap.put(
                    Manifest.permission.READ_EXTERNAL_STORAGE,
                    "@android:string/permgrouplab_storage");
            sPermissionToLabelResNameMap.put(
                    Manifest.permission.WRITE_EXTERNAL_STORAGE,
                    "@android:string/permgrouplab_storage");
            // Location
            sPermissionToLabelResNameMap.put(
                    Manifest.permission.ACCESS_FINE_LOCATION,
                    "@android:string/permgrouplab_location");
            sPermissionToLabelResNameMap.put(
                    Manifest.permission.ACCESS_COARSE_LOCATION,
                    "@android:string/permgrouplab_location");
            // Phone
            sPermissionToLabelResNameMap.put(
                    Manifest.permission.READ_PHONE_STATE, "@android:string/permlab_readPhoneState");
            sPermissionToLabelResNameMap.put(
                    Manifest.permission.CALL_PHONE, "@android:string/permlab_callPhone");
            sPermissionToLabelResNameMap.put(
                    "android.permission.ACCESS_IMS_CALL_SERVICE",
                    "@android:string/permlab_accessImsCallService");
            sPermissionToLabelResNameMap.put(
                    Manifest.permission.READ_CALL_LOG, "@android:string/permlab_readCallLog");
            sPermissionToLabelResNameMap.put(
                    Manifest.permission.WRITE_CALL_LOG, "@android:string/permlab_writeCallLog");
            sPermissionToLabelResNameMap.put(
                    Manifest.permission.ADD_VOICEMAIL, "@android:string/permlab_addVoicemail");
            sPermissionToLabelResNameMap.put(
                    Manifest.permission.USE_SIP, "@android:string/permlab_use_sip");
            sPermissionToLabelResNameMap.put(
                    Manifest.permission.PROCESS_OUTGOING_CALLS,
                    "@android:string/permlab_processOutgoingCalls");
            // Microphone
            sPermissionToLabelResNameMap.put(
                    Manifest.permission.RECORD_AUDIO, "@android:string/permgrouplab_microphone");
            // Camera
            sPermissionToLabelResNameMap.put(
                    Manifest.permission.CAMERA, "@android:string/permgrouplab_camera");
            // Body sensors
            sPermissionToLabelResNameMap.put(
                    Manifest.permission.BODY_SENSORS, "@android:string/permgrouplab_sensors");
        }
    }

    @Before
    public void beforeTest() {
        mContext = InstrumentationRegistry.getTargetContext();
        try {
            Context platformContext = mContext.createPackageContext(PLATFORM_PACKAGE_NAME, 0);
            mPlatformResources = platformContext.getResources();
        } catch (PackageManager.NameNotFoundException e) {
            /* cannot happen */
        }

        PackageManager packageManager = mContext.getPackageManager();
        mWatch = packageManager.hasSystemFeature(PackageManager.FEATURE_WATCH);
        initPermissionToLabelMap(packageManager.isPermissionReviewModeEnabled());

        UiObject2 button = getUiDevice().findObject(By.text("Close"));
        if (button != null) {
            button.click();
        }
    }

    protected BasePermissionActivity.Result requestPermissions(
            String[] permissions, int requestCode, Class<?> clazz, Runnable postRequestAction)
            throws Exception {
        // Start an activity
        BasePermissionActivity activity = (BasePermissionActivity) launchActivity(
                getInstrumentation().getTargetContext().getPackageName(), clazz, null);

        activity.waitForOnCreate();

        // Request the permissions
        activity.requestPermissions(permissions, requestCode);

        // Define a more conservative idle criteria
        getInstrumentation().getUiAutomation().waitForIdle(
                IDLE_TIMEOUT_MILLIS, GLOBAL_TIMEOUT_MILLIS);

        // Perform the post-request action
        if (postRequestAction != null) {
            postRequestAction.run();
        }

        BasePermissionActivity.Result result = activity.getResult();
        activity.finish();
        return result;
    }

    protected void clickAllowButton() throws Exception {
        scrollToBottomIfWatch();
        getUiDevice().findObject(new UiSelector().resourceId(
                "com.android.packageinstaller:id/permission_allow_button")).click();
    }

    protected void clickDenyButton() throws Exception {
        scrollToBottomIfWatch();
        getUiDevice().findObject(new UiSelector().resourceId(
                "com.android.packageinstaller:id/permission_deny_button")).click();
    }

    protected void clickDontAskAgainCheckbox() throws Exception {
        getUiDevice().findObject(new UiSelector().resourceId(
                "com.android.packageinstaller:id/do_not_ask_checkbox")).click();
    }

    protected void clickDontAskAgainButton() throws Exception {
        scrollToBottomIfWatch();
        getUiDevice().findObject(new UiSelector().resourceId(
                "com.android.packageinstaller:id/permission_deny_dont_ask_again_button")).click();
    }

    protected void grantPermission(String permission) throws Exception {
        grantPermissions(new String[]{permission});
    }

    protected void grantPermissions(String[] permissions) throws Exception {
        setPermissionGrantState(permissions, true, false);
    }

    protected void revokePermission(String permission) throws Exception {
        revokePermissions(new String[] {permission}, false);
    }

    protected void revokePermissions(String[] permissions, boolean legacyApp) throws Exception {
        setPermissionGrantState(permissions, false, legacyApp);
    }

    private void scrollToBottomIfWatch() throws Exception {
        if (mWatch) {
            getUiDevice().wait(Until.findObject(By.clazz(ScrollView.class)), GLOBAL_TIMEOUT_MILLIS);
            UiScrollable scrollable =
                    new UiScrollable(new UiSelector().className(ScrollView.class));
            if (scrollable.exists()) {
                scrollable.flingToEnd(10);
            }
        }
    }

    private void setPermissionGrantState(String[] permissions, boolean granted,
            boolean legacyApp) throws Exception {
        getUiDevice().pressBack();
        waitForIdle();
        getUiDevice().pressBack();
        waitForIdle();
        getUiDevice().pressBack();
        waitForIdle();

        if (isTv()) {
            getUiDevice().pressHome();
            waitForIdle();
        }

        // Open the app details settings
        Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
        intent.addCategory(Intent.CATEGORY_DEFAULT);
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        intent.setData(Uri.parse("package:" + mContext.getPackageName()));
        startActivity(intent);

        waitForIdle();

        // Open the permissions UI
        String label = mContext.getResources().getString(R.string.Permissions);
        AccessibilityNodeInfo permLabelView = getNodeTimed(() -> findByText(label), true);
        Assert.assertNotNull("Permissions label should be present", permLabelView);

        AccessibilityNodeInfo permItemView = findCollectionItem(permLabelView);
        Assert.assertNotNull("Permissions item should be present", permItemView);

        click(permItemView);

        waitForIdle();

        for (String permission : permissions) {
            // Find the permission toggle
            String permissionLabel = getPermissionLabel(permission);

            AccessibilityNodeInfo labelView = getNodeTimed(() -> findByText(permissionLabel), true);
            Assert.assertNotNull("Permission label should be present", labelView);

            AccessibilityNodeInfo itemView = findCollectionItem(labelView);
            Assert.assertNotNull("Permission item should be present", itemView);

            final AccessibilityNodeInfo toggleView = findSwitch(itemView);
            Assert.assertNotNull("Permission toggle should be present", toggleView);

            final boolean wasGranted = toggleView.isChecked();
            if (granted != wasGranted) {
                // Toggle the permission

                if (!itemView.getActionList().contains(AccessibilityAction.ACTION_CLICK)) {
                    click(toggleView);
                } else {
                    click(itemView);
                }

                waitForIdle();

                if (wasGranted && legacyApp) {
                    scrollToBottomIfWatch();
                    String packageName = getInstrumentation().getContext().getPackageManager()
                            .getPermissionControllerPackageName();
                    String resIdName = "com.android.packageinstaller"
                            + ":string/grant_dialog_button_deny_anyway";
                    Resources resources = getInstrumentation().getContext()
                            .createPackageContext(packageName, 0).getResources();
                    final int confirmResId = resources.getIdentifier(resIdName, null, null);
                    String confirmTitle = resources.getString(confirmResId);
                    UiObject denyAnyway = getUiDevice().findObject(new UiSelector()
                            .textStartsWith(confirmTitle));
                    denyAnyway.click();

                    waitForIdle();
                }
            }
        }

        getUiDevice().pressBack();
        waitForIdle();
        getUiDevice().pressBack();
        waitForIdle();
    }

    private String getPermissionLabel(String permission) throws Exception {
        String labelResName = sPermissionToLabelResNameMap.get(permission);
        assertNotNull("Unknown permisison " + permission, labelResName);
        final int resourceId = mPlatformResources.getIdentifier(labelResName, null, null);
        return mPlatformResources.getString(resourceId);
    }

    private void startActivity(final Intent intent) throws Exception {
        getInstrumentation().getUiAutomation().executeAndWaitForEvent(
                () -> {
            try {
                getInstrumentation().getContext().startActivity(intent);
            } catch (Exception e) {
                Log.e(LOG_TAG, "Cannot start activity: " + intent, e);
                fail("Cannot start activity: " + intent);
            }
        }, (AccessibilityEvent event) -> event.getEventType()
                        == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED
         , GLOBAL_TIMEOUT_MILLIS);
    }

    private AccessibilityNodeInfo findByText(String text) throws Exception {
        AccessibilityNodeInfo root = getInstrumentation().getUiAutomation().getRootInActiveWindow();
        AccessibilityNodeInfo result = findByText(root, text);
        if (result != null) {
            return result;
        }
        return findByTextInCollection(root, text);
    }

    private static AccessibilityNodeInfo findByText(AccessibilityNodeInfo root, String text) {
        List<AccessibilityNodeInfo> nodes = root.findAccessibilityNodeInfosByText(text);
        for (AccessibilityNodeInfo node : nodes) {
            if (node.getText().toString().equals(text)) {
                return node;
            }
        }
        return null;
    }

    private static AccessibilityNodeInfo findByTextInCollection(AccessibilityNodeInfo root,
            String text)  throws Exception {
        AccessibilityNodeInfo result;
        final int childCount = root.getChildCount();
        for (int i = 0; i < childCount; i++) {
            AccessibilityNodeInfo child = root.getChild(i);
            if (child == null) {
                continue;
            }
            if (child.getCollectionInfo() != null) {
                scrollTop(child);
                result = getNodeTimed(() -> findByText(child, text), false);
                if (result != null) {
                    return result;
                }
                try {
                    while (child.getActionList().contains(
                            AccessibilityAction.ACTION_SCROLL_FORWARD) || child.getActionList()
                            .contains(AccessibilityAction.ACTION_SCROLL_DOWN)) {
                        scrollForward(child);
                        result = getNodeTimed(() -> findByText(child, text), false);
                        if (result != null) {
                            return result;
                        }
                    }
                } catch (TimeoutException e) {
                     /* ignore */
                }
            } else {
                result = findByTextInCollection(child, text);
                if (result != null) {
                    return result;
                }
            }
        }
        return null;
    }

    private static void scrollTop(AccessibilityNodeInfo node) throws Exception {
        try {
            while (node.getActionList().contains(AccessibilityAction.ACTION_SCROLL_BACKWARD)) {
                scroll(node, false);
            }
        } catch (TimeoutException e) {
            /* ignore */
        }
    }

    private static void scrollForward(AccessibilityNodeInfo node) throws Exception {
            scroll(node, true);
    }

    private static void scroll(AccessibilityNodeInfo node, boolean forward) throws Exception {
        getInstrumentation().getUiAutomation().executeAndWaitForEvent(
                () -> {
                    if (isTv()) {
                        if (forward) {
                            getUiDevice().pressDPadDown();
                        } else {
                            for (int i = 0; i < 50; i++) {
                                getUiDevice().pressDPadUp();
                            }
                        }
                    } else {
                        node.performAction(forward
                                ? AccessibilityNodeInfo.ACTION_SCROLL_FORWARD
                                : AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD);
                    }
                },
                (AccessibilityEvent event) -> event.getEventType()
                        == AccessibilityEvent.TYPE_VIEW_SCROLLED
                        || event.getEventType() == AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED,
                GLOBAL_TIMEOUT_MILLIS);
        node.refresh();
        waitForIdle();
    }

    private static void click(AccessibilityNodeInfo node) throws Exception {
        getInstrumentation().getUiAutomation().executeAndWaitForEvent(
                () -> node.performAction(AccessibilityNodeInfo.ACTION_CLICK),
                (AccessibilityEvent event) -> event.getEventType()
                        == AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED
                        || event.getEventType() == AccessibilityEvent.TYPE_WINDOWS_CHANGED,
                GLOBAL_TIMEOUT_MILLIS);
    }

    private static AccessibilityNodeInfo findCollectionItem(AccessibilityNodeInfo current)
            throws Exception {
        AccessibilityNodeInfo result = current;
        while (result != null) {
            // Nodes that are in the hierarchy but not yet on screen may not have collection item
            // info populated. Use a parent with collection info as an indicator in those cases.
            if (result.getCollectionItemInfo() != null || hasCollectionAsParent(result)) {
                return result;
            }
            result = result.getParent();
        }
        return null;
    }

    private static boolean hasCollectionAsParent(AccessibilityNodeInfo node) {
        return node.getParent() != null && node.getParent().getCollectionInfo() != null;
    }

    private static AccessibilityNodeInfo findSwitch(AccessibilityNodeInfo root) throws Exception {
        if (Switch.class.getName().equals(root.getClassName().toString())) {
            return root;
        }
        final int childCount = root.getChildCount();
        for (int i = 0; i < childCount; i++) {
            AccessibilityNodeInfo child = root.getChild(i);
            if (child == null) {
                continue;
            }
            if (Switch.class.getName().equals(child.getClassName().toString())) {
                return child;
            }
            AccessibilityNodeInfo result = findSwitch(child);
            if (result != null) {
                return result;
            }
        }
        return null;
    }

    private static AccessibilityNodeInfo getNodeTimed(
            Callable<AccessibilityNodeInfo> callable, boolean retry) throws Exception {
        final long startTimeMillis = SystemClock.uptimeMillis();
        while (true) {
            try {
                AccessibilityNodeInfo node = callable.call();

                if (node != null) {
                    return node;
                }
            } catch (NullPointerException e) {
                Log.e(LOG_TAG, "NPE while finding AccessibilityNodeInfo", e);
            }

            final long elapsedTimeMillis = SystemClock.uptimeMillis() - startTimeMillis;
            if (!retry || elapsedTimeMillis > RETRY_TIMEOUT) {
                return null;
            }
            SystemClock.sleep(2 * elapsedTimeMillis);
        }
    }

    private static void waitForIdle() throws TimeoutException {
        getInstrumentation().getUiAutomation().waitForIdle(IDLE_TIMEOUT_MILLIS,
                GLOBAL_TIMEOUT_MILLIS);
    }

    private static boolean isTv() {
        return getInstrumentation().getContext().getPackageManager()
                .hasSystemFeature(PackageManager.FEATURE_LEANBACK);
    }
 }
