/*
 * Copyright (C) 2013 Google Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 * copyright notice, this list of conditions and the following disclaimer
 * in the documentation and/or other materials provided with the
 * distribution.
 *     * Neither the name of Google Inc. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/public/platform/web_coalesced_input_event.h"
#include "third_party/blink/public/platform/web_touch_event.h"
#include "third_party/blink/public/platform/web_url_loader_mock_factory.h"
#include "third_party/blink/public/web/web_document.h"
#include "third_party/blink/public/web/web_frame.h"
#include "third_party/blink/public/web/web_hit_test_result.h"
#include "third_party/blink/public/web/web_view.h"
#include "third_party/blink/public/web/web_view_client.h"
#include "third_party/blink/public/web/web_widget_client.h"
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/dom/element.h"
#include "third_party/blink/renderer/core/dom/shadow_root.h"
#include "third_party/blink/renderer/core/dom/static_node_list.h"
#include "third_party/blink/renderer/core/exported/web_view_impl.h"
#include "third_party/blink/renderer/core/frame/frame_test_helpers.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/core/frame/local_frame_view.h"
#include "third_party/blink/renderer/core/frame/web_local_frame_impl.h"
#include "third_party/blink/renderer/core/geometry/dom_rect.h"
#include "third_party/blink/renderer/core/geometry/dom_rect_list.h"
#include "third_party/blink/renderer/core/html/html_iframe_element.h"
#include "third_party/blink/renderer/core/input/event_handler.h"
#include "third_party/blink/renderer/core/layout/hit_test_result.h"
#include "third_party/blink/renderer/core/layout/layout_tree_as_text.h"
#include "third_party/blink/renderer/core/layout/layout_view.h"
#include "third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h"
#include "third_party/blink/renderer/platform/testing/unit_test_helpers.h"
#include "third_party/blink/renderer/platform/testing/url_test_helpers.h"

using blink::test::RunPendingTasks;

namespace blink {

class TouchActionTrackingWebWidgetClient
    : public frame_test_helpers::TestWebWidgetClient {
 public:
  TouchActionTrackingWebWidgetClient()
      : action_set_count_(0), action_(TouchAction::kTouchActionAuto) {}

  // WebWidgetClient methods
  void SetTouchAction(TouchAction touch_action) override {
    action_set_count_++;
    action_ = touch_action;
  }

  // Local methods
  void Reset() {
    action_set_count_ = 0;
    action_ = TouchAction::kTouchActionAuto;
  }

  int TouchActionSetCount() { return action_set_count_; }

  TouchAction LastTouchAction() { return action_; }

 private:
  int action_set_count_;
  TouchAction action_;
};

class TouchActionTest : public testing::Test {
 public:
  TouchActionTest() : base_url_("http://www.test.com/") {
    url_test_helpers::RegisterMockedURLLoadFromBase(
        WebString::FromUTF8(base_url_), test::CoreTestDataPath(),
        "touch-action-tests.css", "text/css");
    url_test_helpers::RegisterMockedURLLoadFromBase(
        WebString::FromUTF8(base_url_), test::CoreTestDataPath(),
        "touch-action-tests.js", "text/javascript");
    url_test_helpers::RegisterMockedURLLoadFromBase(
        WebString::FromUTF8(base_url_), test::CoreTestDataPath(),
        "white-1x1.png", "image/png");
  }

  void TearDown() override {
    Platform::Current()
        ->GetURLLoaderMockFactory()
        ->UnregisterAllURLsAndClearMemoryCache();
  }

 protected:
  void RunTouchActionTest(std::string file);
  void RunShadowDOMTest(std::string file);
  void RunIFrameTest(std::string file);
  void SendTouchEvent(WebView*, WebInputEvent::Type, IntPoint client_point);
  WebViewImpl* SetupTest(std::string file, TouchActionTrackingWebWidgetClient*);
  void RunTestOnTree(ContainerNode* root,
                     WebView*,
                     TouchActionTrackingWebWidgetClient&);

  std::string base_url_;
  frame_test_helpers::WebViewHelper web_view_helper_;
};

void TouchActionTest::RunTouchActionTest(std::string file) {
  TouchActionTrackingWebWidgetClient client;

  // runTouchActionTest() loads a document in a frame, setting up a
  // nested run loop. Should any Oilpan GC happen while it is in
  // effect, the implicit assumption that we're outside any event
  // loop (=> there being no pointers on the stack needing scanning)
  // when that GC strikes will no longer hold.
  //
  // To ensure that the references on the stack are also traced, we
  // turn them into persistent, stack allocated references. This
  // workaround is sufficient to handle this artificial test
  // scenario.
  WebViewImpl* web_view = SetupTest(file, &client);

  Persistent<Document> document =
      static_cast<Document*>(web_view->MainFrameImpl()->GetDocument());
  RunTestOnTree(document.Get(), web_view, client);

  // Explicitly reset to break dependency on locally scoped client.
  web_view_helper_.Reset();
}

void TouchActionTest::RunShadowDOMTest(std::string file) {
  TouchActionTrackingWebWidgetClient client;

  WebViewImpl* web_view = SetupTest(file, &client);

  DummyExceptionStateForTesting es;

  // Oilpan: see runTouchActionTest() comment why these are persistent
  // references.
  Persistent<Document> document =
      static_cast<Document*>(web_view->MainFrameImpl()->GetDocument());
  Persistent<StaticElementList> host_nodes =
      document->QuerySelectorAll("[shadow-host]", es);
  ASSERT_FALSE(es.HadException());
  ASSERT_GE(host_nodes->length(), 1u);

  for (unsigned index = 0; index < host_nodes->length(); index++) {
    ShadowRoot* shadow_root = host_nodes->item(index)->OpenShadowRoot();
    RunTestOnTree(shadow_root, web_view, client);
  }

  // Projections show up in the main document.
  RunTestOnTree(document.Get(), web_view, client);

  // Explicitly reset to break dependency on locally scoped client.
  web_view_helper_.Reset();
}

void TouchActionTest::RunIFrameTest(std::string file) {
  TouchActionTrackingWebWidgetClient client;

  WebViewImpl* web_view = SetupTest(file, &client);
  WebFrame* cur_frame = web_view->MainFrame()->FirstChild();
  ASSERT_TRUE(cur_frame);

  for (; cur_frame; cur_frame = cur_frame->NextSibling()) {
    // Oilpan: see runTouchActionTest() comment why these are persistent
    // references.
    Persistent<Document> content_doc =
        static_cast<Document*>(cur_frame->ToWebLocalFrame()->GetDocument());
    RunTestOnTree(content_doc.Get(), web_view, client);
  }

  // Explicitly reset to break dependency on locally scoped client.
  web_view_helper_.Reset();
}

WebViewImpl* TouchActionTest::SetupTest(
    std::string file,
    TouchActionTrackingWebWidgetClient* client) {
  url_test_helpers::RegisterMockedURLLoadFromBase(
      WebString::FromUTF8(base_url_), test::CoreTestDataPath(),
      WebString::FromUTF8(file));
  // Note that JavaScript must be enabled for shadow DOM tests.
  WebViewImpl* web_view = web_view_helper_.InitializeAndLoad(
      base_url_ + file, nullptr, nullptr, client);

  // Set size to enable hit testing, and avoid line wrapping for consistency
  // with browser.
  web_view->MainFrameWidget()->Resize(WebSize(900, 1600));

  // Scroll to verify the code properly transforms windows to client co-ords.
  const int kScrollOffset = 100;
  Document* document =
      static_cast<Document*>(web_view->MainFrameImpl()->GetDocument());
  document->GetFrame()->View()->LayoutViewport()->SetScrollOffset(
      ScrollOffset(0, kScrollOffset), kProgrammaticScroll);

  return web_view;
}

IntRect WindowClipRect(const LocalFrameView& frame_view) {
  LayoutRect clip_rect(LayoutPoint(), LayoutSize(frame_view.Size()));
  frame_view.GetLayoutView()->MapToVisualRectInAncestorSpace(
      &frame_view.GetLayoutView()->ContainerForPaintInvalidation(), clip_rect,
      0, kDefaultVisualRectFlags);
  return EnclosingIntRect(clip_rect);
}

void TouchActionTest::RunTestOnTree(
    ContainerNode* root,
    WebView* web_view,
    TouchActionTrackingWebWidgetClient& client) {
  // Find all elements to test the touch-action of in the document.
  DummyExceptionStateForTesting es;

  // Oilpan: see runTouchActionTest() comment why these are persistent
  // references.
  Persistent<StaticElementList> elements =
      root->QuerySelectorAll("[expected-action]", es);
  ASSERT_FALSE(es.HadException());

  for (unsigned index = 0; index < elements->length(); index++) {
    Element* element = elements->item(index);
    element->scrollIntoViewIfNeeded();

    std::string failure_context("Test case: ");
    if (element->HasID()) {
      failure_context.append(element->GetIdAttribute().Ascii().data());
    } else if (element->firstChild()) {
      failure_context.append("\"");
      failure_context.append(element->firstChild()
                                 ->textContent(false)
                                 .StripWhiteSpace()
                                 .Ascii()
                                 .data());
      failure_context.append("\"");
    } else {
      failure_context += "<missing ID>";
    }

    // Run each test three times at different positions in the element.
    // Note that we don't want the bounding box because our tests sometimes have
    // elements with multiple border boxes with other elements in between. Use
    // the first border box (which we can easily visualize in a browser for
    // debugging).
    Persistent<DOMRectList> rects = element->getClientRects();
    ASSERT_GE(rects->length(), 0u) << failure_context;
    Persistent<DOMRect> r = rects->item(0);
    FloatRect client_float_rect =
        FloatRect(r->left(), r->top(), r->width(), r->height());
    IntRect client_rect = EnclosedIntRect(client_float_rect);
    for (int loc_idx = 0; loc_idx < 3; loc_idx++) {
      IntPoint frame_point;
      std::stringstream context_stream;
      context_stream << failure_context << " (";
      switch (loc_idx) {
        case 0:
          frame_point = client_rect.Center();
          context_stream << "center";
          break;
        case 1:
          frame_point = client_rect.Location();
          context_stream << "top-left";
          break;
        case 2:
          frame_point = client_rect.MaxXMaxYCorner();
          frame_point.Move(-1, -1);
          context_stream << "bottom-right";
          break;
        default:
          FAIL() << "Invalid location index.";
      }

      IntPoint window_point =
          root->GetDocument().GetFrame()->View()->ConvertToRootFrame(
              frame_point);
      context_stream << "=" << window_point.X() << "," << window_point.Y()
                     << ").";
      std::string failure_context_pos = context_stream.str();

      LocalFrame* main_frame =
          ToLocalFrame(WebFrame::ToCoreFrame(*web_view->MainFrame()));
      LocalFrameView* main_frame_view = main_frame->View();
      IntRect visible_rect = WindowClipRect(*main_frame_view);
      ASSERT_TRUE(visible_rect.Contains(window_point))
          << failure_context_pos
          << " Test point not contained in visible area: " << visible_rect.X()
          << "," << visible_rect.Y() << "-" << visible_rect.MaxX() << ","
          << visible_rect.MaxY();

      // First validate that a hit test at this point will really hit the
      // element we intended. This is the easiest way for a test to be broken,
      // but has nothing really to do with touch action.  Note that we can't use
      // WebView's hit test API because it doesn't look into shadow DOM.
      HitTestLocation location(window_point);
      HitTestResult result =
          main_frame->GetEventHandler().HitTestResultAtLocation(
              location, HitTestRequest::kReadOnly | HitTestRequest::kActive);
      ASSERT_EQ(element, result.InnerElement())
          << "Unexpected hit test result " << failure_context_pos
          << "  Got element: \""
          << result.InnerElement()
                 ->OuterHTMLAsString()
                 .StripWhiteSpace()
                 .Left(80)
                 .Ascii()
                 .data()
          << "\"" << std::endl
          << "Document render tree:" << std::endl
          << ExternalRepresentation(root->GetDocument().GetFrame())
                 .Utf8()
                 .data();

      // Now send the touch event and check any touch action result.
      SendTouchEvent(web_view, WebInputEvent::kPointerDown, window_point);

      AtomicString expected_action = element->getAttribute("expected-action");
      // Should have received exactly one touch action, even for auto.
      EXPECT_EQ(1, client.TouchActionSetCount()) << failure_context_pos;
      if (client.TouchActionSetCount()) {
        if (expected_action == "auto") {
          EXPECT_EQ(TouchAction::kTouchActionAuto, client.LastTouchAction())
              << failure_context_pos;
        } else if (expected_action == "none") {
          EXPECT_EQ(TouchAction::kTouchActionNone, client.LastTouchAction())
              << failure_context_pos;
        } else if (expected_action == "pan-x") {
          EXPECT_EQ(TouchAction::kTouchActionPanX, client.LastTouchAction())
              << failure_context_pos;
        } else if (expected_action == "pan-y") {
          EXPECT_EQ(TouchAction::kTouchActionPanY, client.LastTouchAction())
              << failure_context_pos;
        } else if (expected_action == "pan-x-y") {
          EXPECT_EQ((TouchAction::kTouchActionPan), client.LastTouchAction())
              << failure_context_pos;
        } else if (expected_action == "manipulation") {
          EXPECT_EQ((TouchAction::kTouchActionManipulation),
                    client.LastTouchAction())
              << failure_context_pos;
        } else {
          FAIL() << "Unrecognized expected-action \""
                 << expected_action.Ascii().data() << "\" "
                 << failure_context_pos;
        }
      }

      // Reset webview touch state.
      client.Reset();
      SendTouchEvent(web_view, WebInputEvent::kPointerCancel, window_point);
      EXPECT_EQ(0, client.TouchActionSetCount());
    }
  }
}
void TouchActionTest::SendTouchEvent(WebView* web_view,
                                     WebInputEvent::Type type,
                                     IntPoint client_point) {
  ASSERT_TRUE(type == WebInputEvent::kPointerDown ||
              type == WebInputEvent::kPointerCancel);

  WebPointerEvent event(
      type,
      WebPointerProperties(1, WebPointerProperties::PointerType::kTouch,
                           WebPointerProperties::Button::kLeft,
                           WebFloatPoint(client_point.X(), client_point.Y()),
                           WebFloatPoint(client_point.X(), client_point.Y())),
      10.0f, 10.0f);
  if (type == WebInputEvent::kPointerCancel)
    event.dispatch_type = WebInputEvent::kEventNonBlocking;

  web_view->MainFrameWidget()->HandleInputEvent(WebCoalescedInputEvent(event));
  web_view->MainFrameWidget()->DispatchBufferedTouchEvents();
  RunPendingTasks();
}

// crbug.com/411038
TEST_F(TouchActionTest, Simple) {
  RunTouchActionTest("touch-action-simple.html");
}

TEST_F(TouchActionTest, Overflow) {
  RunTouchActionTest("touch-action-overflow.html");
}

TEST_F(TouchActionTest, IFrame) {
  RunIFrameTest("touch-action-iframe.html");
}

TEST_F(TouchActionTest, ShadowDOM) {
  RunShadowDOMTest("touch-action-shadow-dom.html");
}

TEST_F(TouchActionTest, Pan) {
  RunTouchActionTest("touch-action-pan.html");
}

}  // namespace blink
