// Copyright (c) 2016 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.

#include "core/dom/Range.h"
#include "core/frame/FrameView.h"
#include "core/input/EventHandler.h"
#include "core/page/ChromeClient.h"
#include "core/page/ContextMenuController.h"
#include "core/page/FocusController.h"
#include "core/page/Page.h"
#include "platform/Cursor.h"
#include "platform/testing/URLTestHelpers.h"
#include "platform/testing/UnitTestHelpers.h"
#include "public/web/WebSettings.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "web/WebLocalFrameImpl.h"
#include "web/tests/FrameTestHelpers.h"

using ::testing::_;

namespace blink {

IntSize scaled(IntSize p, float scale)
{
    p.scale(scale, scale);
    return p;
}

class LinkSelectionTestBase : public ::testing::Test {
protected:
    enum DragFlag {
        SendDownEvent = 1,
        SendUpEvent = 1 << 1
    };
    using DragFlags = unsigned;

    void emulateMouseDrag(const IntPoint& downPoint, const IntPoint& upPoint, int modifiers,
        DragFlags = SendDownEvent | SendUpEvent);

    void emulateMouseClick(const IntPoint& clickPoint, WebMouseEvent::Button, int modifiers, int count = 1);
    void emulateMouseDown(const IntPoint& clickPoint, WebMouseEvent::Button, int modifiers, int count = 1);

    String getSelectionText();

    FrameTestHelpers::WebViewHelper m_helper;
    WebViewImpl* m_webView = nullptr;
    RawPtrWillBePersistent<WebLocalFrameImpl> m_mainFrame = nullptr;
};

void LinkSelectionTestBase::emulateMouseDrag(const IntPoint& downPoint, const IntPoint& upPoint, int modifiers, DragFlags dragFlags)
{
    if (dragFlags & SendDownEvent) {
        const auto& downEvent = FrameTestHelpers::createMouseEvent(WebMouseEvent::MouseDown, WebMouseEvent::ButtonLeft, downPoint, modifiers);
        m_webView->handleInputEvent(downEvent);
    }

    const int kMoveEventsNumber = 10;
    const float kMoveIncrementFraction = 1. / kMoveEventsNumber;
    const auto& upDownVector = upPoint - downPoint;
    for (int i = 0; i < kMoveEventsNumber; ++i) {
        const auto& movePoint = downPoint + scaled(upDownVector, i * kMoveIncrementFraction);
        const auto& moveEvent = FrameTestHelpers::createMouseEvent(WebMouseEvent::MouseMove, WebMouseEvent::ButtonLeft, movePoint, modifiers);
        m_webView->handleInputEvent(moveEvent);
    }

    if (dragFlags & SendUpEvent) {
        const auto& upEvent = FrameTestHelpers::createMouseEvent(WebMouseEvent::MouseUp, WebMouseEvent::ButtonLeft, upPoint, modifiers);
        m_webView->handleInputEvent(upEvent);
    }
}

void LinkSelectionTestBase::emulateMouseClick(const IntPoint& clickPoint, WebMouseEvent::Button button, int modifiers, int count)
{
    auto event = FrameTestHelpers::createMouseEvent(WebMouseEvent::MouseDown, button, clickPoint, modifiers);
    event.clickCount = count;
    m_webView->handleInputEvent(event);
    event.type = WebMouseEvent::MouseUp;
    m_webView->handleInputEvent(event);
}

void LinkSelectionTestBase::emulateMouseDown(const IntPoint& clickPoint, WebMouseEvent::Button button, int modifiers, int count)
{
    auto event = FrameTestHelpers::createMouseEvent(WebMouseEvent::MouseDown, button, clickPoint, modifiers);
    event.clickCount = count;
    m_webView->handleInputEvent(event);
}

String LinkSelectionTestBase::getSelectionText()
{
    return m_mainFrame->selectionAsText();
}

class TestFrameClient : public FrameTestHelpers::TestWebFrameClient {
public:
    MOCK_METHOD4(loadURLExternally,
        void(const WebURLRequest&, WebNavigationPolicy, const WebString& downloadName, bool shouldReplaceCurrentEntry));
};

class LinkSelectionTest : public LinkSelectionTestBase {
protected:
    void SetUp() override
    {
        const char* const kHTMLString =
            "<a id='link' href='foo.com' style='font-size:20pt'>Text to select foobar</a>"
            "<div id='page_text'>Lorem ipsum dolor sit amet</div>";

        // We need to set deviceSupportsMouse setting to true and page's focus controller to active
        // so that FrameView can set the mouse cursor.
        m_webView = m_helper.initialize(false, &m_testFrameClient, nullptr,
            [](WebSettings* settings) { settings->setDeviceSupportsMouse(true); });
        m_mainFrame = m_webView->mainFrameImpl();
        FrameTestHelpers::loadHTMLString(m_mainFrame, kHTMLString, URLTestHelpers::toKURL("http://foobar.com"));
        m_webView->resize(WebSize(800, 600));
        m_webView->page()->focusController().setActive(true);

        auto* document = m_mainFrame->frame()->document();
        ASSERT_NE(nullptr, document);
        auto* linkToSelect = document->getElementById("link")->firstChild();
        ASSERT_NE(nullptr, linkToSelect);
        // We get larger range that we actually want to select, because we need a slightly larger
        // rect to include the last character to the selection.
        const auto rangeToSelect = Range::create(*document, linkToSelect, 5, linkToSelect, 16);

        const auto& selectionRect = rangeToSelect->boundingBox();
        const auto& selectionRectCenterY = selectionRect.center().y();
        m_leftPointInLink = selectionRect.minXMinYCorner();
        m_leftPointInLink.setY(selectionRectCenterY);

        m_rightPointInLink = selectionRect.maxXMinYCorner();
        m_rightPointInLink.setY(selectionRectCenterY);
        m_rightPointInLink.move(-2, 0);
    }

