// Copyright (c) 2013 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.test;

import android.app.AlertDialog;
import android.content.DialogInterface;
import android.test.suitebuilder.annotation.MediumTest;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText;

import org.chromium.base.ThreadUtils;
import org.chromium.base.test.util.DisabledTest;
import org.chromium.base.test.util.Feature;
import org.chromium.base.test.util.UrlUtils;
import org.chromium.chrome.browser.JavascriptAppModalDialog;
import org.chromium.chrome.testshell.ChromiumTestShellTestBase;
import org.chromium.chrome.testshell.TabShellTabUtils;
import org.chromium.chrome.testshell.TabShellTabUtils.TestCallbackHelperContainerForTab;
import org.chromium.content.browser.test.util.Criteria;
import org.chromium.content.browser.test.util.CriteriaHelper;
import org.chromium.content.browser.test.util.TestCallbackHelperContainer;
import org.chromium.content.browser.test.util.TestCallbackHelperContainer.OnEvaluateJavaScriptResultHelper;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeoutException;

/**
 * Test suite for displaying and functioning of modal dialogs.
 */
public class ModalDialogTest extends ChromiumTestShellTestBase {
    private final static String TAG = "ModalDialogTest";
    private final static String EMPTY_PAGE = UrlUtils.encodeHtmlDataUri(
            "<html><title>Modal Dialog Test</title><p>Testcase.</p></title></html>");
    private final static String BEFORE_UNLOAD_URL = UrlUtils.encodeHtmlDataUri(
            "<html>" +
            "<head><script>window.onbeforeunload=function() {" +
            "return 'Are you sure?';" +
            "};</script></head></html>");

    @Override
    public void setUp() throws Exception {
        super.setUp();
        launchChromiumTestShellWithUrl(EMPTY_PAGE);
        assertTrue("Page failed to load", waitForActiveShellToBeDoneLoading());
    }

    /**
     * Verifies modal alert-dialog appearance and that JavaScript execution is
     * able to continue after dismissal.
     */
    @MediumTest
    @Feature({"Browser", "Main"})
    public void testAlertModalDialog()
            throws InterruptedException, TimeoutException, ExecutionException {
        final OnEvaluateJavaScriptResultHelper scriptEvent =
                executeJavaScriptAndWaitForDialog("alert('Hello Android!');");

        JavascriptAppModalDialog jsDialog = getCurrentDialog();
        assertNotNull("No dialog showing.", jsDialog);

        clickOk(jsDialog);
        assertTrue("JavaScript execution should continue after closing prompt.",
                scriptEvent.waitUntilHasValue());
    }

    /**
     * Verifies that clicking on a button twice doesn't crash.
     */
    @MediumTest
    @Feature({"Browser", "Main"})
    public void testAlertModalDialogWithTwoClicks()
            throws InterruptedException, TimeoutException, ExecutionException {
        OnEvaluateJavaScriptResultHelper scriptEvent =
                executeJavaScriptAndWaitForDialog("alert('Hello Android');");
        JavascriptAppModalDialog jsDialog = getCurrentDialog();
        assertNotNull("No dialog showing.", jsDialog);

        clickOk(jsDialog);
        clickOk(jsDialog);

        assertTrue("JavaScript execution should continue after closing prompt.",
                scriptEvent.waitUntilHasValue());
    }

