// Copyright 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.content.browser.input;

import android.graphics.Point;
import android.graphics.Rect;
import android.os.SystemClock;
import android.test.FlakyTest;
import android.test.suitebuilder.annotation.MediumTest;
import android.text.Editable;
import android.text.Selection;
import android.view.MotionEvent;
import android.view.ViewGroup;

import org.chromium.base.ThreadUtils;
import org.chromium.base.test.util.Feature;
import org.chromium.base.test.util.UrlUtils;
import org.chromium.content.browser.RenderCoordinates;
import org.chromium.content.browser.test.util.Criteria;
import org.chromium.content.browser.test.util.CriteriaHelper;
import org.chromium.content.browser.test.util.DOMUtils;
import org.chromium.content.browser.test.util.TestInputMethodManagerWrapper;
import org.chromium.content.browser.test.util.TestTouchUtils;
import org.chromium.content.browser.test.util.TouchCommon;
import org.chromium.content_shell_apk.ContentShellTestBase;

import java.util.concurrent.Callable;

public class SelectionHandleTest extends ContentShellTestBase {
    private static final String META_DISABLE_ZOOM =
        "<meta name=\"viewport\" content=\"" +
        "height=device-height," +
        "width=device-width," +
        "initial-scale=1.0," +
        "minimum-scale=1.0," +
        "maximum-scale=1.0," +
        "\" />";

    // For these we use a tiny font-size so that we can be more strict on the expected handle
    // positions.
    private static final String TEXTAREA_ID = "textarea";
    private static final String TEXTAREA_DATA_URL = UrlUtils.encodeHtmlDataUri(
            "<html><head>" + META_DISABLE_ZOOM + "</head><body>" +
            "<textarea id=\"" + TEXTAREA_ID +
            "\" cols=\"40\" rows=\"20\" style=\"font-size:6px\">" +
            "L r m i s m d l r s t a e , c n e t t r a i i i i g e i , s d d e u m d t m o " +
            "i c d d n u l b r e d l r m g a l q a U e i a m n m e i m q i n s r d " +
            "e e c t t o u l m o a o i n s u a i u p x a o m d c n e u t D i a t " +
            "i u e o o i r p e e d r t n o u t t v l t s e i l m o o e u u i t u l " +
            "p r a u . x e t u s n o c e a c p d t t o p o d n , u t n u p q i " +
            "o f c a e e u t o l t n m d s l b r m." +
            "L r m i s m d l r s t a e , c n e t t r a i i i i g e i , s d d e u m d t m o " +
            "i c d d n u l b r e d l r m g a l q a U e i a m n m e i m q i n s r d " +
            "e e c t t o u l m o a o i n s u a i u p x a o m d c n e u t D i a t " +
            "i u e o o i r p e e d r t n o u t t v l t s e i l m o o e u u i t u l " +
            "p r a u . x e t u s n o c e a c p d t t o p o d n , u t n u p q i " +
            "o f c a e e u t o l t n m d s l b r m." +
            "</textarea>" +
            "</body></html>");

    private static final String NONEDITABLE_DIV_ID = "noneditable";
    private static final String NONEDITABLE_DATA_URL = UrlUtils.encodeHtmlDataUri(
            "<html><head>" + META_DISABLE_ZOOM + "</head><body>" +
            "<div id=\"" + NONEDITABLE_DIV_ID + "\" style=\"width:200; font-size:6px\">" +
            "L r m i s m d l r s t a e , c n e t t r a i i i i g e i , s d d e u m d t m o " +
            "i c d d n u l b r e d l r m g a l q a U e i a m n m e i m q i n s r d " +
            "e e c t t o u l m o a o i n s u a i u p x a o m d c n e u t D i a t " +
            "i u e o o i r p e e d r t n o u t t v l t s e i l m o o e u u i t u l " +
            "p r a u . x e t u s n o c e a c p d t t o p o d n , u t n u p q i " +
            "o f c a e e u t o l t n m d s l b r m." +
            "L r m i s m d l r s t a e , c n e t t r a i i i i g e i , s d d e u m d t m o " +
            "i c d d n u l b r e d l r m g a l q a U e i a m n m e i m q i n s r d " +
            "e e c t t o u l m o a o i n s u a i u p x a o m d c n e u t D i a t " +
            "i u e o o i r p e e d r t n o u t t v l t s e i l m o o e u u i t u l " +
            "p r a u . x e t u s n o c e a c p d t t o p o d n , u t n u p q i " +
            "o f c a e e u t o l t n m d s l b r m." +
            "</div>" +
            "</body></html>");