    TestFrameClient m_testFrameClient;
    IntPoint m_leftPointInLink;
    IntPoint m_rightPointInLink;
};

TEST_F(LinkSelectionTest, MouseDragWithoutAltAllowNoLinkSelection)
{
    emulateMouseDrag(m_leftPointInLink, m_rightPointInLink, 0);
    EXPECT_TRUE(getSelectionText().isEmpty());
}

TEST_F(LinkSelectionTest, MouseDragWithAltAllowSelection)
{
    emulateMouseDrag(m_leftPointInLink, m_rightPointInLink, WebInputEvent::AltKey);
    EXPECT_EQ("to select", getSelectionText());
}

TEST_F(LinkSelectionTest, HandCursorDuringLinkDrag)
{
    emulateMouseDrag(m_rightPointInLink, m_leftPointInLink, 0, SendDownEvent);
    m_mainFrame->frame()->localFrameRoot()->eventHandler().scheduleCursorUpdate();
    testing::runDelayedTasks(50);
    const auto& cursor = m_mainFrame->frame()->chromeClient().lastSetCursorForTesting();
    EXPECT_EQ(Cursor::Hand, cursor.getType());
}

TEST_F(LinkSelectionTest, CaretCursorOverLinkDuringSelection)
{
    emulateMouseDrag(m_rightPointInLink, m_leftPointInLink, WebInputEvent::AltKey, SendDownEvent);
    m_mainFrame->frame()->localFrameRoot()->eventHandler().scheduleCursorUpdate();
    testing::runDelayedTasks(50);
    const auto& cursor = m_mainFrame->frame()->chromeClient().lastSetCursorForTesting();
    EXPECT_EQ(Cursor::IBeam, cursor.getType());
}

TEST_F(LinkSelectionTest, HandCursorOverLinkAfterContextMenu)
{
    // Move mouse.
    emulateMouseDrag(m_rightPointInLink, m_leftPointInLink, 0, 0);

    // Show context menu. We don't send mouseup event here since in browser it doesn't reach
    // blink because of shown context menu.
    emulateMouseDown(m_leftPointInLink, WebMouseEvent::ButtonRight, 0, 1);

    LocalFrame* frame = m_mainFrame->frame();
    // Hide context menu.
    frame->page()->contextMenuController().clearContextMenu();

    frame->localFrameRoot()->eventHandler().scheduleCursorUpdate();
    testing::runDelayedTasks(50);
    const auto& cursor = m_mainFrame->frame()->chromeClient().lastSetCursorForTesting();
    EXPECT_EQ(Cursor::Hand, cursor.getType());
}

TEST_F(LinkSelectionTest, SingleClickWithAltStartsDownload)
{
    EXPECT_CALL(m_testFrameClient, loadURLExternally(_, WebNavigationPolicy::WebNavigationPolicyDownload, WebString(), _));
    emulateMouseClick(m_leftPointInLink, WebMouseEvent::ButtonLeft, WebInputEvent::AltKey);
}

TEST_F(LinkSelectionTest, SingleClickWithAltStartsDownloadWhenTextSelected)
{
    auto* document = m_mainFrame->frame()->document();
    auto* textToSelect = document->getElementById("page_text")->firstChild();
    ASSERT_NE(nullptr, textToSelect);

    // Select some page text outside the link element.
    const RefPtrWillBeRawPtr<Range> rangeToSelect = Range::create(*document, textToSelect, 1, textToSelect, 20);
    const auto& selectionRect = rangeToSelect->boundingBox();
    m_mainFrame->moveRangeSelection(selectionRect.minXMinYCorner(), selectionRect.maxXMaxYCorner());
    EXPECT_FALSE(getSelectionText().isEmpty());

    EXPECT_CALL(m_testFrameClient, loadURLExternally(_, WebNavigationPolicy::WebNavigationPolicyDownload, WebString(), _));
    emulateMouseClick(m_leftPointInLink, WebMouseEvent::ButtonLeft, WebInputEvent::AltKey);
}

class LinkSelectionClickEventsTest : public LinkSelectionTestBase {
protected:
    class MockEventListener final : public EventListener {
    public:
        static PassRefPtrWillBeRawPtr<MockEventListener> create()
        {
            return adoptRefWillBeNoop(new MockEventListener());
        }

