// Copyright 2018 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.fullscreen;

import android.os.SystemClock;

import org.junit.Assert;

import org.chromium.base.ThreadUtils;
import org.chromium.base.test.util.CallbackHelper;
import org.chromium.chrome.browser.fullscreen.ChromeFullscreenManager.FullscreenListener;
import org.chromium.chrome.browser.tab.Tab;
import org.chromium.chrome.test.ChromeTabbedActivityTestRule;
import org.chromium.content_public.browser.GestureListenerManager;
import org.chromium.content_public.browser.GestureStateListener;
import org.chromium.content_public.browser.RenderCoordinates;
import org.chromium.content_public.browser.WebContents;
import org.chromium.content_public.browser.test.util.Criteria;
import org.chromium.content_public.browser.test.util.CriteriaHelper;
import org.chromium.content_public.browser.test.util.TouchCommon;
import org.chromium.content_public.browser.test.util.WebContentsUtils;

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

/**
 * Utility methods for testing the {@link ChromeFullscreenManager}.
 */
public class FullscreenManagerTestUtils {
    /**
     * Scrolls the underlying web page to show or hide the browser controls.
     * @param testRule The test rule for the currently running test.
     * @param show Whether the browser controls should be shown.
     */
    public static void scrollBrowserControls(ChromeTabbedActivityTestRule testRule, boolean show) {
        ChromeFullscreenManager fullscreenManager = testRule.getActivity().getFullscreenManager();
        int browserControlsHeight = fullscreenManager.getTopControlsHeight();

        waitForPageToBeScrollable(testRule.getActivity().getActivityTab());

        float dragX = 50f;
        // Use a larger scroll range than the height of the browser controls to ensure we overcome
        // the delay in a scroll start being sent.
        float dragStartY = browserControlsHeight * 3;
        float dragEndY = dragStartY - browserControlsHeight * 2;
        int expectedPosition = -browserControlsHeight;
        if (show) {
            expectedPosition = 0;
            float tempDragStartY = dragStartY;
            dragStartY = dragEndY;
            dragEndY = tempDragStartY;
        }
        long downTime = SystemClock.uptimeMillis();
        TouchCommon.dragStart(testRule.getActivity(), dragX, dragStartY, downTime);
        TouchCommon.dragTo(
                testRule.getActivity(), dragX, dragX, dragStartY, dragEndY, 100, downTime);
        TouchCommon.dragEnd(testRule.getActivity(), dragX, dragEndY, downTime);
        waitForBrowserControlsPosition(testRule, expectedPosition);
    }

    /**
     * Waits for the browser controls to reach the specified position.
     * @param testRule The test rule for the currently running test.
     * @param position The desired top controls offset.
     */
    public static void waitForBrowserControlsPosition(
            ChromeTabbedActivityTestRule testRule, int position) {
        final ChromeFullscreenManager fullscreenManager =
                testRule.getActivity().getFullscreenManager();
        CriteriaHelper.pollUiThread(Criteria.equals(position, new Callable<Integer>() {
            @Override
            public Integer call() {
                return fullscreenManager.getTopControlOffset();
            }
        }));
    }

    /**
     * Waits for the base page to be scrollable.
     * @param tab The current activity tab.
     */
    public static void waitForPageToBeScrollable(final Tab tab) {
        CriteriaHelper.pollUiThread(new Criteria() {
            @Override
            public boolean isSatisfied() {
                return RenderCoordinates.fromWebContents(tab.getWebContents())
                               .getContentHeightPixInt()
                        > tab.getContentView().getHeight();
            }
        });
    }

