// Copyright 2012 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.android_webview.test;

import static org.chromium.android_webview.test.AwActivityTestRule.WAIT_TIMEOUT_MS;

import android.support.test.InstrumentationRegistry;
import android.support.test.filters.MediumTest;

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

import org.chromium.android_webview.AwContents;
import org.chromium.android_webview.test.util.CommonResources;
import org.chromium.android_webview.test.util.JSUtils;
import org.chromium.base.test.util.Feature;
import org.chromium.base.test.util.FlakyTest;
import org.chromium.content_public.browser.test.util.TestCallbackHelperContainer;
import org.chromium.content_public.common.ContentUrlConstants;
import org.chromium.net.test.util.TestWebServer;

import java.util.concurrent.CountDownLatch;

/**
 * Tests for the ContentViewClient.onPageFinished() method.
 */
@RunWith(AwJUnit4ClassRunner.class)
public class ClientOnPageFinishedTest {
    @Rule
    public AwActivityTestRule mActivityTestRule = new AwActivityTestRule();

    private TestAwContentsClient mContentsClient;
    private AwContents mAwContents;

    @Before
    public void setUp() throws Exception {
        setTestAwContentsClient(new TestAwContentsClient());
    }

    private void setTestAwContentsClient(TestAwContentsClient contentsClient) throws Exception {
        mContentsClient = contentsClient;
        final AwTestContainerView testContainerView =
                mActivityTestRule.createAwTestContainerViewOnMainSync(mContentsClient);
        mAwContents = testContainerView.getAwContents();
    }

    @Test
    @MediumTest
    @Feature({"AndroidWebView"})
    public void testPassesCorrectUrl() throws Throwable {
        TestCallbackHelperContainer.OnPageFinishedHelper onPageFinishedHelper =
                mContentsClient.getOnPageFinishedHelper();

        String html = "<html><body>Simple page.</body></html>";
        int currentCallCount = onPageFinishedHelper.getCallCount();
        mActivityTestRule.loadDataAsync(mAwContents, html, "text/html", false);

        onPageFinishedHelper.waitForCallback(currentCallCount);
        Assert.assertEquals("data:text/html," + html, onPageFinishedHelper.getUrl());
    }

    @Test
    @MediumTest
    @Feature({"AndroidWebView"})
    @FlakyTest(message = "crbug.com/652577")
    public void testCalledAfterError() throws Throwable {
        class LocalTestClient extends TestAwContentsClient {
            private boolean mIsOnReceivedErrorCalled;
            private boolean mIsOnPageFinishedCalled;
            private boolean mAllowAboutBlank;

            @Override
            public void onReceivedError(int errorCode, String description, String failingUrl) {
                Assert.assertEquals("onReceivedError called twice for " + failingUrl, false,
                        mIsOnReceivedErrorCalled);
                mIsOnReceivedErrorCalled = true;
                Assert.assertEquals(
                        "onPageFinished called before onReceivedError for " + failingUrl, false,
                        mIsOnPageFinishedCalled);
                super.onReceivedError(errorCode, description, failingUrl);
            }

            @Override
            public void onPageFinished(String url) {
                if (mAllowAboutBlank && ContentUrlConstants.ABOUT_BLANK_DISPLAY_URL.equals(url)) {
                    super.onPageFinished(url);
                    return;
                }
                Assert.assertEquals(
                        "onPageFinished called twice for " + url, false, mIsOnPageFinishedCalled);
                mIsOnPageFinishedCalled = true;
                Assert.assertEquals("onReceivedError not called before onPageFinished for " + url,
                        true, mIsOnReceivedErrorCalled);
                super.onPageFinished(url);
            }

            void setAllowAboutBlank() {
                mAllowAboutBlank = true;
            }
        }
        LocalTestClient testContentsClient = new LocalTestClient();
        setTestAwContentsClient(testContentsClient);

        TestCallbackHelperContainer.OnReceivedErrorHelper onReceivedErrorHelper =
                mContentsClient.getOnReceivedErrorHelper();
        TestCallbackHelperContainer.OnPageFinishedHelper onPageFinishedHelper =
                mContentsClient.getOnPageFinishedHelper();

        String invalidUrl = "http://localhost:7/non_existent";
        mActivityTestRule.loadUrlSync(mAwContents, onPageFinishedHelper, invalidUrl);

        Assert.assertEquals(invalidUrl, onReceivedErrorHelper.getFailingUrl());
        Assert.assertEquals(invalidUrl, onPageFinishedHelper.getUrl());

        // Rather than wait a fixed time to see that another onPageFinished callback isn't issued
        // we load a valid page. Since callbacks arrive sequentially, this will ensure that
        // any extra calls of onPageFinished / onReceivedError will arrive to our client.
        testContentsClient.setAllowAboutBlank();
        mActivityTestRule.loadUrlSync(
                mAwContents, onPageFinishedHelper, ContentUrlConstants.ABOUT_BLANK_DISPLAY_URL);
    }