        bool operator==(const EventListener& other) const final
        {
            return this == &other;
        }

        MOCK_METHOD2(handleEvent, void(ExecutionContext* executionContext, Event*));

    private:
        MockEventListener() : EventListener(CPPEventListenerType)
        {
        }
    };

    void SetUp() override
    {
        const char* const kHTMLString =
            "<div id='empty_div' style='width: 100px; height: 100px;'></div>"
            "<span id='text_div'>Sometexttoshow</span>";

        m_webView = m_helper.initialize(false);
        m_mainFrame = m_webView->mainFrameImpl();
        FrameTestHelpers::loadHTMLString(m_mainFrame, kHTMLString, URLTestHelpers::toKURL("http://foobar.com"));
        m_webView->resize(WebSize(800, 600));
        m_webView->page()->focusController().setActive(true);

        auto* document = m_mainFrame->frame()->document();
        ASSERT_NE(nullptr, document);

        auto* emptyDiv = document->getElementById("empty_div");
        auto* textDiv = document->getElementById("text_div");
        ASSERT_NE(nullptr, emptyDiv);
        ASSERT_NE(nullptr, textDiv);
    }

    void checkMouseClicks(Element& element, bool doubleClickEvent)
    {
        struct ScopedListenersCleaner {
            ScopedListenersCleaner(Element* element) : m_element(element) {}

            ~ScopedListenersCleaner()
            {
                m_element->removeAllEventListeners();
            }

            RawPtrWillBePersistent<Element> m_element;
        } const listenersCleaner(&element);

        RefPtrWillBeRawPtr<MockEventListener> eventHandler = MockEventListener::create();
        element.addEventListener(
            doubleClickEvent ? EventTypeNames::dblclick : EventTypeNames::click,
            eventHandler);

        ::testing::InSequence s;
        EXPECT_CALL(*eventHandler, handleEvent(_, _)).Times(1);

        const auto& elemBounds = element.boundsInViewport();
        const int clickCount = doubleClickEvent ? 2 : 1;
        emulateMouseClick(elemBounds.center(), WebMouseEvent::ButtonLeft, 0, clickCount);

        if (doubleClickEvent) {
            EXPECT_EQ(element.innerText().isEmpty(), getSelectionText().isEmpty());
        }
    }
};

TEST_F(LinkSelectionClickEventsTest, SingleAndDoubleClickWillBeHandled)
{
    auto* document = m_mainFrame->frame()->document();
    auto* element = document->getElementById("empty_div");

    {
        SCOPED_TRACE("Empty div, single click");
        checkMouseClicks(*element, false);
    }

    {
        SCOPED_TRACE("Empty div, double click");
        checkMouseClicks(*element, true);
    }

    element = document->getElementById("text_div");

    {
        SCOPED_TRACE("Text div, single click");
        checkMouseClicks(*element, false);
    }

    {
        SCOPED_TRACE("Text div, double click");
        checkMouseClicks(*element, true);
    }
}

} // namespace blink