    /**
     * Verifies that modal confirm-dialogs display, two buttons are visible and
     * the return value of [Ok] equals true, [Cancel] equals false.
     */
    @MediumTest
    @Feature({"Browser", "Main"})
    public void testConfirmModalDialog()
            throws InterruptedException, TimeoutException, ExecutionException {
        OnEvaluateJavaScriptResultHelper scriptEvent =
                executeJavaScriptAndWaitForDialog("confirm('Android');");

        JavascriptAppModalDialog jsDialog = getCurrentDialog();
        assertNotNull("No dialog showing.", jsDialog);

        Button[] buttons = getAlertDialogButtons(jsDialog.getDialogForTest());
        assertNotNull("No cancel button in confirm dialog.", buttons[0]);
        assertEquals("Cancel button is not visible.", View.VISIBLE, buttons[0].getVisibility());
        if (buttons[1] != null) {
            assertNotSame("Neutral button visible when it should not.",
                    View.VISIBLE, buttons[1].getVisibility());
        }
        assertNotNull("No OK button in confirm dialog.", buttons[2]);
        assertEquals("OK button is not visible.", View.VISIBLE, buttons[2].getVisibility());

        clickOk(jsDialog);
        assertTrue("JavaScript execution should continue after closing dialog.",
                scriptEvent.waitUntilHasValue());

        String resultString = scriptEvent.getJsonResultAndClear();
        assertEquals("Invalid return value.", "true", resultString);

        // Try again, pressing cancel this time.
        scriptEvent = executeJavaScriptAndWaitForDialog("confirm('Android');");
        jsDialog = getCurrentDialog();
        assertNotNull("No dialog showing.", jsDialog);

        clickCancel(jsDialog);
        assertTrue("JavaScript execution should continue after closing dialog.",
                scriptEvent.waitUntilHasValue());

        resultString = scriptEvent.getJsonResultAndClear();
        assertEquals("Invalid return value.", "false", resultString);
    }

    /**
     * Verifies that modal prompt-dialogs display and the result is returned.
     */
    @MediumTest
    @Feature({"Browser", "Main"})
    public void testPromptModalDialog()
            throws InterruptedException, TimeoutException, ExecutionException {
        final String promptText = "Hello Android!";
        final OnEvaluateJavaScriptResultHelper scriptEvent =
                executeJavaScriptAndWaitForDialog("prompt('Android', 'default');");

        final JavascriptAppModalDialog jsDialog = getCurrentDialog();
        assertNotNull("No dialog showing.", jsDialog);

        // Set the text in the prompt field of the dialog.
        boolean result = ThreadUtils.runOnUiThreadBlocking(new Callable<Boolean>() {
            @Override
            public Boolean call() {
                EditText prompt = (EditText) jsDialog.getDialogForTest().findViewById(
                        org.chromium.chrome.R.id.js_modal_dialog_prompt);
                if (prompt == null) return false;
                prompt.setText(promptText);
                return true;
            }
        });
        assertTrue("Failed to find prompt view in prompt dialog.", result);

        clickOk(jsDialog);
        assertTrue("JavaScript execution should continue after closing prompt.",
                scriptEvent.waitUntilHasValue());

        String resultString = scriptEvent.getJsonResultAndClear();
        assertEquals("Invalid return value.", '"' + promptText + '"', resultString);
    }

    /**
     * Verifies beforeunload dialogs are shown and they block/allow navigation
     * as appropriate.
     */
    //@MediumTest
    //@Feature({"Browser", "Main"})
    @DisabledTest //crbug/270593
    public void testBeforeUnloadDialog()
            throws InterruptedException, TimeoutException, ExecutionException {
        loadUrlWithSanitization(BEFORE_UNLOAD_URL);
        executeJavaScriptAndWaitForDialog("history.back();");

        JavascriptAppModalDialog jsDialog = getCurrentDialog();
        assertNotNull("No dialog showing.", jsDialog);
        checkButtonPresenceVisibilityText(
                jsDialog, 0, org.chromium.chrome.R.string.stay_on_this_page,
                "Stay on this page");
        clickCancel(jsDialog);

        assertEquals(BEFORE_UNLOAD_URL, getActivity().getActiveContentView().getUrl());
        executeJavaScriptAndWaitForDialog("history.back();");

        jsDialog = getCurrentDialog();
        assertNotNull("No dialog showing.", jsDialog);
        checkButtonPresenceVisibilityText(
                jsDialog, 2, org.chromium.chrome.R.string.leave_this_page,
                "Leave this page");

        final TestCallbackHelperContainer.OnPageFinishedHelper onPageLoaded =
                getActiveTabTestCallbackHelperContainer().getOnPageFinishedHelper();
        int callCount = onPageLoaded.getCallCount();
        clickOk(jsDialog);
        onPageLoaded.waitForCallback(callCount);
        assertEquals(EMPTY_PAGE, getActivity().getActiveContentView().getUrl());
    }

