/*
 * Copyright (C) 2018 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.jobscheduler.cts;

import android.annotation.TargetApi;
import android.app.job.JobInfo;
import android.os.SystemClock;
import android.support.test.uiautomator.UiDevice;

import androidx.test.InstrumentationRegistry;

/**
 * Make sure the state of {@link android.app.job.JobScheduler} is correct.
 */
@TargetApi(28)
public class DeviceStatesTest extends ConstraintTest {
    /** Unique identifier for the job scheduled by this suite of tests. */
    public static final int STATE_JOB_ID = DeviceStatesTest.class.hashCode();

    private JobInfo.Builder mBuilder;
    private UiDevice mUiDevice;

    @Override
    public void setUp() throws Exception {
        super.setUp();
        mBuilder = new JobInfo.Builder(STATE_JOB_ID, kJobServiceComponent);
        mUiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
    }

    @Override
    public void tearDown() throws Exception {
        mJobScheduler.cancel(STATE_JOB_ID);
        // Put device back in to normal operation.
        toggleScreenOn(true /* screen on */);
    }

    void assertJobReady() throws Exception {
        assertJobReady(STATE_JOB_ID);
    }

    void assertJobWaiting() throws Exception {
        assertJobWaiting(STATE_JOB_ID);
    }

    void assertJobNotReady() throws Exception {
        assertJobNotReady(STATE_JOB_ID);
    }

    static void waitFor(long waitMillis) throws Exception {
        final long deadline = SystemClock.uptimeMillis() + waitMillis;
        do {
             Thread.sleep(500L);
        } while (SystemClock.uptimeMillis() < deadline);
    }

    /**
     * Toggle device is dock idle or dock active.
     */
    private void toggleFakeDeviceDockState(final boolean idle) throws Exception {
        mUiDevice.executeShellCommand("cmd jobscheduler trigger-dock-state "
                + (idle ? "idle" : "active"));
        // Wait a moment to let that happen before proceeding.
        waitFor(2_000);
    }

    /**
     * Make sure the screen state.
     */
    private void toggleScreenOn(final boolean screenon) throws Exception {
        if (screenon) {
            mUiDevice.executeShellCommand("input keyevent KEYCODE_WAKEUP");
        } else {
            mUiDevice.executeShellCommand("input keyevent KEYCODE_SLEEP");
        }
        // Since the screen on/off intent is ordered, they will not be sent right now.
        waitFor(2_000);
    }

    /**
     * Simulated for idle, and then perform idle maintenance now.
     */
    private void triggerIdleMaintenance() throws Exception {
        mUiDevice.executeShellCommand("cmd activity idle-maintenance");
        // Wait a moment to let that happen before proceeding.
        waitFor(2_000);
    }

    /**
     * Schedule a job that requires the device is idle, and assert it fired to make
     * sure the device is idle.
     */
    void verifyIdleState() throws Exception {
        kTestEnvironment.setExpectedExecutions(1);
        kTestEnvironment.setExpectedWaitForRun();
        mJobScheduler.schedule(mBuilder.setRequiresDeviceIdle(true).build());
        assertJobReady();
        kTestEnvironment.readyToRun();

        assertTrue("Job with idle constraint did not fire on idle",
                kTestEnvironment.awaitExecution());
    }

    /**
     * Schedule a job that requires the device is idle, and assert it failed to make
     * sure the device is active.
     */
    void verifyActiveState() throws Exception {
        kTestEnvironment.setExpectedExecutions(0);
        kTestEnvironment.setExpectedWaitForRun();
        mJobScheduler.schedule(mBuilder.setRequiresDeviceIdle(true).build());
        assertJobWaiting();
        assertJobNotReady();
        kTestEnvironment.readyToRun();

        assertFalse("Job with idle constraint fired while not on idle.",
                kTestEnvironment.awaitExecution(250));
    }

    /**
     * Ensure that device can switch state normally.
     */
    public void testDeviceChangeIdleActiveState() throws Exception {
        toggleScreenOn(true /* screen on */);
        verifyActiveState();

        // Assert device is idle when screen is off for a while.
        toggleScreenOn(false /* screen off */);
        triggerIdleMaintenance();
        verifyIdleState();

        // Assert device is back to active when screen is on.
        toggleScreenOn(true /* screen on */);
        verifyActiveState();
    }

    /**
     * Ensure that device can switch state on dock normally.
     */
    public void testScreenOnDeviceOnDockChangeState() throws Exception {
        toggleScreenOn(true /* screen on */);
        verifyActiveState();

        // Assert device go to idle if user doesn't interact with device for a while.
        toggleFakeDeviceDockState(true /* idle */);
        triggerIdleMaintenance();
        verifyIdleState();

        // Assert device go back to active if user interacts with device.
        toggleFakeDeviceDockState(false /* active */);
        verifyActiveState();
    }

    /**
     *  Ensure that ignores this dock intent during screen off.
     */
    public void testScreenOffDeviceOnDockNoChangeState() throws Exception {
        toggleScreenOn(false /* screen off */);
        triggerIdleMaintenance();
        verifyIdleState();

        toggleFakeDeviceDockState(false /* active */);
        verifyIdleState();
    }
}