    @Test
    @MediumTest
    @Feature({"AndroidWebView"})
    public void testCalledAfterRedirectedUrlIsOverridden() throws Throwable {
        /*
         * If url1 is redirected url2, and url2 load is overridden, onPageFinished should still be
         * called for url2.
         * Steps:
         * 1. load url1. url1 onPageStarted
         * 2. server redirects url1 to url2. url2 onPageStarted
         * 3. shouldOverridedUrlLoading called for url2 and returns true
         * 4. url2 onPageFinishedCalled
         */

        TestWebServer webServer = TestWebServer.start();
        try {
            final String redirectTargetPath = "/redirect_target.html";
            final String redirectTargetUrl = webServer.setResponse(redirectTargetPath,
                    "<html><body>hello world</body></html>", null);
            final String redirectUrl = webServer.setRedirect("/302.html", redirectTargetUrl);

            final TestAwContentsClient.ShouldOverrideUrlLoadingHelper urlOverrideHelper =
                    mContentsClient.getShouldOverrideUrlLoadingHelper();
            // Override the load of redirectTargetUrl
            urlOverrideHelper.setShouldOverrideUrlLoadingReturnValue(true);

            TestCallbackHelperContainer.OnPageFinishedHelper onPageFinishedHelper =
                    mContentsClient.getOnPageFinishedHelper();

            final int currentOnPageFinishedCallCount = onPageFinishedHelper.getCallCount();
            mActivityTestRule.loadUrlAsync(mAwContents, redirectUrl);

            onPageFinishedHelper.waitForCallback(currentOnPageFinishedCallCount);
            // onPageFinished needs to be called for redirectTargetUrl, but not for redirectUrl
            Assert.assertEquals(redirectTargetUrl, onPageFinishedHelper.getUrl());
        } finally {
            webServer.shutdown();
        }
    }

    @Test
    @MediumTest
    @Feature({"AndroidWebView"})
    public void testNotCalledForValidSubresources() throws Throwable {
        TestCallbackHelperContainer.OnPageFinishedHelper onPageFinishedHelper =
                mContentsClient.getOnPageFinishedHelper();

        TestWebServer webServer = TestWebServer.start();
        try {
            final String testHtml = "<html><head>Header</head><body>Body</body></html>";
            final String testPath = "/test.html";
            final String syncPath = "/sync.html";

            final String testUrl = webServer.setResponse(testPath, testHtml, null);
            final String syncUrl = webServer.setResponse(syncPath, testHtml, null);

            Assert.assertEquals(0, onPageFinishedHelper.getCallCount());
            final int pageWithSubresourcesCallCount = onPageFinishedHelper.getCallCount();
            mActivityTestRule.loadDataAsync(mAwContents,
                    "<html><iframe src=\"" + testUrl + "\" /></html>", "text/html", false);

            onPageFinishedHelper.waitForCallback(pageWithSubresourcesCallCount);

            // Rather than wait a fixed time to see that an onPageFinished callback isn't issued
            // we load another valid page. Since callbacks arrive sequentially if the next callback
            // we get is for the synchronizationUrl we know that the previous load did not schedule
            // a callback for the iframe.
            final int synchronizationPageCallCount = onPageFinishedHelper.getCallCount();
            mActivityTestRule.loadUrlAsync(mAwContents, syncUrl);

            onPageFinishedHelper.waitForCallback(synchronizationPageCallCount);
            Assert.assertEquals(syncUrl, onPageFinishedHelper.getUrl());
            Assert.assertEquals(2, onPageFinishedHelper.getCallCount());
        } finally {
            webServer.shutdown();
        }
    }

