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

import static com.android.cts.devicepolicy.metrics.DevicePolicyEventLogVerifier.assertMetricsLogged;

import android.platform.test.annotations.FlakyTest;
import android.platform.test.annotations.LargeTest;
import android.stats.devicepolicy.EventId;

import com.android.cts.devicepolicy.annotations.LockSettingsTest;
import com.android.cts.devicepolicy.metrics.DevicePolicyEventWrapper;
import com.android.tradefed.device.DeviceNotAvailableException;

import org.junit.Test;

import java.util.concurrent.TimeUnit;

public class ManagedProfilePasswordTest extends BaseManagedProfileTest {
    private static final String USER_STATE_LOCKED = "RUNNING_LOCKED";
    private static final long TIMEOUT_USER_LOCKED_MILLIS = TimeUnit.MINUTES.toMillis(3);
    // Password needs to be in sync with ResetPasswordWithTokenTest.PASSWORD1
    private static final String RESET_PASSWORD_TEST_DEFAULT_PASSWORD = "123456";

    @FlakyTest
    @Test
    public void testLockNowWithKeyEviction() throws Exception {
        assumeHasFileBasedEncryptionAndSecureLockScreenFeatures();

        changeUserCredential(TEST_PASSWORD, null, mProfileUserId);
        lockProfile();
    }

