/*
 * 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