    // TODO(cjhopman): These tolerances should be based on the actual width/height of a
    // character/line.
    private static final int HANDLE_POSITION_X_TOLERANCE_PIX = 20;
    private static final int HANDLE_POSITION_Y_TOLERANCE_PIX = 30;

    private enum TestPageType {
        EDITABLE(TEXTAREA_ID, TEXTAREA_DATA_URL, true),
        NONEDITABLE(NONEDITABLE_DIV_ID, NONEDITABLE_DATA_URL, false);

        final String nodeId;
        final String dataUrl;
        final boolean selectionShouldBeEditable;

        TestPageType(String nodeId, String dataUrl, boolean selectionShouldBeEditable) {
            this.nodeId = nodeId;
            this.dataUrl = dataUrl;
            this.selectionShouldBeEditable = selectionShouldBeEditable;
        }
    }

    private void launchWithUrl(String url) throws Throwable {
        launchContentShellWithUrl(url);
        assertTrue("Page failed to load", waitForActiveShellToBeDoneLoading());
        assertWaitForPageScaleFactorMatch(1.0f);

        // The TestInputMethodManagerWrapper intercepts showSoftInput so that a keyboard is never
        // brought up.
        getImeAdapter().setInputMethodManagerWrapper(
                new TestInputMethodManagerWrapper(getContentViewCore()));
    }

    private void assertWaitForHasSelectionPosition()
            throws Throwable {
        assertTrue(CriteriaHelper.pollForCriteria(new Criteria() {
            @Override
            public boolean isSatisfied() {
                int start = getSelectionStart();
                int end = getSelectionEnd();
                return start > 0 && start == end;
            }
        }));
    }

    /**
     * Verifies that when a long-press is performed on static page text,
     * selection handles appear and that handles can be dragged to extend the
     * selection. Does not check exact handle position as this will depend on
     * screen size; instead, position is expected to be correct within
     * HANDLE_POSITION_TOLERANCE_PIX.
     *
     * Test is flaky: crbug.com/290375
     * @MediumTest
     * @Feature({ "TextSelection", "Main" })
     */
    @FlakyTest
    public void testNoneditableSelectionHandles() throws Throwable {
        doSelectionHandleTest(TestPageType.NONEDITABLE);
    }

    /**
     * Test is flaky: crbug.com/290375
     * @MediumTest
     * @Feature({ "TextSelection", "Main" })
     */
    @FlakyTest
    public void testUpdateContainerViewAndNoneditableSelectionHandles() throws Throwable {
        launchWithUrl(TestPageType.NONEDITABLE.dataUrl);
        replaceContainerView();
        doSelectionHandleTestUrlLaunched(TestPageType.NONEDITABLE);
    }

    /**
     * Verifies that when a long-press is performed on editable text (within a
     * textarea), selection handles appear and that handles can be dragged to
     * extend the selection. Does not check exact handle position as this will
     * depend on screen size; instead, position is expected to be correct within
     * HANDLE_POSITION_TOLERANCE_PIX.
     */
    @MediumTest
    @Feature({ "TextSelection" })
    public void testEditableSelectionHandles() throws Throwable {
        doSelectionHandleTest(TestPageType.EDITABLE);
    }

    @MediumTest
    @Feature({ "TextSelection" })
    public void testUpdateContainerViewAndEditableSelectionHandles() throws Throwable {
        launchWithUrl(TestPageType.EDITABLE.dataUrl);
        replaceContainerView();
        doSelectionHandleTestUrlLaunched(TestPageType.EDITABLE);
    }

    private void doSelectionHandleTest(TestPageType pageType) throws Throwable {
        launchWithUrl(pageType.dataUrl);
        doSelectionHandleTestUrlLaunched(pageType);
    }