    /**
     * Verifies that when showing a beforeunload dialogs as a result of a page
     * reload, the correct UI strings are used.
     */
    @MediumTest
    @Feature({"Browser", "Main"})
    public void testBeforeUnloadOnReloadDialog()
            throws InterruptedException, TimeoutException, ExecutionException {
        loadUrlWithSanitization(BEFORE_UNLOAD_URL);
        executeJavaScriptAndWaitForDialog("window.location.reload();");

        JavascriptAppModalDialog jsDialog = getCurrentDialog();
        assertNotNull("No dialog showing.", jsDialog);

        checkButtonPresenceVisibilityText(
                jsDialog, 0, org.chromium.chrome.R.string.dont_reload_this_page,
                "Don't reload this page");
        checkButtonPresenceVisibilityText(
                jsDialog, 2, org.chromium.chrome.R.string.reload_this_page,
                "Reload this page");
    }

    /**
     * Verifies that repeated dialogs give the option to disable dialogs
     * altogether and then that disabling them works.
     */
    @MediumTest
    @Feature({"Browser", "Main"})
    public void testDisableRepeatedDialogs()
            throws InterruptedException, TimeoutException, ExecutionException {
        OnEvaluateJavaScriptResultHelper scriptEvent =
                executeJavaScriptAndWaitForDialog("alert('Android');");

        // Show a dialog once.
        JavascriptAppModalDialog jsDialog = getCurrentDialog();
        assertNotNull("No dialog showing.", jsDialog);

        clickCancel(jsDialog);
        scriptEvent.waitUntilHasValue();

        // Show it again, it should have the option to suppress subsequent dialogs.
        scriptEvent = executeJavaScriptAndWaitForDialog("alert('Android');");
        jsDialog = getCurrentDialog();
        assertNotNull("No dialog showing.", jsDialog);
        final AlertDialog dialog = jsDialog.getDialogForTest();
        String errorMessage = ThreadUtils.runOnUiThreadBlocking(new Callable<String>() {
            @Override
            public String call() {
                final CheckBox suppress = (CheckBox) dialog.findViewById(
                        org.chromium.chrome.R.id.suppress_js_modal_dialogs);
                if (suppress == null) return "Suppress checkbox not found.";
                if (suppress.getVisibility() != View.VISIBLE) {
                    return "Suppress checkbox is not visible.";
                }
                suppress.setChecked(true);
                return null;
            }
        });
        assertNull(errorMessage, errorMessage);
        clickCancel(jsDialog);
        scriptEvent.waitUntilHasValue();

        scriptEvent.evaluateJavaScript(getActivity().getActiveContentView().getContentViewCore(),
                "alert('Android');");
        assertTrue("No further dialog boxes should be shown.", scriptEvent.waitUntilHasValue());
    }

    /**
     * Displays a dialog and closes the tab in the background before attempting
     * to accept the dialog. Verifies that the dialog is dismissed when the tab
     * is closed.
     */
    @MediumTest
    @Feature({"Browser", "Main"})
    public void testDialogDismissedAfterClosingTab()
            throws InterruptedException, TimeoutException, ExecutionException {
        executeJavaScriptAndWaitForDialog("alert('Android')");

        final TestCallbackHelperContainerForTab.OnCloseTabHelper onTabClosed =
                getActiveTabTestCallbackHelperContainer().getOnCloseTabHelper();
        int callCount = onTabClosed.getCallCount();
        ThreadUtils.runOnUiThreadBlocking(new Runnable() {
            @Override
            public void run() {
                getActivity().createTab(EMPTY_PAGE);
            }
        });
        onTabClosed.waitForCallback(callCount);

        // Closing the tab should have dismissed the dialog.
        boolean criteriaSatisfied = CriteriaHelper.pollForCriteria(
                new JavascriptAppModalDialogShownCriteria(false));
        assertTrue("The dialog should have been dismissed when its tab was closed.",
                criteriaSatisfied);
    }

    /**
     * Asynchronously executes the given code for spawning a dialog and waits
     * for the dialog to be visible.
     */
    private OnEvaluateJavaScriptResultHelper executeJavaScriptAndWaitForDialog(String script)
            throws InterruptedException {
        final OnEvaluateJavaScriptResultHelper helper =
                getActiveTabTestCallbackHelperContainer().getOnEvaluateJavaScriptResultHelper();
        return executeJavaScriptAndWaitForDialog(helper, script);
    }