    /**
     * Waits for the browser controls to be moveable by user gesture.
     *
     * This function requires the browser controls to start fully visible. Then it ensures that
     * at some point the controls can be moved by user gesture.  It will then fully cycle the top
     * controls to entirely hidden and back to fully shown.
     *
     * @param testRule The test rule for the currently running test.
     * @param tab The current activity tab.
     */
    public static void waitForBrowserControlsToBeMoveable(
            ChromeTabbedActivityTestRule testRule, final Tab tab) throws InterruptedException {
        waitForBrowserControlsPosition(testRule, 0);

        final CallbackHelper contentMovedCallback = new CallbackHelper();
        final ChromeFullscreenManager fullscreenManager =
                testRule.getActivity().getFullscreenManager();
        final float initialVisibleContentOffset = fullscreenManager.getTopVisibleContentOffset();

        fullscreenManager.addListener(new FullscreenListener() {
            @Override
            public void onControlsOffsetChanged(
                    int topOffset, int bottomOffset, boolean needsAnimate) {
                if (fullscreenManager.getTopVisibleContentOffset() != initialVisibleContentOffset) {
                    contentMovedCallback.notifyCalled();
                    fullscreenManager.removeListener(this);
                }
            }

            @Override
            public void onToggleOverlayVideoMode(boolean enabled) {}

            @Override
            public void onContentOffsetChanged(int offset) {}

            @Override
            public void onBottomControlsHeightChanged(int bottomControlsHeight) {}
        });

        float dragX = 50f;
        float dragStartY = tab.getView().getHeight() - 50f;

        WebContents webContents = tab.getWebContents();

        final CallbackHelper scrollEndCallback = new CallbackHelper();
        final CallbackHelper flingEndCallback = new CallbackHelper();
        GestureStateListener scrollEndListener = new GestureStateListener() {
            @Override
            public void onScrollEnded(int scrollOffsetY, int scrollExtentY) {
                scrollEndCallback.notifyCalled();
            }

            @Override
            public void onFlingEndGesture(int scrollOffsetY, int scrollExtentY) {
                flingEndCallback.notifyCalled();
            }

        };
        GestureListenerManager gestureListenerManager =
                WebContentsUtils.getGestureListenerManager(webContents);
        gestureListenerManager.addListener(scrollEndListener);

        for (int i = 0; i < 10; i++) {
            int numScrollEndCalled = scrollEndCallback.getCallCount();
            int numFlingEndCalled = flingEndCallback.getCallCount();
            float dragEndY = dragStartY - fullscreenManager.getTopControlsHeight();

            long downTime = SystemClock.uptimeMillis();
            TouchCommon.dragStart(testRule.getActivity(), dragX, dragStartY, downTime);
            TouchCommon.dragTo(
                    testRule.getActivity(), dragX, dragX, dragStartY, dragEndY, 100, downTime);
            TouchCommon.dragEnd(testRule.getActivity(), dragX, dragEndY, downTime);

            try {
                contentMovedCallback.waitForCallback(0, 1, 500, TimeUnit.MILLISECONDS);

                try {
                    scrollEndCallback.waitForCallback(
                            numScrollEndCalled, 1, 5000, TimeUnit.MILLISECONDS);
                    flingEndCallback.waitForCallback(
                            numFlingEndCalled, 1, 5000, TimeUnit.MILLISECONDS);
                } catch (TimeoutException e) {
                    Assert.fail("Didn't get expected ScrollEnd gestures");
                }

                try {
                    flingEndCallback.waitForCallback(
                            numFlingEndCalled, 1, 200, TimeUnit.MILLISECONDS);
                } catch (TimeoutException e) {
                    // Depending on timing - the above scroll may not have
                    // generated a fling. If it did, it the fling end may
                    // sometimes be called after the scroll end so wait a little
                    // for it.
                }

                numFlingEndCalled = flingEndCallback.getCallCount();

                scrollBrowserControls(testRule, false);
                scrollBrowserControls(testRule, true);

                // Make sure the gesture stream is finished before we hand back control.
                try {
                    scrollEndCallback.waitForCallback(
                            numScrollEndCalled + 1, 2, 5000, TimeUnit.MILLISECONDS);
                } catch (TimeoutException e) {
                    Assert.fail("Didn't get expected ScrollEnd gestures");
                }

                try {
                    flingEndCallback.waitForCallback(
                            numFlingEndCalled, 2, 200, TimeUnit.MILLISECONDS);
                } catch (TimeoutException e) {
                    // Depending on timing - the above scrolls may not have
                    // generated flings. If they did, the fling end may sometimes
                    // be called after the scroll end so wait a little for it.
                }

                gestureListenerManager.removeListener(scrollEndListener);

                return;
            } catch (TimeoutException e) {
                // Ignore and retry
            }
        }

        Assert.fail("Visible content never moved as expected.");
    }

    /**
     * Disable any browser visibility overrides for testing.
     */
    public static void disableBrowserOverrides() {
        ThreadUtils.runOnUiThreadBlocking(new Runnable() {
            @Override
            public void run() {
                BrowserStateBrowserControlsVisibilityDelegate.disableForTesting();
            }
        });
    }

    public static void fling(ChromeTabbedActivityTestRule testRule, final int vx, final int vy) {
        try {
            ThreadUtils.runOnUiThread(new Callable<Boolean>() {
                @Override
                public Boolean call() {
                    testRule.getWebContents().getEventForwarder().startFling(
                            SystemClock.uptimeMillis(), vx, vy, /*synthetic_scroll*/ false,
                            /*prevent_boosting*/ false);
                    return true;
                }
            });
        } catch (Throwable e) {
            Assert.fail("Failed to fling");
        }
    }
}
