// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

package org.chromium.chrome.browser.vr_shell;

import static org.chromium.chrome.browser.vr_shell.VrUtils.POLL_CHECK_INTERVAL_LONG_MS;
import static org.chromium.chrome.browser.vr_shell.VrUtils.POLL_CHECK_INTERVAL_SHORT_MS;
import static org.chromium.chrome.browser.vr_shell.VrUtils.POLL_TIMEOUT_LONG_MS;
import static org.chromium.chrome.browser.vr_shell.VrUtils.POLL_TIMEOUT_SHORT_MS;
import static org.chromium.chrome.test.util.ChromeRestriction.RESTRICTION_TYPE_VIEWER_DAYDREAM;
import static org.chromium.chrome.test.util.ChromeRestriction.RESTRICTION_TYPE_VIEWER_NON_DAYDREAM;
import static org.chromium.chrome.test.util.ChromeRestriction.RESTRICTION_TYPE_WEBVR_SUPPORTED;

import android.os.Build;
import android.support.test.filters.LargeTest;
import android.support.test.filters.MediumTest;
import android.support.test.filters.SmallTest;
import android.widget.TextView;

import org.chromium.base.Log;
import org.chromium.base.test.util.CommandLineFlags;
import org.chromium.base.test.util.Restriction;
import org.chromium.base.test.util.UrlUtils;
import org.chromium.chrome.R;
import org.chromium.chrome.test.ChromeTabbedActivityTestBase;
import org.chromium.content.browser.test.util.ClickUtils;
import org.chromium.content.browser.test.util.Criteria;
import org.chromium.content.browser.test.util.CriteriaHelper;
import org.chromium.content.browser.test.util.JavaScriptUtils;
import org.chromium.content_public.browser.WebContents;

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

/**
 * This is a workaround for testing aspects of WebVR that aren't testable with
 * WebVR's mocked layout tests, such as E2E tests.
 *
 * The general test flow is:
 * - Load the HTML file containing the test, which:
 *   - Loads the WebVR boilerplate code and some test functions
 *   - Sets up common elements like the canvas and synchronization variable
 *   - Sets up any steps that need to be triggered by the Java code
 * - Check if any VRDisplay objects were found and fail the test if it doesn't
 *       match what we expect for that test
 * - Repeat:
 *   - Run any necessary Java-side code, e.g. trigger a user action
 *   - Trigger the next JavaScript test step and wait for it to finish
 *
 * The JavaScript code will automatically process test results once all
 * testharness.js tests are done, just like in layout tests. Once the results
 * are processed, the JavaScript code will automatically signal the Java code,
 * which can then grab the results and pass/fail the instrumentation test.
 */
@CommandLineFlags.Add("enable-webvr")
@Restriction(RESTRICTION_TYPE_WEBVR_SUPPORTED)
public class WebVrTest extends ChromeTabbedActivityTestBase {
    private static final String TAG = "WebVrTest";
    private static final String TEST_DIR = "chrome/test/data/android/webvr_instrumentation";
    private static final int PAGE_LOAD_TIMEOUT_S = 10;

    private WebContents mWebContents;

    @Override
    protected void setUp() throws Exception {
        super.setUp();
        mWebContents = getActivity().getActivityTab().getWebContents();
    }

    @Override
    public void startMainActivity() throws InterruptedException {
        startMainActivityOnBlankPage();
    }

    /**
     * Gets the file:// URL to the test file
     * @param testName The name of the test whose file will be retrieved
     * @return The file:// URL to the specified test file
     */
    private String getHtmlTestFile(String testName) {
        return "file://" + UrlUtils.getIsolatedTestFilePath(TEST_DIR) + "/html/" + testName
                + ".html";
    }

    /**
     * Blocks until the promise returned by nagivator.getVRDisplays() resolves,
     * then checks whether a VRDisplay was actually found.
     * @param webContents The WebContents to run the JavaScript through
     * @return Whether a VRDisplay was found
     */
    private boolean vrDisplayFound(WebContents webContents) {
        pollJavaScriptBoolean("vrDisplayPromiseDone", POLL_TIMEOUT_SHORT_MS, webContents);
        return !runJavaScriptOrFail("vrDisplay", POLL_TIMEOUT_SHORT_MS, webContents).equals("null");
    }

    /**
     * Use to tap in the middle of the screen, triggering the canvas' onclick
     * to fulfil WebVR's gesture requirement for presenting.
     */
    private void enterVrTap() {
        ClickUtils.mouseSingleClickView(
                getInstrumentation(), getActivity().getWindow().getDecorView().getRootView());
    }

    /**
     * Taps in the middle of the screen then waits for the JavaScript step to finish.
     * @param webContents The WebContents for the tab the JavaScript step is in
     */
    private void enterVrTapAndWait(WebContents webContents) {
        enterVrTap();
        waitOnJavaScriptStep(webContents);
    }

