/*
 * Copyright (C) 2015 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.permission3.cts

import android.content.pm.PackageManager
import androidx.test.filters.FlakyTest
import com.android.compatibility.common.util.SystemUtil
import org.junit.Assert
import org.junit.Assume
import org.junit.Before
import org.junit.Test

/**
 * Runtime permission behavior tests for apps targeting API 23.
 */
class PermissionTest23 : BaseUsePermissionTest() {
    companion object {
        private const val NON_EXISTENT_PERMISSION = "permission.does.not.exist"
        private const val INVALID_PERMISSION = "$APP_PACKAGE_NAME.abadname"
    }

    @Before
    fun installApp23() {
        installPackage(APP_APK_PATH_23)
    }

    @Test
    fun testDefault() {
        // New permission model is denied by default
        assertAppHasAllOrNoPermissions(false)
    }

    @Test
    fun testGranted() {
        grantAppPermissions(android.Manifest.permission.READ_CALENDAR)

        // Read/write access should be allowed
        assertAppHasPermission(android.Manifest.permission.READ_CALENDAR, true)
        assertAppHasPermission(android.Manifest.permission.WRITE_CALENDAR, true)
        assertAppHasCalendarAccess(true)
    }

    @Test
    fun testInteractiveGrant() {
        // Start out without permission
        assertAppHasPermission(android.Manifest.permission.READ_CALENDAR, false)
        assertAppHasPermission(android.Manifest.permission.WRITE_CALENDAR, false)
        assertAppHasCalendarAccess(false)

        // Go through normal grant flow
        requestAppPermissionsAndAssertResult(
            android.Manifest.permission.READ_CALENDAR to true,
            android.Manifest.permission.WRITE_CALENDAR to true
        ) {
            clickPermissionRequestAllowButton()
        }

        // We should have permission now!
        assertAppHasCalendarAccess(true)
    }

    @Test
    fun testRuntimeGroupGrantSpecificity() {
        // Start out without permission
        assertAppHasPermission(android.Manifest.permission.READ_CONTACTS, false)
        assertAppHasPermission(android.Manifest.permission.WRITE_CONTACTS, false)

        // Request only one permission from the 'contacts' permission group
        // Expect the permission is granted
        requestAppPermissionsAndAssertResult(android.Manifest.permission.WRITE_CONTACTS to true) {
            clickPermissionRequestAllowButton()
        }

        // Make sure no undeclared as used permissions are granted
        assertAppHasPermission(android.Manifest.permission.READ_CONTACTS, false)
    }

    @Test
    fun testCancelledPermissionRequest() {
        // Make sure we don't have the permission
        assertAppHasPermission(android.Manifest.permission.WRITE_CONTACTS, false)

        // Request the permission and cancel the request
        // Expect the permission is not granted
        requestAppPermissionsAndAssertResult(android.Manifest.permission.WRITE_CONTACTS to false) {
            clickPermissionRequestDenyButton()
        }
    }

    @Test
    fun testRequestGrantedPermission() {
        // Make sure we don't have the permission
        assertAppHasPermission(android.Manifest.permission.WRITE_CONTACTS, false)

        // Request the permission and allow it
        // Expect the permission is granted
        requestAppPermissionsAndAssertResult(android.Manifest.permission.WRITE_CONTACTS to true) {
            clickPermissionRequestAllowButton()
        }

        // Request the permission and do nothing
        // Expect the permission is granted
        requestAppPermissionsAndAssertResult(android.Manifest.permission.WRITE_CONTACTS to true) {}
    }

    @Test
    fun testDenialWithPrejudice() {
        // Make sure we don't have the permission
        assertAppHasPermission(android.Manifest.permission.WRITE_CONTACTS, false)

        // Request the permission and deny it
        // Expect the permission is not granted
        requestAppPermissionsAndAssertResult(android.Manifest.permission.WRITE_CONTACTS to false) {
            clickPermissionRequestDenyButton()
        }

        // Request the permission and choose don't ask again
        // Expect the permission is not granted
        requestAppPermissionsAndAssertResult(android.Manifest.permission.WRITE_CONTACTS to false) {
            denyPermissionRequestWithPrejudice()
        }

        // Request the permission and do nothing
        // Expect the permission is not granted
        requestAppPermissionsAndAssertResult(android.Manifest.permission.WRITE_CONTACTS to false) {}
    }

    @FlakyTest
    @Test
    fun testRevokeAffectsWholeGroup() {
        // Grant the group
        grantAppPermissions(android.Manifest.permission.READ_CALENDAR)

        // Make sure we have the permissions
        assertAppHasPermission(android.Manifest.permission.READ_CALENDAR, true)
        assertAppHasPermission(android.Manifest.permission.WRITE_CALENDAR, true)

        // Revoke the group
        revokeAppPermissions(android.Manifest.permission.READ_CALENDAR)

        // Make sure we don't have the permissions
        assertAppHasPermission(android.Manifest.permission.READ_CALENDAR, false)
        assertAppHasPermission(android.Manifest.permission.WRITE_CALENDAR, false)
    }