    @Test
    @MediumTest
    @Feature({"AndroidWebView"})
    public void testNotCalledForHistoryApi() throws Throwable {
        TestCallbackHelperContainer.OnPageFinishedHelper onPageFinishedHelper =
                mContentsClient.getOnPageFinishedHelper();
        AwActivityTestRule.enableJavaScriptOnUiThread(mAwContents);

        TestWebServer webServer = TestWebServer.start();
        try {
            final String testHtml = "<html><head>Header</head><body>Body</body></html>";
            final String testPath = "/test.html";
            final String historyPath = "/history.html";
            final String syncPath = "/sync.html";

            final String testUrl = webServer.setResponse(testPath, testHtml, null);
            final String historyUrl = webServer.getResponseUrl(historyPath);
            final String syncUrl = webServer.setResponse(syncPath, testHtml, null);

            Assert.assertEquals(0, onPageFinishedHelper.getCallCount());
            mActivityTestRule.loadUrlSync(mAwContents, onPageFinishedHelper, testUrl);

            mActivityTestRule.executeJavaScriptAndWaitForResult(mAwContents, mContentsClient,
                    "history.pushState(null, null, '" + historyUrl + "');");

            // Rather than wait a fixed time to see that an onPageFinished callback isn't issued
            // we load another valid page. Since callbacks arrive sequentially if the next callback
            // we get is for the synchronizationUrl we know that the previous load did not schedule
            // a callback for the iframe.
            final int synchronizationPageCallCount = onPageFinishedHelper.getCallCount();
            mActivityTestRule.loadUrlAsync(mAwContents, syncUrl);

            onPageFinishedHelper.waitForCallback(synchronizationPageCallCount);
            Assert.assertEquals(syncUrl, onPageFinishedHelper.getUrl());
            Assert.assertEquals(2, onPageFinishedHelper.getCallCount());
        } finally {
            webServer.shutdown();
        }
    }

    @Test
    @MediumTest
    @Feature({"AndroidWebView"})
    public void testCalledForHrefNavigations() throws Throwable {
        doTestOnPageFinishedCalledForHrefNavigations(false);
    }

    @Test
    @MediumTest
    @Feature({"AndroidWebView"})
    public void testCalledForHrefNavigationsWithBaseUrl() throws Throwable {
        doTestOnPageFinishedCalledForHrefNavigations(true);
    }

    private void doTestOnPageFinishedCalledForHrefNavigations(boolean useBaseUrl) throws Throwable {
        TestCallbackHelperContainer.OnPageFinishedHelper onPageFinishedHelper =
                mContentsClient.getOnPageFinishedHelper();
        TestCallbackHelperContainer.OnPageStartedHelper onPageStartedHelper =
                mContentsClient.getOnPageStartedHelper();
        AwActivityTestRule.enableJavaScriptOnUiThread(mAwContents);

        TestWebServer webServer = TestWebServer.start();
        try {
            final String testHtml = CommonResources.makeHtmlPageFrom("",
                    "<a href=\"#anchor\" id=\"link\">anchor</a>");
            final String testPath = "/test.html";
            final String testUrl = webServer.setResponse(testPath, testHtml, null);

            if (useBaseUrl) {
                mActivityTestRule.loadDataWithBaseUrlSync(mAwContents, onPageFinishedHelper,
                        testHtml, "text/html", false, webServer.getBaseUrl(), null);
            } else {
                mActivityTestRule.loadUrlSync(mAwContents, onPageFinishedHelper, testUrl);
            }

            int onPageFinishedCallCount = onPageFinishedHelper.getCallCount();
            int onPageStartedCallCount = onPageStartedHelper.getCallCount();

            JSUtils.clickOnLinkUsingJs(InstrumentationRegistry.getInstrumentation(), mAwContents,
                    mContentsClient.getOnEvaluateJavaScriptResultHelper(), "link");

            onPageFinishedHelper.waitForCallback(onPageFinishedCallCount);
            Assert.assertEquals(onPageStartedCallCount, onPageStartedHelper.getCallCount());

            onPageFinishedCallCount = onPageFinishedHelper.getCallCount();
            onPageStartedCallCount = onPageStartedHelper.getCallCount();

            mActivityTestRule.executeJavaScriptAndWaitForResult(
                    mAwContents, mContentsClient, "window.history.go(-1)");

            onPageFinishedHelper.waitForCallback(onPageFinishedCallCount);
            Assert.assertEquals(onPageStartedCallCount, onPageStartedHelper.getCallCount());
        } finally {
            webServer.shutdown();
        }
    }