    /**
     * Given a JavaScript evaluation helper, asynchronously executes the given
     * code for spawning a dialog and waits for the dialog to be visible.
     */
    private OnEvaluateJavaScriptResultHelper executeJavaScriptAndWaitForDialog(
            final OnEvaluateJavaScriptResultHelper helper, String script)
            throws InterruptedException {
        helper.evaluateJavaScript(getActivity().getActiveContentView().getContentViewCore(),
                script);
        boolean criteriaSatisfied = CriteriaHelper.pollForCriteria(
                new JavascriptAppModalDialogShownCriteria(true));
        assertTrue("Could not spawn or locate a modal dialog.", criteriaSatisfied);
        return helper;
    }

    /**
     * Returns an array of the 3 buttons for this dialog, in the order
     * BUTTON_NEGATIVE, BUTTON_NEUTRAL and BUTTON_POSITIVE. Any of these values
     * can be null.
     */
    private Button[] getAlertDialogButtons(final AlertDialog dialog) throws ExecutionException {
        return ThreadUtils.runOnUiThreadBlocking(new Callable<Button[]>() {
            @Override
            public Button[] call() {
                final Button[] buttons = new Button[3];
                buttons[0] = dialog.getButton(DialogInterface.BUTTON_NEGATIVE);
                buttons[1] = dialog.getButton(DialogInterface.BUTTON_NEUTRAL);
                buttons[2] = dialog.getButton(DialogInterface.BUTTON_POSITIVE);
                return buttons;
            }
        });
    }

    /**
     * Returns the current JavaScript modal dialog showing or null if no such dialog is currently
     * showing.
     */
    private JavascriptAppModalDialog getCurrentDialog() throws ExecutionException {
        return ThreadUtils.runOnUiThreadBlocking(new Callable<JavascriptAppModalDialog>() {
            @Override
            public JavascriptAppModalDialog call() {
                return JavascriptAppModalDialog.getCurrentDialogForTest();
            }
        });
    }

    private static class JavascriptAppModalDialogShownCriteria implements Criteria {
        private final boolean mShouldBeShown;

        public JavascriptAppModalDialogShownCriteria(boolean shouldBeShown) {
            mShouldBeShown = shouldBeShown;
        }

        @Override
        public boolean isSatisfied() {
            try {
                return ThreadUtils.runOnUiThreadBlocking(new Callable<Boolean>() {
                    @Override
                    public Boolean call() {
                        final boolean isShown =
                                JavascriptAppModalDialog.getCurrentDialogForTest() != null;
                        return mShouldBeShown == isShown;
                    }
                });
            } catch (ExecutionException e) {
                Log.e(TAG, "Failed to getCurrentDialog", e);
                return false;
            }
        }
    }

    /**
     * Simulates pressing the OK button of the passed dialog.
     */
    private void clickOk(JavascriptAppModalDialog dialog) {
        clickButton(dialog, DialogInterface.BUTTON_POSITIVE);
    }

    /**
     * Simulates pressing the Cancel button of the passed dialog.
     */
    private void clickCancel(JavascriptAppModalDialog dialog) {
        clickButton(dialog, DialogInterface.BUTTON_NEGATIVE);
    }

    private void clickButton(final JavascriptAppModalDialog dialog, final int whichButton) {
        ThreadUtils.runOnUiThreadBlocking(new Runnable() {
            @Override
            public void run() {
                dialog.onClick(null, whichButton);
            }
        });
    }

    private void checkButtonPresenceVisibilityText(
            JavascriptAppModalDialog jsDialog, int buttonIndex,
            int expectedTextResourceId, String readableName) throws ExecutionException {
        final Button[] buttons = getAlertDialogButtons(jsDialog.getDialogForTest());
        final Button button = buttons[buttonIndex];
        assertNotNull("No '" + readableName + "' button in confirm dialog.", button);
        assertEquals("'" + readableName + "' button is not visible.",
                View.VISIBLE,
                button.getVisibility());
        assertEquals("'" + readableName + "' button has wrong text",
                getActivity().getResources().getString(expectedTextResourceId),
                button.getText().toString());
    }

    private TestCallbackHelperContainerForTab getActiveTabTestCallbackHelperContainer() {
        return TabShellTabUtils.getTestCallbackHelperContainer(getActivity().getActiveTab());
    }
}