    /**
     * Use to simulate a Daydream View NFC scan without blocking afterwards
     */
    private void simNfcScan() {
        VrUtils.simNfc(getActivity());
    }

    /**
     * Simulate an NFC scan and wait for the JavaScript code in the given
     * WebContents to signal that it is done with the step.
     * @param webContents The WebContents for the JavaScript that will be polled
     */
    private void simNfcScanAndWait(WebContents webContents) {
        simNfcScan();
        waitOnJavaScriptStep(webContents);
    }

    /**
     * Helper function to run the given JavaScript, return the return value,
     * and fail if a timeout/interrupt occurs so we don't have to catch or
     * declare exceptions all the time.
     * @param js The JavaScript to run
     * @param timeout The timeout in milliseconds before a failure
     * @param webContents The WebContents object to run the JavaScript in
     * @return The return value of the JavaScript
     */
    private String runJavaScriptOrFail(String js, int timeout, WebContents webContents) {
        try {
            return JavaScriptUtils.executeJavaScriptAndWaitForResult(
                    webContents, js, timeout, TimeUnit.MILLISECONDS);
        } catch (InterruptedException | TimeoutException e) {
            fail("Fatal interruption or timeout running JavaScript: " + js);
        }
        return "Not reached";
    }

    /**
     * Ends the test harness test and checks whether there it passed
     * @param webContents The WebContents for the tab to check results in
     * @return "Passed" if test passed, String with failure reason otherwise
     */
    private String checkResults(WebContents webContents) {
        if (runJavaScriptOrFail("testPassed", POLL_TIMEOUT_SHORT_MS, webContents).equals("true")) {
            return "Passed";
        }
        return runJavaScriptOrFail("resultString", POLL_TIMEOUT_SHORT_MS, webContents);
    }

    /**
     * Helper function to end the test harness test and assert that it passed,
     * setting the failure reason as the description if it didn't.
     * @param webContents The WebContents for the tab to check test results in
     */
    private void endTest(WebContents webContents) {
        assertEquals("Passed", checkResults(webContents));
    }

    /**
     * Polls the provided JavaScript boolean until the timeout is reached or
     * the boolean is true.
     * @param boolName The name of the JavaScript boolean or expression to poll
     * @param timeoutMs The polling timeout in milliseconds
     * @param webContents The WebContents to run the JavaScript through
     * @return True if the boolean evaluated to true, false if timed out
     */
    private boolean pollJavaScriptBoolean(
            final String boolName, int timeoutMs, final WebContents webContents) {
        try {
            CriteriaHelper.pollInstrumentationThread(Criteria.equals(true, new Callable<Boolean>() {
                @Override
                public Boolean call() {
                    String result = "false";
                    try {
                        result = JavaScriptUtils.executeJavaScriptAndWaitForResult(webContents,
                                boolName, POLL_CHECK_INTERVAL_SHORT_MS, TimeUnit.MILLISECONDS);
                    } catch (InterruptedException | TimeoutException e) {
                        // Expected to happen regularly, do nothing
                    }
                    return Boolean.parseBoolean(result);
                }
            }), timeoutMs, POLL_CHECK_INTERVAL_LONG_MS);
        } catch (AssertionError e) {
            Log.d(TAG, "pollJavaScriptBoolean() timed out");
            return false;
        }
        return true;
    }

    /**
     * Waits for a JavaScript step to finish, asserting that the step finished
     * instead of timing out.
     * @param webContents The WebContents for the tab the JavaScript step is in
     */
    private void waitOnJavaScriptStep(WebContents webContents) {
        assertTrue("Polling JavaScript boolean javascriptDone succeeded",
                pollJavaScriptBoolean("javascriptDone", POLL_TIMEOUT_LONG_MS, webContents));
        // Reset the synchronization boolean
        runJavaScriptOrFail("javascriptDone = false", POLL_TIMEOUT_SHORT_MS, webContents);
    }

    /**
     * Executes a JavaScript step function using the given WebContents.
     * @param stepFunction The JavaScript step function to call
     * @param webContents The WebContents for the tab the JavaScript is in
     */
    private void executeStepAndWait(String stepFunction, WebContents webContents) {
        // Run the step and block
        JavaScriptUtils.executeJavaScript(webContents, stepFunction);
        waitOnJavaScriptStep(webContents);
    }

    /**
     * Tests that a successful requestPresent call actually enters VR
     */
    @SmallTest
    public void testRequestPresentEntersVr() throws InterruptedException {
        String testName = "test_requestPresent_enters_vr";
        loadUrl(getHtmlTestFile(testName), PAGE_LOAD_TIMEOUT_S);
        assertTrue("VRDisplay found", vrDisplayFound(mWebContents));
        enterVrTapAndWait(mWebContents);
        assertTrue("VrShellDelegate is in VR", VrShellDelegate.isInVr());
        endTest(mWebContents);
    }