    private void doSelectionHandleTestUrlLaunched(TestPageType pageType) throws Throwable {
        clickNodeToShowSelectionHandles(pageType.nodeId);
        assertWaitForSelectionEditableEquals(pageType.selectionShouldBeEditable);

        HandleView startHandle = getStartHandle();
        HandleView endHandle = getEndHandle();

        Rect nodeWindowBounds = getNodeBoundsPix(pageType.nodeId);

        int leftX = (nodeWindowBounds.left + nodeWindowBounds.centerX()) / 2;
        int centerX = nodeWindowBounds.centerX();
        int rightX = (nodeWindowBounds.right + nodeWindowBounds.centerX()) / 2;

        int topY = (nodeWindowBounds.top + nodeWindowBounds.centerY()) / 2;
        int centerY = nodeWindowBounds.centerY();
        int bottomY = (nodeWindowBounds.bottom + nodeWindowBounds.centerY()) / 2;

        // Drag start handle up and to the left. The selection start should decrease.
        dragHandleAndCheckSelectionChange(startHandle, leftX, topY, -1, 0);
        // Drag end handle down and to the right. The selection end should increase.
        dragHandleAndCheckSelectionChange(endHandle, rightX, bottomY, 0, 1);
        // Drag start handle back to the middle. The selection start should increase.
        dragHandleAndCheckSelectionChange(startHandle, centerX, centerY, 1, 0);
        // Drag end handle up and to the left past the start handle. Both selection start and end
        // should decrease.
        dragHandleAndCheckSelectionChange(endHandle, leftX, topY, -1, -1);
        // Drag start handle down and to the right past the end handle. Both selection start and end
        // should increase.
        dragHandleAndCheckSelectionChange(startHandle, rightX, bottomY, 1, 1);

        clickToDismissHandles();
    }

    private void dragHandleAndCheckSelectionChange(HandleView handle, int dragToX, int dragToY,
            final int expectedStartChange, final int expectedEndChange) throws Throwable {
        String initialText = getContentViewCore().getSelectedText();
        final int initialSelectionEnd = getSelectionEnd();
        final int initialSelectionStart = getSelectionStart();

        dragHandleTo(handle, dragToX, dragToY, 10);
        assertWaitForEitherHandleNear(dragToX, dragToY);

        if (getContentViewCore().isSelectionEditable()) {
            assertTrue(CriteriaHelper.pollForCriteria(new Criteria() {
                @Override
                public boolean isSatisfied() {
                    int startChange = getSelectionStart() - initialSelectionStart;
                    // TODO(cjhopman): Due to http://crbug.com/244633 we can't really assert that
                    // there is no change when we expect to be able to.
                    if (expectedStartChange != 0) {
                        if ((int) Math.signum(startChange) != expectedStartChange) return false;
                    }

                    int endChange = getSelectionEnd() - initialSelectionEnd;
                    if (expectedEndChange != 0) {
                        if ((int) Math.signum(endChange) != expectedEndChange) return false;
                    }

                    return true;
                }
            }));
        }

        assertWaitForHandleViewStopped(getStartHandle());
        assertWaitForHandleViewStopped(getEndHandle());
    }

    private void assertWaitForSelectionEditableEquals(final boolean expected) throws Throwable {
        assertTrue(CriteriaHelper.pollForCriteria(new Criteria() {
            @Override
            public boolean isSatisfied() {
                return getContentViewCore().isSelectionEditable() == expected;
            }
        }));
    }

    private void assertWaitForHandleViewStopped(final HandleView handle) throws Throwable {
        assertTrue(CriteriaHelper.pollForCriteria(new Criteria() {
            private Point position = new Point(-1, -1);
            @Override
            public boolean isSatisfied() {
                Point lastPosition = position;
                position = getHandlePosition(handle);
                return !handle.isDragging() &&
                        position.equals(lastPosition);
            }
        }));
    }

    /**
     * Verifies that when a selection is made within static page text, that the
     * contextual action bar of the correct type is displayed. Also verified
     * that the bar disappears upon deselection.
     */
    @MediumTest
    @Feature({ "TextSelection" })
    public void testNoneditableSelectionActionBar() throws Throwable {
        doSelectionActionBarTest(TestPageType.NONEDITABLE);
    }