    @Test
    @MediumTest
    @Feature({"AndroidWebView"})
    public void testNotCalledOnDomModificationForBlankWebView() throws Throwable {
        TestWebServer webServer = TestWebServer.start();
        try {
            doTestOnPageFinishedNotCalledOnDomMutation(webServer, null);
        } finally {
            webServer.shutdown();
        }
    }

    @Test
    @MediumTest
    @Feature({"AndroidWebView"})
    public void testNotCalledOnDomModificationAfterNonCommittedLoadFromApi() throws Throwable {
        AwActivityTestRule.enableJavaScriptOnUiThread(mAwContents);
        TestWebServer webServer = TestWebServer.start();
        try {
            final String noContentUrl = webServer.setResponseWithNoContentStatus("/nocontent.html");
            mActivityTestRule.loadUrlAsync(mAwContents, noContentUrl);
            doTestOnPageFinishedNotCalledOnDomMutation(webServer, noContentUrl);
        } finally {
            webServer.shutdown();
        }
    }

    @Test
    @MediumTest
    @Feature({"AndroidWebView"})
    public void testNotCalledOnDomModificationWithJavascriptUrlAfterNonCommittedLoadFromApi()
            throws Throwable {
        AwActivityTestRule.enableJavaScriptOnUiThread(mAwContents);
        TestWebServer webServer = TestWebServer.start();
        try {
            final CountDownLatch latch = new CountDownLatch(1);
            final String url = webServer.setResponseWithRunnableAction(
                    "/about.html", CommonResources.ABOUT_HTML, null,
                    () -> {
                        try {
                            Assert.assertTrue(latch.await(WAIT_TIMEOUT_MS,
                                    java.util.concurrent.TimeUnit.MILLISECONDS));
                        } catch (InterruptedException e) {
                            Assert.fail("Caught InterruptedException " + e);
                        }
                    });
            TestCallbackHelperContainer.OnPageFinishedHelper onPageFinishedHelper =
                    mContentsClient.getOnPageFinishedHelper();
            final int onPageFinishedCallCount = onPageFinishedHelper.getCallCount();
            mActivityTestRule.loadUrlAsync(mAwContents, url);
            mActivityTestRule.loadUrlAsync(mAwContents,
                    "javascript:(function(){document.body.innerHTML='Hello,%20World!';})()");
            mActivityTestRule.stopLoading(mAwContents);
            // We now have 3 possible outcomes:
            //  - the good one -- onPageFinished only fires for the first load;
            //  - two bad ones:
            //      - onPageFinished fires for the dom mutation, then for the first load. (1)
            //      - onPageFinished fires for the first load, then for the dom mutation; (2)
            // We verify that (1) doesn't happen with the code below. Then we load a sync page,
            // and make sure that we are getting onPageFinished for the sync page, not due
            // to the dom mutation, thus verifying that (2) doesn't happen as well.
            onPageFinishedHelper.waitForCallback(onPageFinishedCallCount);
            Assert.assertEquals(url, onPageFinishedHelper.getUrl());
            Assert.assertEquals(onPageFinishedCallCount + 1, onPageFinishedHelper.getCallCount());
            latch.countDown();  // Release the server.
            final String syncUrl = webServer.setResponse("/sync.html", "", null);
            mActivityTestRule.loadUrlAsync(mAwContents, syncUrl);
            onPageFinishedHelper.waitForCallback(onPageFinishedCallCount + 1);
            Assert.assertEquals(syncUrl, onPageFinishedHelper.getUrl());
            Assert.assertEquals(onPageFinishedCallCount + 2, onPageFinishedHelper.getCallCount());
        } finally {
            webServer.shutdown();
        }
    }

