// 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;

import static org.chromium.chrome.browser.vr.XrTestFramework.PAGE_LOAD_TIMEOUT_S;
import static org.chromium.chrome.browser.vr.XrTestFramework.POLL_CHECK_INTERVAL_SHORT_MS;
import static org.chromium.chrome.browser.vr.XrTestFramework.POLL_TIMEOUT_LONG_MS;
import static org.chromium.chrome.browser.vr.XrTestFramework.POLL_TIMEOUT_SHORT_MS;
import static org.chromium.chrome.test.util.ChromeRestriction.RESTRICTION_TYPE_DEVICE_NON_DAYDREAM;
import static org.chromium.chrome.test.util.ChromeRestriction.RESTRICTION_TYPE_VIEWER_DAYDREAM;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.support.test.InstrumentationRegistry;
import android.support.test.filters.LargeTest;
import android.support.test.filters.MediumTest;
import android.widget.ImageView;

import org.junit.Assert;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;

import org.chromium.base.ThreadUtils;
import org.chromium.base.test.util.CommandLineFlags;
import org.chromium.base.test.util.Restriction;
import org.chromium.chrome.R;
import org.chromium.chrome.browser.ChromeSwitches;
import org.chromium.chrome.browser.ChromeTabbedActivity;
import org.chromium.chrome.browser.preferences.Preferences;
import org.chromium.chrome.browser.preferences.PreferencesLauncher;
import org.chromium.chrome.browser.preferences.website.SingleWebsitePreferences;
import org.chromium.chrome.browser.vr.mock.MockVrDaydreamApi;
import org.chromium.chrome.browser.vr.rules.ChromeTabbedActivityVrTestRule;
import org.chromium.chrome.browser.vr.util.NativeUiUtils;
import org.chromium.chrome.browser.vr.util.NfcSimUtils;
import org.chromium.chrome.browser.vr.util.VrBrowserTransitionUtils;
import org.chromium.chrome.browser.vr.util.VrShellDelegateUtils;
import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
import org.chromium.chrome.test.util.ActivityUtils;
import org.chromium.content.browser.test.util.CriteriaHelper;
import org.chromium.content.browser.test.util.DOMUtils;
import org.chromium.content.browser.test.util.JavaScriptUtils;

import java.util.concurrent.TimeoutException;

/**
 * End-to-end tests for state transitions in VR, e.g. exiting WebVR presentation
 * into the VR browser.
 */
@RunWith(ChromeJUnit4ClassRunner.class)
@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE})
public class VrBrowserTransitionTest {
    // We explicitly instantiate a rule here instead of using parameterization since this class
    // only ever runs in ChromeTabbedActivity.
    @Rule
    public ChromeTabbedActivityVrTestRule mTestRule = new ChromeTabbedActivityVrTestRule();

    private WebXrVrTestFramework mWebXrVrTestFramework;
    private WebVrTestFramework mWebVrTestFramework;
    private VrBrowserTestFramework mVrBrowserTestFramework;

    @Before
    public void setUp() throws Exception {
        mWebXrVrTestFramework = new WebXrVrTestFramework(mTestRule);
        mWebVrTestFramework = new WebVrTestFramework(mTestRule);
        mVrBrowserTestFramework = new VrBrowserTestFramework(mTestRule);
    }

    private void enterVrShellNfc(boolean supported) {
        InstrumentationRegistry.getInstrumentation().waitForIdleSync();
        if (supported) {
            NfcSimUtils.simNfcScanUntilVrEntry(mTestRule.getActivity());
            Assert.assertTrue("Browser is not in VR", VrShellDelegate.isInVr());
        } else {
            NfcSimUtils.simNfcScan(mTestRule.getActivity());
            Assert.assertFalse("Browser is in VR", VrShellDelegate.isInVr());
        }
        VrBrowserTransitionUtils.forceExitVr();
    }

    private void enterExitVrShell(boolean supported) {
        MockVrDaydreamApi mockApi = new MockVrDaydreamApi();
        if (!supported) {
            VrShellDelegateUtils.getDelegateInstance().overrideDaydreamApiForTesting(mockApi);
        }
        VrBrowserTransitionUtils.forceEnterVrBrowser();
        if (supported) {
            VrBrowserTransitionUtils.waitForVrEntry(POLL_TIMEOUT_LONG_MS);
            Assert.assertTrue("Browser is not in VR", VrShellDelegate.isInVr());
        } else {
            Assert.assertFalse("launchInVr was called", mockApi.getLaunchInVrCalled());
            Assert.assertFalse("Browser is in VR", VrShellDelegate.isInVr());
        }
        VrBrowserTransitionUtils.forceExitVr();
        Assert.assertFalse("Browser is in VR", VrShellDelegate.isInVr());
    }