    /**
     * Verifies that when a selection is made within editable text, that the
     * contextual action bar of the correct type is displayed. Also verified
     * that the bar disappears upon deselection.
     */
    @MediumTest
    @Feature({ "TextSelection" })
    public void testEditableSelectionActionBar() throws Throwable {
        doSelectionActionBarTest(TestPageType.EDITABLE);
    }

    private void doSelectionActionBarTest(TestPageType pageType) throws Throwable {
        launchWithUrl(pageType.dataUrl);
        assertFalse(getContentViewCore().isSelectActionBarShowing());
        clickNodeToShowSelectionHandles(pageType.nodeId);
        assertWaitForSelectActionBarShowingEquals(true);
        clickToDismissHandles();
        assertWaitForSelectActionBarShowingEquals(false);
    }

    private static Point getHandlePosition(final HandleView handle) {
        return ThreadUtils.runOnUiThreadBlockingNoException(new Callable<Point>() {
            @Override
            public Point call() {
                return new Point(handle.getAdjustedPositionX(), handle.getAdjustedPositionY());
            }
        });
    }

    private static boolean isHandleNear(HandleView handle, int x, int y) {
        Point position = getHandlePosition(handle);
        return (Math.abs(position.x - x) < HANDLE_POSITION_X_TOLERANCE_PIX) &&
                (Math.abs(position.y - y) < HANDLE_POSITION_Y_TOLERANCE_PIX);
    }

    private void assertWaitForHandleNear(final HandleView handle, final int x, final int y)
            throws Throwable {
        assertTrue(CriteriaHelper.pollForCriteria(new Criteria() {
            @Override
            public boolean isSatisfied() {
                return isHandleNear(handle, x, y);
            }
        }));
    }

    private void assertWaitForEitherHandleNear(final int x, final int y) throws Throwable {
        final HandleView startHandle = getStartHandle();
        final HandleView endHandle = getEndHandle();
        assertTrue(CriteriaHelper.pollForCriteria(new Criteria() {
            @Override
            public boolean isSatisfied() {
                return isHandleNear(startHandle, x, y) || isHandleNear(endHandle, x, y);
            }
        }));
    }

    private void assertWaitForHandlesShowingEquals(final boolean shouldBeShowing) throws Throwable {
        assertTrue(CriteriaHelper.pollForCriteria(new Criteria() {
            @Override
            public boolean isSatisfied() {
                SelectionHandleController shc =
                        getContentViewCore().getSelectionHandleControllerForTest();
                boolean isShowing = shc != null && shc.isShowing();
                return shouldBeShowing == isShowing;
            }
        }));
    }