    @Test
    @MediumTest
    @Feature({"AndroidWebView"})
    public void testNotCalledOnDomModificationAfterLoadUrl() throws Throwable {
        TestWebServer webServer = TestWebServer.start();
        try {
            final String testUrl =
                    webServer.setResponse("/test.html", CommonResources.ABOUT_HTML, null);
            mActivityTestRule.loadUrlSync(
                    mAwContents, mContentsClient.getOnPageFinishedHelper(), testUrl);
            doTestOnPageFinishedNotCalledOnDomMutation(webServer, null);
        } finally {
            webServer.shutdown();
        }
    }

    @Test
    @MediumTest
    @Feature({"AndroidWebView"})
    public void testNotCalledOnDomModificationAfterLoadData() throws Throwable {
        TestWebServer webServer = TestWebServer.start();
        try {
            mActivityTestRule.loadDataSync(mAwContents, mContentsClient.getOnPageFinishedHelper(),
                    CommonResources.ABOUT_HTML, "text/html", false);
            doTestOnPageFinishedNotCalledOnDomMutation(webServer, null);
        } finally {
            webServer.shutdown();
        }
    }

    private void doTestOnPageFinishedNotCalledOnDomMutation(TestWebServer webServer, String syncUrl)
            throws Throwable {
        AwActivityTestRule.enableJavaScriptOnUiThread(mAwContents);
        TestCallbackHelperContainer.OnPageFinishedHelper onPageFinishedHelper =
                mContentsClient.getOnPageFinishedHelper();
        final int onPageFinishedCallCount = onPageFinishedHelper.getCallCount();
        // Mutate DOM.
        mActivityTestRule.executeJavaScriptAndWaitForResult(
                mAwContents, mContentsClient, "document.body.innerHTML='Hello, World!'");
        // Rather than wait a fixed time to see that an onPageFinished callback isn't issued
        // we load another valid page. Since callbacks arrive sequentially if the next callback
        // we get is for the synchronizationUrl we know that DOM mutation did not schedule
        // a callback for the iframe.
        if (syncUrl == null) {
            syncUrl = webServer.setResponse("/sync.html", "", null);
            mActivityTestRule.loadUrlAsync(mAwContents, syncUrl);
        }
        onPageFinishedHelper.waitForCallback(onPageFinishedCallCount);
        Assert.assertEquals(syncUrl, onPageFinishedHelper.getUrl());
        Assert.assertEquals(onPageFinishedCallCount + 1, onPageFinishedHelper.getCallCount());
    }

    @Test
    @MediumTest
    @Feature({"AndroidWebView"})
    public void testCalledAfter204Reply() throws Throwable {
        TestWebServer webServer = TestWebServer.start();
        try {
            final String url = webServer.setResponseWithNoContentStatus("/page.html");
            TestCallbackHelperContainer.OnPageFinishedHelper onPageFinishedHelper =
                    mContentsClient.getOnPageFinishedHelper();
            int currentCallCount = onPageFinishedHelper.getCallCount();
            mActivityTestRule.loadUrlAsync(mAwContents, url);
            onPageFinishedHelper.waitForCallback(currentCallCount);
            Assert.assertEquals(url, onPageFinishedHelper.getUrl());
        } finally {
            webServer.shutdown();
        }
    }

    /**
     * Ensure onPageFinished is called for an empty response (if the response status isn't
     * HttpStatus.SC_NO_CONTENT).
     */
    @Test
    @MediumTest
    @Feature({"AndroidWebView"})
    public void testCalledOnEmptyResponse() throws Throwable {
        TestWebServer webServer = TestWebServer.start();
        try {
            final String url = webServer.setEmptyResponse("/page.html");
            TestCallbackHelperContainer.OnPageFinishedHelper onPageFinishedHelper =
                    mContentsClient.getOnPageFinishedHelper();
            int currentCallCount = onPageFinishedHelper.getCallCount();
            mActivityTestRule.loadUrlAsync(mAwContents, url);
            onPageFinishedHelper.waitForCallback(currentCallCount);
            Assert.assertEquals(url, onPageFinishedHelper.getUrl());
        } finally {
            webServer.shutdown();
        }
    }