    /**
     * Verifies that browser successfully transitions from 2D Chrome to the VR
     * browser when the Daydream View NFC tag is scanned on a Daydream-ready device.
     */
    @Test
    @Restriction({RESTRICTION_TYPE_VIEWER_DAYDREAM})
    @LargeTest
    public void test2dtoVrShellNfcSupported() {
        enterVrShellNfc(true /* supported */);
    }

    /**
     * Verifies that the browser does not transition from 2D chrome to the VR
     * browser when the Daydream View NFC tag is scanned on a non-Daydream-ready
     * device.
     */
    @Test
    @Restriction(RESTRICTION_TYPE_DEVICE_NON_DAYDREAM)
    @MediumTest
    public void test2dtoVrShellNfcUnsupported() {
        enterVrShellNfc(false /* supported */);
    }

    /**
     * Verifies that browser successfully transitions from 2D chrome to the VR
     * browser and back when the VrShellDelegate tells it to on a Daydream-ready
     * device.
     */
    @Test
    @Restriction(RESTRICTION_TYPE_VIEWER_DAYDREAM)
    @MediumTest
    public void test2dtoVrShellto2dSupported() {
        enterExitVrShell(true /* supported */);
    }

    /**
     * Verifies that browser successfully transitions from 2D Chrome to the VR
     * browser when Chrome gets a VR intent.
     */
    @Test
    @Restriction(RESTRICTION_TYPE_VIEWER_DAYDREAM)
    @MediumTest
    public void testVrIntentStartsVrShell() {
        testVrEntryIntentInternal();
    }

    private String testVrEntryIntentInternal() {
        // Send a VR intent, which will open the link in a CTA.
        final String url =
                VrBrowserTestFramework.getFileUrlForHtmlTestFile("test_navigation_2d_page");
        VrBrowserTransitionUtils.sendVrLaunchIntent(
                url, false /* autopresent */, true /* avoidRelaunch */);

        // Wait until we enter VR and have the correct URL.
        VrBrowserTransitionUtils.waitForVrEntry(POLL_TIMEOUT_LONG_MS);
        CriteriaHelper.pollUiThread(
                ()
                        -> { return mTestRule.getWebContents().getVisibleUrl().equals(url); },
                "Displayed URL does not match URL provided to VR launch intent",
                POLL_TIMEOUT_LONG_MS, POLL_CHECK_INTERVAL_SHORT_MS);
        return url;
    }

    /**
     * Verifies that browser successfully transitions from 2D Chrome to the VR
     * browser when Chrome gets a VR intent, and returns to 2D when Chrome receives a 2D Intent.
     */
    @Test
    @Restriction(RESTRICTION_TYPE_VIEWER_DAYDREAM)
    @MediumTest
    public void test2dIntentExitsVrShell() {
        TestVrShellDelegate.getInstance().setAllow2dIntents(true);
        String url = testVrEntryIntentInternal();

        VrBrowserTransitionUtils.send2dMainIntent();
        CriteriaHelper.pollUiThread(() -> {
            return !VrShellDelegate.isInVr();
        }, "2D intent did not exit VR", POLL_TIMEOUT_LONG_MS, POLL_CHECK_INTERVAL_SHORT_MS);
        Assert.assertEquals("URL is incorrect", url, mTestRule.getWebContents().getVisibleUrl());
    }

    /**
     * Verifies that browser does not enter VR mode on Non-Daydream-ready devices.
     */
    @Test
    @Restriction(RESTRICTION_TYPE_DEVICE_NON_DAYDREAM)
    @MediumTest
    public void test2dtoVrShellto2dUnsupported() {
        enterExitVrShell(false /* supported */);
    }

