/*
 * Copyright (C) 2011 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 "web/tests/FrameTestHelpers.h"

#include "platform/testing/URLTestHelpers.h"
#include "platform/testing/UnitTestHelpers.h"
#include "platform/testing/WebLayerTreeViewImplForTesting.h"
#include "public/platform/Platform.h"
#include "public/platform/WebData.h"
#include "public/platform/WebString.h"
#include "public/platform/WebThread.h"
#include "public/platform/WebURLLoaderMockFactory.h"
#include "public/platform/WebURLRequest.h"
#include "public/platform/WebURLResponse.h"
#include "public/web/WebFrameWidget.h"
#include "public/web/WebSettings.h"
#include "public/web/WebTreeScopeType.h"
#include "public/web/WebViewClient.h"
#include "web/WebLocalFrameImpl.h"
#include "web/WebRemoteFrameImpl.h"
#include "wtf/Functional.h"
#include "wtf/PtrUtil.h"
#include "wtf/StdLibExtras.h"
#include "wtf/text/StringBuilder.h"

namespace blink {
namespace FrameTestHelpers {

namespace {

// The frame test helpers coordinate frame loads in a carefully choreographed
// dance. Since the parser is threaded, simply spinning the run loop once is not
// enough to ensure completion of a load. Instead, the following pattern is
// used to ensure that tests see the final state:
// 1. Starts a load.
// 2. Enter the run loop.
// 3. Posted task triggers the load, and starts pumping pending resource
//    requests using runServeAsyncRequestsTask().
// 4. TestWebFrameClient watches for didStartLoading/didStopLoading calls,
//    keeping track of how many loads it thinks are in flight.
// 5. While runServeAsyncRequestsTask() observes TestWebFrameClient to still
//    have loads in progress, it posts itself back to the run loop.
// 6. When runServeAsyncRequestsTask() notices there are no more loads in
//    progress, it exits the run loop.
// 7. At this point, all parsing, resource loads, and layout should be finished.
TestWebFrameClient* testClientForFrame(WebFrame* frame) {
  return static_cast<TestWebFrameClient*>(toWebLocalFrameImpl(frame)->client());
}

void runServeAsyncRequestsTask(TestWebFrameClient* client) {
  Platform::current()->getURLLoaderMockFactory()->serveAsynchronousRequests();
  if (client->isLoading())
    Platform::current()->currentThread()->getWebTaskRunner()->postTask(
        BLINK_FROM_HERE,
        WTF::bind(&runServeAsyncRequestsTask, WTF::unretained(client)));
  else
    testing::exitRunLoop();
}

TestWebFrameClient* defaultWebFrameClient() {
  DEFINE_STATIC_LOCAL(TestWebFrameClient, client, ());
  return &client;
}

TestWebWidgetClient* defaultWebWidgetClient() {
  DEFINE_STATIC_LOCAL(TestWebWidgetClient, client, ());
  return &client;
}

TestWebViewClient* defaultWebViewClient() {
  DEFINE_STATIC_LOCAL(TestWebViewClient, client, ());
  return &client;
}

// |uniqueName| is normally calculated in a somewhat complicated way by the
// FrameTree class, but for test purposes the approximation below should be
// close enough.
String nameToUniqueName(const String& name) {
  static int uniqueNameCounter = 0;
  StringBuilder uniqueName;
  uniqueName.append(name);
  uniqueName.append(' ');
  uniqueName.appendNumber(uniqueNameCounter++);
  return uniqueName.toString();
}

}  // namespace

void loadFrame(WebFrame* frame, const std::string& url) {
  WebURLRequest urlRequest(URLTestHelpers::toKURL(url));
  frame->loadRequest(urlRequest);
  pumpPendingRequestsForFrameToLoad(frame);
}

void loadHTMLString(WebFrame* frame,
                    const std::string& html,
                    const WebURL& baseURL) {
  frame->loadHTMLString(WebData(html.data(), html.size()), baseURL);
  pumpPendingRequestsForFrameToLoad(frame);
}

void loadHistoryItem(WebFrame* frame,
                     const WebHistoryItem& item,
                     WebHistoryLoadType loadType,
                     WebCachePolicy cachePolicy) {
  WebURLRequest request =
      frame->toWebLocalFrame()->requestFromHistoryItem(item, cachePolicy);
  frame->toWebLocalFrame()->load(request, WebFrameLoadType::BackForward, item);
  pumpPendingRequestsForFrameToLoad(frame);
}

void reloadFrame(WebFrame* frame) {
  frame->reload(WebFrameLoadType::Reload);
  pumpPendingRequestsForFrameToLoad(frame);
}

void reloadFrameIgnoringCache(WebFrame* frame) {
  frame->reload(WebFrameLoadType::ReloadBypassingCache);
  pumpPendingRequestsForFrameToLoad(frame);
}

void pumpPendingRequestsForFrameToLoad(WebFrame* frame) {
  Platform::current()->currentThread()->getWebTaskRunner()->postTask(
      BLINK_FROM_HERE, WTF::bind(&runServeAsyncRequestsTask,
                                 WTF::unretained(testClientForFrame(frame))));
  testing::enterRunLoop();
}

WebMouseEvent createMouseEvent(WebInputEvent::Type type,
                               WebMouseEvent::Button button,
                               const IntPoint& point,
                               int modifiers) {
  WebMouseEvent result;
  result.type = type;
  result.x = result.windowX = result.globalX = point.x();
  result.y = result.windowX = result.globalX = point.y();
  result.modifiers = modifiers;
  result.button = button;
  result.clickCount = 1;
  return result;
}

WebLocalFrameImpl* createLocalChild(WebRemoteFrame* parent,
                                    const WebString& name,
                                    WebFrameClient* client,
                                    WebWidgetClient* widgetClient,
                                    WebFrame* previousSibling,
                                    const WebFrameOwnerProperties& properties) {
  if (!client)
    client = defaultWebFrameClient();

  WebLocalFrameImpl* frame = toWebLocalFrameImpl(parent->createLocalChild(
      WebTreeScopeType::Document, name, nameToUniqueName(name),
      WebSandboxFlags::None, client, previousSibling, properties, nullptr));

  if (!widgetClient)
    widgetClient = defaultWebWidgetClient();
  WebFrameWidget::create(widgetClient, frame);

  return frame;
}

WebRemoteFrameImpl* createRemoteChild(WebRemoteFrame* parent,
                                      WebRemoteFrameClient* client,
                                      const WebString& name) {
  return toWebRemoteFrameImpl(parent->createRemoteChild(
      WebTreeScopeType::Document, name, nameToUniqueName(name),
      WebSandboxFlags::None, client, nullptr));
}

WebViewHelper::WebViewHelper(SettingOverrider* settingOverrider)
    : m_webView(nullptr), m_settingOverrider(settingOverrider) {}

WebViewHelper::~WebViewHelper() {
  reset();
}

WebViewImpl* WebViewHelper::initializeWithOpener(
    WebFrame* opener,
    bool enableJavascript,
    TestWebFrameClient* webFrameClient,
    TestWebViewClient* webViewClient,
    TestWebWidgetClient* webWidgetClient,
    void (*updateSettingsFunc)(WebSettings*)) {
  reset();

  if (!webFrameClient)
    webFrameClient = defaultWebFrameClient();
  if (!webViewClient)
    webViewClient = defaultWebViewClient();
  if (!webWidgetClient)
    webWidgetClient = webViewClient->widgetClient();
  m_webView = WebViewImpl::create(webViewClient, WebPageVisibilityStateVisible);
  m_webView->settings()->setJavaScriptEnabled(enableJavascript);
  m_webView->settings()->setPluginsEnabled(true);
  // Enable (mocked) network loads of image URLs, as this simplifies
  // the completion of resource loads upon test shutdown & helps avoid
  // dormant loads trigger Resource leaks for image loads.
  //
  // Consequently, all external image resources must be mocked.
  m_webView->settings()->setLoadsImagesAutomatically(true);
  if (updateSettingsFunc)
    updateSettingsFunc(m_webView->settings());
  else
    m_webView->settings()->setDeviceSupportsMouse(false);
  if (m_settingOverrider)
    m_settingOverrider->overrideSettings(m_webView->settings());
  m_webView->setDeviceScaleFactor(
      webViewClient->screenInfo().deviceScaleFactor);
  m_webView->setDefaultPageScaleLimits(1, 4);
  WebLocalFrame* frame = WebLocalFrameImpl::create(WebTreeScopeType::Document,
                                                   webFrameClient, opener);
  m_webView->setMainFrame(frame);
  // TODO(dcheng): The main frame widget currently has a special case.
  // Eliminate this once WebView is no longer a WebWidget.
  blink::WebFrameWidget::create(webWidgetClient, m_webView, frame);

  m_testWebViewClient = webViewClient;

  return m_webView;
}

WebViewImpl* WebViewHelper::initialize(
    bool enableJavascript,
    TestWebFrameClient* webFrameClient,
    TestWebViewClient* webViewClient,
    TestWebWidgetClient* webWidgetClient,
    void (*updateSettingsFunc)(WebSettings*)) {
  return initializeWithOpener(nullptr, enableJavascript, webFrameClient,
                              webViewClient, webWidgetClient,
                              updateSettingsFunc);
}

WebViewImpl* WebViewHelper::initializeAndLoad(
    const std::string& url,
    bool enableJavascript,
    TestWebFrameClient* webFrameClient,
    TestWebViewClient* webViewClient,
    TestWebWidgetClient* webWidgetClient,
    void (*updateSettingsFunc)(WebSettings*)) {
  initialize(enableJavascript, webFrameClient, webViewClient, webWidgetClient,
             updateSettingsFunc);

  loadFrame(webView()->mainFrame(), url);

  return webView();
}

void WebViewHelper::reset() {
  if (m_webView) {
    DCHECK(m_webView->mainFrame()->isWebRemoteFrame() ||
           !testClientForFrame(m_webView->mainFrame())->isLoading());
    m_webView->willCloseLayerTreeView();
    m_webView->close();
    m_webView = nullptr;
  }
}

void WebViewHelper::resize(WebSize size) {
  m_testWebViewClient->clearAnimationScheduled();
  webView()->resize(size);
  EXPECT_FALSE(m_testWebViewClient->animationScheduled());
  m_testWebViewClient->clearAnimationScheduled();
}

TestWebFrameClient::TestWebFrameClient() {}

WebLocalFrame* TestWebFrameClient::createChildFrame(
    WebLocalFrame* parent,
    WebTreeScopeType scope,
    const WebString& name,
    const WebString& uniqueName,
    WebSandboxFlags sandboxFlags,
    const WebFrameOwnerProperties& frameOwnerProperties) {
  WebLocalFrame* frame = WebLocalFrame::create(scope, this);
  parent->appendChild(frame);
  return frame;
}

void TestWebFrameClient::didStartLoading(bool) {
  ++m_loadsInProgress;
}

void TestWebFrameClient::didStopLoading() {
  DCHECK_GT(m_loadsInProgress, 0);
  --m_loadsInProgress;
}

TestWebRemoteFrameClient::TestWebRemoteFrameClient()
    : m_frame(WebRemoteFrameImpl::create(WebTreeScopeType::Document,
                                         this,
                                         nullptr)) {}

void TestWebRemoteFrameClient::frameDetached(DetachType type) {
  if (type == DetachType::Remove && m_frame->parent())
    m_frame->parent()->removeChild(m_frame);
  m_frame->close();
}

void TestWebViewClient::initializeLayerTreeView() {
  m_layerTreeView = wrapUnique(new WebLayerTreeViewImplForTesting);
}

void TestWebViewWidgetClient::initializeLayerTreeView() {
  m_testWebViewClient->initializeLayerTreeView();
}

WebLayerTreeView* TestWebViewWidgetClient::layerTreeView() {
  return m_testWebViewClient->layerTreeView();
}

void TestWebViewWidgetClient::scheduleAnimation() {
  m_testWebViewClient->scheduleAnimation();
}

void TestWebViewWidgetClient::didMeaningfulLayout(
    WebMeaningfulLayout layoutType) {
  m_testWebViewClient->didMeaningfulLayout(layoutType);
}

}  // namespace FrameTestHelpers
}  // namespace blink