    @FlakyTest
    @Test
    public void testResetPasswordWithTokenBeforeUnlock() throws Exception {
        assumeHasFileBasedEncryptionAndSecureLockScreenFeatures();

        runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".ResetPasswordWithTokenTest",
                "testSetupWorkProfile", mProfileUserId);
        lockProfile();
        runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".ResetPasswordWithTokenTest",
                "testResetPasswordBeforeUnlock", mProfileUserId);
        // Password needs to be in sync with ResetPasswordWithTokenTest.PASSWORD1
        verifyUserCredential(RESET_PASSWORD_TEST_DEFAULT_PASSWORD, mProfileUserId);
    }

    @FlakyTest
    @Test
    public void testClearPasswordWithTokenBeforeUnlock() throws Exception {
        assumeHasFileBasedEncryptionAndSecureLockScreenFeatures();

        runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".ResetPasswordWithTokenTest",
                "testSetupWorkProfile", mProfileUserId);
        lockProfile();
        runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".ResetPasswordWithTokenTest",
                "testClearPasswordBeforeUnlock", mProfileUserId);
        // Make sure profile has no password
        verifyUserCredential("", mProfileUserId);
    }

    /**
     * Test password reset token is still functional after the primary user clears and
     * re-adds back its device lock. This is to detect a regression where the work profile
     * undergoes an untrusted credential reset (causing synthetic password to change, invalidating
     * existing password reset token) if it has unified work challenge and the primary user clears
     * the device lock.
     */
    @FlakyTest
    @Test
    public void testResetPasswordTokenUsableAfterClearingLock() throws Exception {
        assumeHasFileBasedEncryptionAndSecureLockScreenFeatures();

        final String devicePassword = TEST_PASSWORD;

        runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".ResetPasswordWithTokenTest",
                "testSetResetPasswordToken", mProfileUserId);
        try {
            changeUserCredential(devicePassword, null, mParentUserId);
            changeUserCredential(null, devicePassword, mParentUserId);
            changeUserCredential(devicePassword, null, mParentUserId);
            lockProfile();
            runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".ResetPasswordWithTokenTest",
                    "testResetPasswordBeforeUnlock", mProfileUserId);
            verifyUserCredential(RESET_PASSWORD_TEST_DEFAULT_PASSWORD, mProfileUserId);
        } finally {
            changeUserCredential(null, devicePassword, mParentUserId);
            // Cycle the device screen to flush stale password information from keyguard,
            // otherwise it will still ask for the non-existent password.
            // return screen to be on for cts test runs
            executeShellCommand("input keyevent KEYCODE_WAKEUP");
            executeShellCommand("input keyevent KEYCODE_SLEEP");
            executeShellCommand("input keyevent KEYCODE_WAKEUP");
        }
    }

    @LockSettingsTest
    @Test
    public void testIsUsingUnifiedPassword() throws Exception {
        assumeHasSecureLockScreenFeature();

        // Freshly created profile has no separate challenge.
        verifyUnifiedPassword(true);

        // Set separate challenge and verify that the API reports it correctly.
        changeUserCredential(
                TEST_PASSWORD /* newCredential */, null /* oldCredential */, mProfileUserId);
        verifyUnifiedPassword(false);
    }

    @FlakyTest
    @LargeTest
    @LockSettingsTest
    @Test
    public void testUnlockWorkProfile_deviceWidePassword() throws Exception {
        assumeHasFileBasedEncryptionAndSecureLockScreenFeatures();

        try {
            // Add a device password after the work profile has been created.
            changeUserCredential(TEST_PASSWORD, /* oldCredential= */ null, mPrimaryUserId);
            // Lock the profile with key eviction.
            lockProfile();
            // Turn on work profile, by unlocking the profile with the device password.
            verifyUserCredential(TEST_PASSWORD, mPrimaryUserId);

            // Verify profile user is running unlocked by running a basic test on the work profile.
            installAppAsUser(SIMPLE_APP_APK, mProfileUserId);
            runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".BasicTest", mProfileUserId);
        } finally {
            // Clean up
            changeUserCredential(/* newCredential= */ null, TEST_PASSWORD, mPrimaryUserId);
        }
    }

    @FlakyTest
    @LargeTest
    @LockSettingsTest
    @Test
    public void testRebootDevice_unifiedPassword() throws Exception {
        assumeHasSecureLockScreenFeature();

        // Waiting before rebooting prevents flakiness.
        waitForBroadcastIdle();
        changeUserCredential(TEST_PASSWORD, /* oldCredential= */ null, mPrimaryUserId);
        try {
            rebootAndWaitUntilReady();
            verifyUserCredential(TEST_PASSWORD, mPrimaryUserId);
            waitForUserUnlock(mProfileUserId);
            installAppAsUser(SIMPLE_APP_APK, mProfileUserId);
            runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".BasicTest", mProfileUserId);
        } finally {
            changeUserCredential(/* newCredential= */ null, TEST_PASSWORD, mPrimaryUserId);
            // Work-around for http://b/113866275 - password prompt being erroneously shown at the
            // end.
            pressPowerButton();
        }
    }

    @LargeTest
    @LockSettingsTest
    @Test
    public void testRebootDevice_separatePasswords() throws Exception {
        assumeHasSecureLockScreenFeature();

        // Waiting before rebooting prevents flakiness.
        waitForBroadcastIdle();
        final String profilePassword = "profile";
        final String primaryPassword = TEST_PASSWORD;
        int managedProfileUserId = getFirstManagedProfileUserId();
        changeUserCredential(
                profilePassword, /* oldCredential= */ null, managedProfileUserId);
        changeUserCredential(primaryPassword, /* oldCredential= */ null, mPrimaryUserId);
        try {
            rebootAndWaitUntilReady();
            verifyUserCredential(profilePassword, managedProfileUserId);
            verifyUserCredential(primaryPassword, mPrimaryUserId);
            installAppAsUser(SIMPLE_APP_APK, mProfileUserId);
            runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".BasicTest", mProfileUserId);
        } finally {
            changeUserCredential(
                    /* newCredential= */ null, profilePassword, managedProfileUserId);
            changeUserCredential(/* newCredential= */ null, primaryPassword, mPrimaryUserId);
            // Work-around for http://b/113866275 - password prompt being erroneously shown at the
            // end.
            pressPowerButton();
        }
    }

    @Test
    public void testCreateSeparateChallengeChangedLogged() throws Exception {
        assumeHasSecureLockScreenFeature();

        assertMetricsLogged(getDevice(), () -> {
            changeUserCredential(
                    TEST_PASSWORD /* newCredential */, null /* oldCredential */, mProfileUserId);
        }, new DevicePolicyEventWrapper.Builder(EventId.SEPARATE_PROFILE_CHALLENGE_CHANGED_VALUE)
                .setBoolean(true)
                .build());
    }

    @Test
    public void testActivePasswordSufficientForDeviceRequirement() throws Exception {
        assumeHasSecureLockScreenFeature();

        runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".ActivePasswordSufficientForDeviceTest",
                mProfileUserId);
    }

    private void verifyUnifiedPassword(boolean unified) throws DeviceNotAvailableException {
        final String testMethod =
                unified ? "testUsingUnifiedPassword" : "testNotUsingUnifiedPassword";
        runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".IsUsingUnifiedPasswordTest",
                testMethod, mProfileUserId);
    }

    private void lockProfile() throws Exception {
        final String cmd = "am broadcast --receiver-foreground --user " + mProfileUserId
                + " -a com.android.cts.managedprofile.LOCK_PROFILE"
                + " com.android.cts.managedprofile/.LockProfileReceiver";
        getDevice().executeShellCommand(cmd);
        waitUntilProfileLocked();
    }

    private void waitUntilProfileLocked() throws Exception {
        final String cmd = String.format("am get-started-user-state %d", mProfileUserId);
        tryWaitForSuccess(
                () -> getDevice().executeShellCommand(cmd).startsWith(USER_STATE_LOCKED),
                "The managed profile has not been locked after calling "
                        + "lockNow(FLAG_SECURE_USER_DATA)",
                TIMEOUT_USER_LOCKED_MILLIS);
    }
}