    /**
     * Tests that we exit fullscreen mode after exiting VR from cinema mode.
     */
    @Test
    @Restriction(RESTRICTION_TYPE_VIEWER_DAYDREAM)
    @MediumTest
    public void testExitFullscreenAfterExitingVrFromCinemaMode()
            throws InterruptedException, TimeoutException {
        VrBrowserTransitionUtils.forceEnterVrBrowserOrFail(POLL_TIMEOUT_LONG_MS);
        mVrBrowserTestFramework.loadUrlAndAwaitInitialization(
                VrBrowserTestFramework.getFileUrlForHtmlTestFile("test_navigation_2d_page"),
                PAGE_LOAD_TIMEOUT_S);
        DOMUtils.clickNode(mVrBrowserTestFramework.getFirstTabWebContents(), "fullscreen",
                false /* goThroughRootAndroidView */);
        mVrBrowserTestFramework.waitOnJavaScriptStep();

        Assert.assertTrue("Page is not in fullscreen",
                DOMUtils.isFullscreen(mVrBrowserTestFramework.getFirstTabWebContents()));
        VrBrowserTransitionUtils.forceExitVr();
        // The fullscreen exit from exiting VR isn't necessarily instantaneous, so give it
        // a bit of time.
        CriteriaHelper.pollInstrumentationThread(
                ()
                        -> {
                    try {
                        return !DOMUtils.isFullscreen(
                                mVrBrowserTestFramework.getFirstTabWebContents());
                    } catch (InterruptedException | TimeoutException e) {
                        return false;
                    }
                },
                "Exiting VR did not exit fullscreen", POLL_TIMEOUT_SHORT_MS,
                POLL_CHECK_INTERVAL_SHORT_MS);
        mVrBrowserTestFramework.assertNoJavaScriptErrors();
    }

    /**
     * Tests that the reported display dimensions are correct when exiting
     * from WebVR presentation to the VR browser.
     */
    @Test
    @CommandLineFlags.Add("enable-webvr")
    @Restriction(RESTRICTION_TYPE_VIEWER_DAYDREAM)
    @MediumTest
    public void testExitPresentationWebVrToVrShell()
            throws IllegalArgumentException, InterruptedException, TimeoutException {
        exitPresentationToVrShellImpl(
                WebVrTestFramework.getFileUrlForHtmlTestFile("test_navigation_webvr_page"),
                mWebVrTestFramework);
    }

    /**
     * Tests that the reported display dimensions are correct when exiting
     * from WebVR presentation to the VR browser.
     */
    @Test
    @CommandLineFlags.Add("enable-features=WebXR")
    @Restriction(RESTRICTION_TYPE_VIEWER_DAYDREAM)
    @MediumTest
    public void testExitPresentationWebXrToVrShell()
            throws IllegalArgumentException, InterruptedException, TimeoutException {
        exitPresentationToVrShellImpl(
                WebXrVrTestFramework.getFileUrlForHtmlTestFile("test_navigation_webxr_page"),
                mWebXrVrTestFramework);
    }

    private void exitPresentationToVrShellImpl(String url, WebXrVrTestFramework framework)
            throws InterruptedException {
        VrBrowserTransitionUtils.forceEnterVrBrowserOrFail(POLL_TIMEOUT_LONG_MS);
        framework.loadUrlAndAwaitInitialization(url, PAGE_LOAD_TIMEOUT_S);
        VrShellImpl vrShellImpl = (VrShellImpl) TestVrShellDelegate.getVrShellForTesting();
        float expectedWidth = vrShellImpl.getContentWidthForTesting();
        float expectedHeight = vrShellImpl.getContentHeightForTesting();
        framework.enterSessionWithUserGestureOrFail();

        // Validate our size is what we expect while in VR.
        // We aren't comparing for equality because there is some rounding that occurs.
        String javascript = "Math.abs(screen.width - " + expectedWidth + ") <= 1 && "
                + "Math.abs(screen.height - " + expectedHeight + ") <= 1";
        framework.pollJavaScriptBooleanOrFail(javascript, POLL_TIMEOUT_LONG_MS);

        // Exit presentation through JavaScript.
        framework.endSession();

        framework.pollJavaScriptBooleanOrFail(javascript, POLL_TIMEOUT_LONG_MS);
        framework.assertNoJavaScriptErrors();
    }

    /**
     * Tests that entering WebVR presentation from the VR browser, exiting presentation, and
     * re-entering presentation works. This is a regression test for crbug.com/799999.
     */
    @Test
    @CommandLineFlags.Add("enable-webvr")
    @Restriction(RESTRICTION_TYPE_VIEWER_DAYDREAM)
    @MediumTest
    public void testWebVrReEntryFromVrBrowser() throws InterruptedException, TimeoutException {
        reEntryFromVrBrowserImpl(
                WebVrTestFramework.getFileUrlForHtmlTestFile("test_webvr_reentry_from_vr_browser"),
                mWebVrTestFramework);
    }