    /**
     * Tests that scanning the Daydream View NFC tag on supported devices fires the
     * vrdisplayactivate event.
     */
    @SmallTest
    @Restriction(RESTRICTION_TYPE_VIEWER_DAYDREAM)
    public void testNfcFiresVrdisplayactivate() throws InterruptedException {
        String testName = "test_nfc_fires_vrdisplayactivate";
        loadUrl(getHtmlTestFile(testName), PAGE_LOAD_TIMEOUT_S);
        simNfcScanAndWait(mWebContents);
        endTest(mWebContents);
    }

    /**
     * Tests that screen touches are not registered when the viewer is a Daydream View.
     */
    @LargeTest
    @Restriction(RESTRICTION_TYPE_VIEWER_DAYDREAM)
    public void testScreenTapsNotRegisteredOnDaydream() throws InterruptedException {
        String testName = "test_screen_taps_not_registered_on_daydream";
        loadUrl(getHtmlTestFile(testName), PAGE_LOAD_TIMEOUT_S);
        assertTrue("VRDisplay found", vrDisplayFound(mWebContents));
        executeStepAndWait("stepVerifyNoInitialTaps()", mWebContents);
        enterVrTapAndWait(mWebContents);
        // Wait on VrShellImpl to say that its parent consumed the touch event
        // Set to 2 because there's an ACTION_DOWN followed by ACTION_UP
        final CountDownLatch touchRegisteredLatch = new CountDownLatch(2);
        ((VrShellImpl) VrShellDelegate.getVrShellForTesting())
                .setOnDispatchTouchEventForTesting(new OnDispatchTouchEventCallback() {
                    @Override
                    public void onDispatchTouchEvent(
                            boolean parentConsumed, boolean cardboardTriggered) {
                        if (!parentConsumed) fail("Parent did not consume event");
                        if (cardboardTriggered) fail("Cardboard event triggered");
                        touchRegisteredLatch.countDown();
                    }
                });
        enterVrTap();
        assertTrue("VrShellImpl dispatched touches",
                touchRegisteredLatch.await(POLL_TIMEOUT_SHORT_MS, TimeUnit.MILLISECONDS));
        executeStepAndWait("stepVerifyNoAdditionalTaps()", mWebContents);
        endTest(mWebContents);
    }

    /**
     * Tests that screen touches are still registered when the viewer is
     * Cardboard.
     */
    @MediumTest
    @Restriction(RESTRICTION_TYPE_VIEWER_NON_DAYDREAM)
    public void testScreenTapsRegisteredOnCardboard() throws InterruptedException {
        String testName = "test_screen_taps_registered_on_cardboard";
        loadUrl(getHtmlTestFile(testName), PAGE_LOAD_TIMEOUT_S);
        assertTrue("VRDisplay found", vrDisplayFound(mWebContents));
        executeStepAndWait("stepVerifyNoInitialTaps()", mWebContents);
        // Tap and wait to enter VR
        enterVrTapAndWait(mWebContents);
        // Tap and wait for JavaScript to receive it
        enterVrTapAndWait(mWebContents);
        endTest(mWebContents);
    }

    /**
     * Tests that non-focused tabs cannot get pose information.
     */
    @SmallTest
    public void testPoseDataUnfocusedTab() throws InterruptedException {
        String testName = "test_pose_data_unfocused_tab";
        loadUrl(getHtmlTestFile(testName), PAGE_LOAD_TIMEOUT_S);
        assertTrue("VRDisplay found", vrDisplayFound(mWebContents));
        executeStepAndWait("stepCheckFrameDataWhileFocusedTab()", mWebContents);

        loadUrlInNewTab("about:blank");

        executeStepAndWait("stepCheckFrameDataWhileNonFocusedTab()", mWebContents);
        endTest(mWebContents);
    }