    /**
     * Ensure onPageFinished is called when a provisional load is cancelled.
     */
    @Test
    @MediumTest
    @Feature({"AndroidWebView"})
    public void testCalledOnCancelingProvisionalLoad() throws Throwable {
        TestWebServer webServer = TestWebServer.start();
        final CountDownLatch firstUrlLatch = new CountDownLatch(1);
        try {
            final String url = webServer.setResponseWithRunnableAction(
                    "/slow_page.html", "", null /* headers */, () -> {
                        try {
                            // Delay the server response so that we guarantee stopLoading() comes
                            // before the server response.
                            Assert.assertTrue(firstUrlLatch.await(
                                    WAIT_TIMEOUT_MS, java.util.concurrent.TimeUnit.MILLISECONDS));
                        } catch (InterruptedException e) {
                            Assert.fail("Caught InterruptedException " + e);
                        }
                    });
            TestCallbackHelperContainer.OnPageFinishedHelper onPageFinishedHelper =
                    mContentsClient.getOnPageFinishedHelper();
            int initialCallCount = onPageFinishedHelper.getCallCount();
            mActivityTestRule.loadUrlAsync(mAwContents, url);

            // Cancel before getting a response from the server.
            mActivityTestRule.stopLoading(mAwContents);

            onPageFinishedHelper.waitForCallback(initialCallCount);
            Assert.assertEquals(url, onPageFinishedHelper.getUrl());
            firstUrlLatch.countDown();

            // Load another page to ensure onPageFinished isn't called several times.
            final String syncUrl = webServer.setResponse("/sync.html", "", null /* headers */);
            mActivityTestRule.loadUrlSync(mAwContents, onPageFinishedHelper, syncUrl);
            Assert.assertEquals(syncUrl, onPageFinishedHelper.getUrl());
            final int finalCallCount = onPageFinishedHelper.getCallCount();
            Assert.assertEquals(
                    "onPageFinished should be called twice", initialCallCount + 2, finalCallCount);
        } finally {
            webServer.shutdown();
        }
    }

    /**
     * Ensure onPageFinished is called when a committed load is cancelled.
     */
    @Test
    @MediumTest
    @Feature({"AndroidWebView"})
    public void testCalledOnCancelingCommittedLoad() throws Throwable {
        TestCallbackHelperContainer.OnPageFinishedHelper onPageFinishedHelper =
                mContentsClient.getOnPageFinishedHelper();

        TestWebServer webServer = TestWebServer.start();
        final CountDownLatch serverImageUrlLatch = new CountDownLatch(1);
        final CountDownLatch testDoneLatch = new CountDownLatch(1);
        try {
            final String stallingImageUrl = webServer.setResponseWithRunnableAction(
                    "/stallingImage.html", "", null /* headers */, () -> {
                        serverImageUrlLatch.countDown();
                        try {
                            Assert.assertTrue(testDoneLatch.await(WAIT_TIMEOUT_MS,
                                    java.util.concurrent.TimeUnit.MILLISECONDS));
                        } catch (InterruptedException e) {
                            Assert.fail("Caught InterruptedException " + e);
                        }
                    });

            final String mainPageHtml =
                    CommonResources.makeHtmlPageFrom("", "<img src=" + stallingImageUrl + ">");
            final String mainPageUrl = webServer.setResponse("/mainPage.html", mainPageHtml, null);

            Assert.assertEquals(0, onPageFinishedHelper.getCallCount());
            mActivityTestRule.loadUrlAsync(mAwContents, mainPageUrl);

            Assert.assertTrue(serverImageUrlLatch.await(
                    WAIT_TIMEOUT_MS, java.util.concurrent.TimeUnit.MILLISECONDS));
            Assert.assertEquals(0, onPageFinishedHelper.getCallCount());
            // Our load isn't done since we haven't loaded the image - now cancel the load.
            mActivityTestRule.stopLoading(mAwContents);
            onPageFinishedHelper.waitForCallback(0);
            Assert.assertEquals(1, onPageFinishedHelper.getCallCount());
        } finally {
            testDoneLatch.countDown();
            webServer.shutdown();
        }
    }
}