    /**
     * Tests that entering WebVR presentation from the VR browser, exiting presentation, and
     * re-entering presentation works. This is a regression test for crbug.com/799999.
     */
    @Test
    @CommandLineFlags.Add("enable-features=WebXR")
    @Restriction(RESTRICTION_TYPE_VIEWER_DAYDREAM)
    @MediumTest
    public void testWebXrReEntryFromVrBrowser() throws InterruptedException, TimeoutException {
        reEntryFromVrBrowserImpl(WebXrVrTestFramework.getFileUrlForHtmlTestFile(
                                         "test_webxr_reentry_from_vr_browser"),
                mWebXrVrTestFramework);
    }

    private void reEntryFromVrBrowserImpl(String url, WebXrVrTestFramework framework)
            throws InterruptedException {
        VrBrowserTransitionUtils.forceEnterVrBrowserOrFail(POLL_TIMEOUT_LONG_MS);
        EmulatedVrController controller = new EmulatedVrController(mTestRule.getActivity());

        framework.loadUrlAndAwaitInitialization(url, PAGE_LOAD_TIMEOUT_S);
        framework.enterSessionWithUserGestureOrFail();

        framework.executeStepAndWait("stepVerifyFirstPresent()");
        // The bug did not reproduce with vrDisplay.exitPresent(), so it might not reproduce with
        // session.end(). Instead, use the controller to exit.
        controller.pressReleaseAppButton();
        framework.executeStepAndWait("stepVerifyMagicWindow()");

        framework.enterSessionWithUserGestureOrFail();
        framework.executeStepAndWait("stepVerifySecondPresent()");

        framework.endTest();
    }

    /**
     * Tests that you can enter VR in Overview mode, and the NTP shows up.
     */
    @Test
    @Restriction(RESTRICTION_TYPE_VIEWER_DAYDREAM)
    @MediumTest
    public void testEnterVrInOverviewMode() throws InterruptedException, TimeoutException {
        final ChromeTabbedActivity activity = mTestRule.getActivity();
        ThreadUtils.runOnUiThreadBlocking(() -> {
            ImageView tabSwitcher = (ImageView) activity.findViewById(R.id.tab_switcher_button);
            tabSwitcher.callOnClick();
        });

        Assert.assertTrue("Browser is not in overview mode", activity.isInOverviewMode());

        MockVrDaydreamApi mockApi = new MockVrDaydreamApi();
        VrShellDelegateUtils.getDelegateInstance().overrideDaydreamApiForTesting(mockApi);
        VrBrowserTransitionUtils.forceEnterVrBrowserOrFail(POLL_TIMEOUT_LONG_MS);
        Assert.assertFalse("exitFromVr was called", mockApi.getExitFromVrCalled());
        Assert.assertFalse("launchVrHomescreen was called", mockApi.getLaunchVrHomescreenCalled());
        VrShellDelegateUtils.getDelegateInstance().overrideDaydreamApiForTesting(null);
    }

    /**
     * Tests that attempting to start an Activity through the Activity context in VR triggers DOFF.
     */
    @Test
    @Restriction(RESTRICTION_TYPE_VIEWER_DAYDREAM)
    @MediumTest
    public void testStartActivityTriggersDoffChromeActivity()
            throws InterruptedException, TimeoutException {
        testStartActivityTriggersDoffImpl(mTestRule.getActivity());
    }

    /**
     * Tests that attempting to start an Activity through the Application context in VR triggers
     * DOFF.
     */
    @Test
    @Restriction(RESTRICTION_TYPE_VIEWER_DAYDREAM)
    @MediumTest
    public void testStartActivityTriggersDoffAppContext()
            throws InterruptedException, TimeoutException {
        testStartActivityTriggersDoffImpl(mTestRule.getActivity().getApplicationContext());
    }