    @Test
    fun testGrantPreviouslyRevokedWithPrejudiceShowsPrompt() {
        // Make sure we don't have the permission
        assertAppHasPermission(android.Manifest.permission.CAMERA, false)

        // Request the permission and deny it
        // Expect the permission is not granted
        requestAppPermissionsAndAssertResult(android.Manifest.permission.CAMERA to false) {
            clickPermissionRequestDenyButton()
        }

        // Request the permission and choose don't ask again
        // Expect the permission is not granted
        requestAppPermissionsAndAssertResult(android.Manifest.permission.CAMERA to false) {
            denyPermissionRequestWithPrejudice()
        }

        // Clear the denial with prejudice
        grantAppPermissions(android.Manifest.permission.CAMERA)
        revokeAppPermissions(android.Manifest.permission.CAMERA)

        // Make sure we don't have the permission
        assertAppHasPermission(android.Manifest.permission.CAMERA, false)

        // Request the permission and allow it
        // Make sure the permission is granted
        requestAppPermissionsAndAssertResult(android.Manifest.permission.CAMERA to true) {
            clickPermissionRequestAllowForegroundButton()
        }
    }

    @Test
    fun testRequestNonRuntimePermission() {
        // Make sure we don't have the permission
        assertAppHasPermission(android.Manifest.permission.BIND_PRINT_SERVICE, false)

        // Request the permission and do nothing
        // Expect the permission is not granted
        requestAppPermissionsAndAssertResult(
            android.Manifest.permission.BIND_PRINT_SERVICE to false
        ) {}
    }

    @Test
    fun testRequestNonExistentPermission() {
        // Make sure we don't have the permission
        assertAppHasPermission(NON_EXISTENT_PERMISSION, false)

        // Request the permission and do nothing
        // Expect the permission is not granted
        requestAppPermissionsAndAssertResult(NON_EXISTENT_PERMISSION to false) {}
    }

    @Test
    fun testRequestPermissionFromTwoGroups() {
        // Make sure we don't have the permissions
        assertAppHasPermission(android.Manifest.permission.WRITE_CONTACTS, false)
        assertAppHasPermission(android.Manifest.permission.WRITE_CALENDAR, false)
        assertAppHasPermission(android.Manifest.permission.READ_CALENDAR, false)

        // Request the permission and allow it
        // Expect the permission are granted
        val result = requestAppPermissionsAndAssertResult(
            android.Manifest.permission.WRITE_CONTACTS to true,
            android.Manifest.permission.WRITE_CALENDAR to true
        ) {
            clickPermissionRequestAllowButton()
            clickPermissionRequestAllowButton()
        }

        // In API < N_MR1 all permissions of a group are granted. I.e. the grant was "expanded"
        assertAppHasPermission(android.Manifest.permission.READ_CALENDAR, true)
        // Even the contacts group was expanded, the read-calendar permission is not in the
        // manifest, hence not granted.
        assertAppHasPermission(android.Manifest.permission.READ_CONTACTS, false)
    }

    @Test(timeout = 180000)
    @FlakyTest
    fun testNoResidualPermissionsOnUninstall() {
        Assume.assumeFalse(packageManager.arePermissionsIndividuallyControlled())

        // Grant all permissions
        grantAppPermissions(
            android.Manifest.permission.WRITE_CALENDAR,
            android.Manifest.permission.WRITE_CONTACTS,
            android.Manifest.permission.READ_SMS,
            android.Manifest.permission.CALL_PHONE,
            android.Manifest.permission.RECORD_AUDIO,
            android.Manifest.permission.CAMERA,
            android.Manifest.permission.READ_EXTERNAL_STORAGE, targetSdk = 23
        )
        // Don't use UI for granting location and sensor permissions as they show another dialog
        uiAutomation.grantRuntimePermission(
            APP_PACKAGE_NAME, android.Manifest.permission.ACCESS_FINE_LOCATION
        )
        uiAutomation.grantRuntimePermission(
            APP_PACKAGE_NAME, android.Manifest.permission.ACCESS_COARSE_LOCATION
        )
        uiAutomation.grantRuntimePermission(
            APP_PACKAGE_NAME, android.Manifest.permission.ACCESS_BACKGROUND_LOCATION
        )
        uiAutomation.grantRuntimePermission(
            APP_PACKAGE_NAME, android.Manifest.permission.BODY_SENSORS
        )

        uninstallPackage(APP_PACKAGE_NAME)
        installPackage(APP_APK_PATH_23)

        // Make no permissions are granted after uninstalling and installing the app
        assertAppHasAllOrNoPermissions(false)
    }