    private void dragHandleTo(final HandleView handle, final int dragToX, final int dragToY,
            final int steps) throws Throwable {
        assertTrue(ThreadUtils.runOnUiThreadBlocking(new Callable<Boolean>() {
            @Override
            public Boolean call() {
                int adjustedX = handle.getAdjustedPositionX();
                int adjustedY = handle.getAdjustedPositionY();
                int realX = handle.getPositionX();
                int realY = handle.getPositionY();

                int realDragToX = dragToX + (realX - adjustedX);
                int realDragToY = dragToY + (realY - adjustedY);

                ViewGroup view = getContentViewCore().getContainerView();
                int[] fromLocation = TestTouchUtils.getAbsoluteLocationFromRelative(
                        view, realX, realY);
                int[] toLocation = TestTouchUtils.getAbsoluteLocationFromRelative(
                        view, realDragToX, realDragToY);

                long downTime = SystemClock.uptimeMillis();
                MotionEvent event = MotionEvent.obtain(downTime, downTime, MotionEvent.ACTION_DOWN,
                        fromLocation[0], fromLocation[1], 0);
                handle.dispatchTouchEvent(event);

                if (!handle.isDragging()) return false;

                for (int i = 0; i < steps; i++) {
                    float scale = (float) (i + 1) / steps;
                    int x = fromLocation[0] + (int) (scale * (toLocation[0] - fromLocation[0]));
                    int y = fromLocation[1] + (int) (scale * (toLocation[1] - fromLocation[1]));
                    long eventTime = SystemClock.uptimeMillis();
                    event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_MOVE,
                            x, y, 0);
                    handle.dispatchTouchEvent(event);
                }
                long upTime = SystemClock.uptimeMillis();
                event = MotionEvent.obtain(downTime, upTime, MotionEvent.ACTION_UP,
                        toLocation[0], toLocation[1], 0);
                handle.dispatchTouchEvent(event);

                return !handle.isDragging();
            }
        }));
    }

    private Rect getNodeBoundsPix(String nodeId) throws Throwable {
        Rect nodeBounds = DOMUtils.getNodeBounds(getContentViewCore(), nodeId);

        RenderCoordinates renderCoordinates = getContentViewCore().getRenderCoordinates();
        int offsetX = getContentViewCore().getViewportSizeOffsetWidthPix();
        int offsetY = getContentViewCore().getViewportSizeOffsetHeightPix();

        int left = (int) renderCoordinates.fromLocalCssToPix(nodeBounds.left) + offsetX;
        int right = (int) renderCoordinates.fromLocalCssToPix(nodeBounds.right) + offsetX;
        int top = (int) renderCoordinates.fromLocalCssToPix(nodeBounds.top) + offsetY;
        int bottom = (int) renderCoordinates.fromLocalCssToPix(nodeBounds.bottom) + offsetY;

        return new Rect(left, top, right, bottom);
    }

    private void clickNodeToShowSelectionHandles(String nodeId) throws Throwable {
        Rect nodeWindowBounds = getNodeBoundsPix(nodeId);

        TouchCommon touchCommon = new TouchCommon(this);
        int centerX = nodeWindowBounds.centerX();
        int centerY = nodeWindowBounds.centerY();
        touchCommon.longPressView(getContentViewCore().getContainerView(), centerX, centerY);

        assertWaitForHandlesShowingEquals(true);
        assertWaitForHandleViewStopped(getStartHandle());

        // No words wrap in the sample text so handles should be at the same y
        // position.
        assertEquals(getStartHandle().getPositionY(), getEndHandle().getPositionY());
    }

    private void clickToDismissHandles() throws Throwable {
        TestTouchUtils.sleepForDoubleTapTimeout(getInstrumentation());
        new TouchCommon(this).singleClickView(getContentViewCore().getContainerView(), 0, 0);
        assertWaitForHandlesShowingEquals(false);
    }

    private void assertWaitForSelectActionBarShowingEquals(final boolean shouldBeShowing)
            throws InterruptedException {
        assertTrue(CriteriaHelper.pollForCriteria(new Criteria() {
            @Override
            public boolean isSatisfied() {
                return shouldBeShowing == getContentViewCore().isSelectActionBarShowing();
            }
        }));
    }

    public void assertWaitForHasInputConnection() {
        try {
            assertTrue(CriteriaHelper.pollForCriteria(new Criteria() {
                @Override
                public boolean isSatisfied() {
                    return getContentViewCore().getInputConnectionForTest() != null;
                }
            }));
        } catch (InterruptedException e) {
            fail();
        }
    }

    private ImeAdapter getImeAdapter() {
        return getContentViewCore().getImeAdapterForTest();
    }

    private int getSelectionStart() {
        return Selection.getSelectionStart(getEditable());
    }

    private int getSelectionEnd() {
        return Selection.getSelectionEnd(getEditable());
    }

    private Editable getEditable() {
        // We have to wait for the input connection (with the IME) to be created before accessing
        // the ContentViewCore's editable.
        assertWaitForHasInputConnection();
        return getContentViewCore().getEditableForTest();
    }

    private HandleView getStartHandle() {
        SelectionHandleController shc = getContentViewCore().getSelectionHandleControllerForTest();
        return shc.getStartHandleViewForTest();
    }

    private HandleView getEndHandle() {
        SelectionHandleController shc = getContentViewCore().getSelectionHandleControllerForTest();
        return shc.getEndHandleViewForTest();
    }
}