    private void testStartActivityTriggersDoffImpl(Context context)
            throws InterruptedException, TimeoutException {
        VrBrowserTransitionUtils.forceEnterVrBrowserOrFail(POLL_TIMEOUT_LONG_MS);

        MockVrDaydreamApi mockApi = new MockVrDaydreamApi();
        mockApi.setExitFromVrReturnValue(false);
        VrShellDelegateUtils.getDelegateInstance().overrideDaydreamApiForTesting(mockApi);

        NativeUiUtils.performActionAndWaitForUiQuiescence(() -> {
            ThreadUtils.runOnUiThreadBlocking(() -> {
                Intent preferencesIntent = PreferencesLauncher.createIntentForSettingsPage(
                        context, SingleWebsitePreferences.class.getName());
                context.startActivity(preferencesIntent);
            });
        });
        ThreadUtils.runOnUiThreadBlocking(
                () -> { VrShellDelegateUtils.getDelegateInstance().acceptDoffPromptForTesting(); });

        CriteriaHelper.pollUiThread(
                () -> { return mockApi.getExitFromVrCalled(); }, "exitFromVr was not called");
        Assert.assertFalse("launchVrHomescreen was called", mockApi.getLaunchVrHomescreenCalled());
        mockApi.close();

        MockVrDaydreamApi mockApiWithDoff = new MockVrDaydreamApi();
        mockApiWithDoff.setExitFromVrReturnValue(true);

        VrShellDelegateUtils.getDelegateInstance().overrideDaydreamApiForTesting(mockApiWithDoff);

        ThreadUtils.runOnUiThreadBlocking(() -> {
            PreferencesLauncher.launchSettingsPage(context, null);
            VrShellDelegateUtils.getDelegateInstance().acceptDoffPromptForTesting();
        });
        CriteriaHelper.pollUiThread(() -> {
            return VrShellDelegateUtils.getDelegateInstance().isShowingDoff();
        }, "DOFF screen was not shown");
        ThreadUtils.runOnUiThreadBlocking(() -> {
            mTestRule.getActivity().onActivityResult(
                    VrShellDelegate.EXIT_VR_RESULT, Activity.RESULT_OK, null);
        });

        ActivityUtils.waitForActivity(
                InstrumentationRegistry.getInstrumentation(), Preferences.class);
        VrShellDelegateUtils.getDelegateInstance().overrideDaydreamApiForTesting(null);
    }

    /**
     * Tests that attempting to start an Activity through the Activity context in VR triggers DOFF.
     */
    @Test
    @Restriction(RESTRICTION_TYPE_VIEWER_DAYDREAM)
    @MediumTest
    public void testStartActivityIfNeeded() throws InterruptedException, TimeoutException {
        Activity context = mTestRule.getActivity();
        VrBrowserTransitionUtils.forceEnterVrBrowserOrFail(POLL_TIMEOUT_LONG_MS);

        ThreadUtils.runOnUiThreadBlocking(() -> {
            Intent preferencesIntent = PreferencesLauncher.createIntentForSettingsPage(
                    context, SingleWebsitePreferences.class.getName());
            Assert.assertFalse("Starting an activity did not trigger DOFF",
                    context.startActivityIfNeeded(preferencesIntent, 0));
        });
    }

    /**
     * Tests that exiting VR while a permission prompt or JavaScript dialog is being displayed
     * does not cause a browser crash. Regression test for https://crbug.com/821443.
     */
    @Test
    @Restriction(RESTRICTION_TYPE_VIEWER_DAYDREAM)
    @LargeTest
    @CommandLineFlags.Add("enable-features=VrBrowsingNativeAndroidUi")
    public void testExitVrWithPromptDisplayed() throws InterruptedException, TimeoutException {
        mVrBrowserTestFramework.loadUrlAndAwaitInitialization(
                VrBrowserTestFramework.getFileUrlForHtmlTestFile("test_navigation_2d_page"),
                PAGE_LOAD_TIMEOUT_S);

        // Test JavaScript dialogs.
        VrBrowserTransitionUtils.forceEnterVrBrowserOrFail(POLL_TIMEOUT_LONG_MS);
        // Alerts block JavaScript execution until they're closed, so we can't use the normal
        // runJavaScriptOrFail, as that will time out.
        JavaScriptUtils.executeJavaScript(
                mVrBrowserTestFramework.getFirstTabWebContents(), "alert('Please no crash')");
        VrBrowserTransitionUtils.waitForNativeUiPrompt(POLL_TIMEOUT_LONG_MS);
        VrBrowserTransitionUtils.forceExitVr();

        // Test permission prompts.
        VrBrowserTransitionUtils.forceEnterVrBrowserOrFail(POLL_TIMEOUT_LONG_MS);
        mVrBrowserTestFramework.runJavaScriptOrFail(
                "navigator.getUserMedia({video: true}, ()=>{}, ()=>{})", POLL_TIMEOUT_SHORT_MS);
        VrBrowserTransitionUtils.waitForNativeUiPrompt(POLL_TIMEOUT_LONG_MS);
        VrBrowserTransitionUtils.forceExitVr();
        mVrBrowserTestFramework.assertNoJavaScriptErrors();
    }
}