    /**
     * Helper function to run the tests checking for the upgrade/install InfoBar being present since
     * all that differs is the value returned by VrCoreVersionChecker and a couple asserts.
     *
     * @param checkerReturnValue The value to have the VrCoreVersionChecker return
     */
    private void infoBarTestHelper(int checkerReturnValue) throws InterruptedException {
        MockVrCoreVersionCheckerImpl mockChecker = new MockVrCoreVersionCheckerImpl();
        mockChecker.setMockReturnValue(checkerReturnValue);
        VrShellDelegate.getInstanceForTesting().overrideVrCoreVersionCheckerForTesting(mockChecker);
        String testName = "generic_webvr_page";
        loadUrl(getHtmlTestFile(testName), PAGE_LOAD_TIMEOUT_S);
        String displayFound = "VRDisplay Found";
        String barPresent = "InfoBar present";
        if (checkerReturnValue == VrCoreVersionChecker.VR_READY) {
            assertTrue(displayFound, vrDisplayFound(mWebContents));
            assertFalse(barPresent,
                    VrUtils.isUpdateInstallInfoBarPresent(
                            getActivity().getWindow().getDecorView()));
        } else if (checkerReturnValue == VrCoreVersionChecker.VR_OUT_OF_DATE
                || checkerReturnValue == VrCoreVersionChecker.VR_NOT_AVAILABLE) {
            // Out of date and missing cases are the same, but with different text
            String expectedMessage, expectedButton;
            if (checkerReturnValue == VrCoreVersionChecker.VR_OUT_OF_DATE) {
                expectedMessage =
                        getActivity().getString(R.string.vr_services_check_infobar_update_text);
                expectedButton =
                        getActivity().getString(R.string.vr_services_check_infobar_update_button);
            } else {
                expectedMessage =
                        getActivity().getString(R.string.vr_services_check_infobar_install_text);
                expectedButton =
                        getActivity().getString(R.string.vr_services_check_infobar_install_button);
            }
            assertFalse(displayFound, vrDisplayFound(mWebContents));
            assertTrue(barPresent,
                    VrUtils.isUpdateInstallInfoBarPresent(
                            getActivity().getWindow().getDecorView()));
            TextView tempView = (TextView) getActivity().getWindow().getDecorView().findViewById(
                    R.id.infobar_message);
            assertEquals(expectedMessage, tempView.getText().toString());
            tempView = (TextView) getActivity().getWindow().getDecorView().findViewById(
                    R.id.button_primary);
            assertEquals(expectedButton, tempView.getText().toString());
        } else if (checkerReturnValue == VrCoreVersionChecker.VR_NOT_SUPPORTED) {
            assertFalse(displayFound, vrDisplayFound(mWebContents));
            assertFalse(barPresent,
                    VrUtils.isUpdateInstallInfoBarPresent(
                            getActivity().getWindow().getDecorView()));
        } else {
            fail("Invalid VrCoreVersionChecker value: " + String.valueOf(checkerReturnValue));
        }
        assertEquals(checkerReturnValue, mockChecker.getLastReturnValue());
    }

    /**
     * Tests that the upgrade/install VR Services InfoBar is not present when VR Services is
     * installed and up to date.
     */
    @MediumTest
    public void testInfoBarNotPresentWhenVrServicesCurrent() throws InterruptedException {
        infoBarTestHelper(VrCoreVersionChecker.VR_READY);
    }

    /**
     * Tests that the upgrade VR Services InfoBar is present when VR Services is outdated.
     */
    @MediumTest
    public void testInfoBarPresentWhenVrServicesOutdated() throws InterruptedException {
        infoBarTestHelper(VrCoreVersionChecker.VR_OUT_OF_DATE);
    }

    /**
     * Tests that the install VR Services InfoBar is present when VR Services is missing.
     */
    @MediumTest
    public void testInfoBarPresentWhenVrServicesMissing() throws InterruptedException {
        infoBarTestHelper(VrCoreVersionChecker.VR_NOT_AVAILABLE);
    }

    /**
     * Tests that the install VR Services InfoBar is not present when VR is not supported on the
     * device.
     */
    @MediumTest
    public void testInfoBarNotPresentWhenVrServicesNotSupported() throws InterruptedException {
        infoBarTestHelper(VrCoreVersionChecker.VR_NOT_SUPPORTED);
    }

    /**
     * Tests that the reported WebVR capabilities match expectations on the devices the WebVR tests
     * are run on continuously.
     */
    @MediumTest
    public void testDeviceCapabilitiesMatchExpectations() throws InterruptedException {
        String testName = "test_device_capabilities_match_expectations";
        loadUrl(getHtmlTestFile(testName), PAGE_LOAD_TIMEOUT_S);
        assertTrue("VRDisplayFound", vrDisplayFound(mWebContents));
        executeStepAndWait("stepCheckDeviceCapabilities('" + Build.DEVICE + "')", mWebContents);
        endTest(mWebContents);
    }

    /**
     * Tests that focus is locked to the presenting display for purposes of VR input.
     */
    @MediumTest
    public void testPresentationLocksFocus() throws InterruptedException {
        String testName = "test_presentation_locks_focus";
        loadUrl(getHtmlTestFile(testName), PAGE_LOAD_TIMEOUT_S);
        enterVrTapAndWait(mWebContents);
        waitOnJavaScriptStep(mWebContents);
        endTest(mWebContents);
    }
}