    @Test
    fun testNullPermissionRequest() {
        // Go through normal grant flow
        requestAppPermissionsAndAssertResult(null to false) {}
    }

    @Test
    fun testNullAndRealPermission() {
        // Make sure we don't have the permissions
        assertAppHasPermission(android.Manifest.permission.WRITE_CONTACTS, false)
        assertAppHasPermission(android.Manifest.permission.RECORD_AUDIO, false)

        // Request the permission and allow it
        // Expect the permission are granted
        requestAppPermissionsAndAssertResult(
            null to false,
            android.Manifest.permission.WRITE_CONTACTS to true,
            null to false,
            android.Manifest.permission.RECORD_AUDIO to true
        ) {
            clickPermissionRequestAllowForegroundButton()
            clickPermissionRequestAllowButton()
        }
    }

    @Test
    fun testInvalidPermission() {
        // Request the permission and allow it
        // Expect the permission is not granted
        requestAppPermissionsAndAssertResult(INVALID_PERMISSION to false) {}
    }

    @Test
    fun testAskButtonSetsFlags() {
        Assume.assumeFalse("other form factors might not support the ask button",
                isTv || isAutomotive || isWatch)

        grantAppPermissions(android.Manifest.permission.ACCESS_BACKGROUND_LOCATION, targetSdk = 23)
        assertAppHasPermission(android.Manifest.permission.ACCESS_BACKGROUND_LOCATION, true)
        assertAppHasPermission(android.Manifest.permission.ACCESS_FINE_LOCATION, true)
        assertAppHasPermission(android.Manifest.permission.ACCESS_COARSE_LOCATION, true)

        revokeAppPermissions(android.Manifest.permission.ACCESS_BACKGROUND_LOCATION, targetSdk = 23)
        SystemUtil.runWithShellPermissionIdentity {
            val perms = listOf(android.Manifest.permission.ACCESS_BACKGROUND_LOCATION,
                    android.Manifest.permission.ACCESS_FINE_LOCATION,
                    android.Manifest.permission.ACCESS_COARSE_LOCATION)
            for (perm in perms) {
                var flags = packageManager.getPermissionFlags(perm, APP_PACKAGE_NAME, context.user)
                Assert.assertEquals("USER_SET should not be set for $perm", 0,
                        flags and PackageManager.FLAG_PERMISSION_USER_SET)
                Assert.assertEquals("USER_FIXED should not be set for $perm", 0,
                        flags and PackageManager.FLAG_PERMISSION_USER_FIXED)
                Assert.assertEquals("ONE_TIME should be set for $perm",
                        PackageManager.FLAG_PERMISSION_ONE_TIME,
                        flags and PackageManager.FLAG_PERMISSION_ONE_TIME)
            }
        }
    }

    private fun denyPermissionRequestWithPrejudice() {
        if (isTv || isWatch) {
            clickPermissionRequestDontAskAgainButton()
        } else {
            clickPermissionRequestDenyAndDontAskAgainButton()
        }
    }

    private fun assertAppHasAllOrNoPermissions(expectPermissions: Boolean) {
        arrayOf(
            android.Manifest.permission.SEND_SMS,
            android.Manifest.permission.RECEIVE_SMS,
            android.Manifest.permission.RECEIVE_WAP_PUSH,
            android.Manifest.permission.RECEIVE_MMS,
            android.Manifest.permission.READ_CALENDAR,
            android.Manifest.permission.WRITE_CALENDAR,
            android.Manifest.permission.WRITE_CONTACTS,
            android.Manifest.permission.READ_SMS,
            android.Manifest.permission.READ_PHONE_STATE,
            android.Manifest.permission.READ_CALL_LOG,
            android.Manifest.permission.WRITE_CALL_LOG,
            android.Manifest.permission.ADD_VOICEMAIL,
            android.Manifest.permission.CALL_PHONE,
            android.Manifest.permission.USE_SIP,
            android.Manifest.permission.PROCESS_OUTGOING_CALLS,
            android.Manifest.permission.RECORD_AUDIO,
            android.Manifest.permission.ACCESS_FINE_LOCATION,
            android.Manifest.permission.ACCESS_COARSE_LOCATION,
            android.Manifest.permission.CAMERA,
            android.Manifest.permission.BODY_SENSORS,
            android.Manifest.permission.READ_CELL_BROADCASTS,
            // Split permissions
            android.Manifest.permission.ACCESS_BACKGROUND_LOCATION,
            // Storage permissions
            android.Manifest.permission.READ_EXTERNAL_STORAGE,
            android.Manifest.permission.WRITE_EXTERNAL_STORAGE
        ).forEach {
            assertAppHasPermission(it, expectPermissions)
        }
    }
}
