// Copyright 2015 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 "content/test/test_render_frame.h"

#include <string>
#include <utility>
#include <vector>

#include "base/debug/stack_trace.h"
#include "base/threading/thread_task_runner_handle.h"
#include "build/build_config.h"
#include "content/common/frame_messages.h"
#include "content/common/navigation_params.h"
#include "content/common/navigation_params.mojom.h"
#include "content/public/test/mock_render_thread.h"
#include "content/renderer/input/frame_input_handler_impl.h"
#include "content/renderer/loader/web_url_loader_impl.h"
#include "services/network/public/cpp/resource_response.h"
#include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h"
#include "third_party/blink/public/web/web_local_frame.h"
#include "third_party/blink/public/web/web_navigation_control.h"

namespace content {

class MockFrameHost : public mojom::FrameHost {
 public:
  MockFrameHost() {}
  ~MockFrameHost() override = default;

  std::unique_ptr<FrameHostMsg_DidCommitProvisionalLoad_Params>
  TakeLastCommitParams() {
    return std::move(last_commit_params_);
  }

  service_manager::mojom::InterfaceProviderRequest
  TakeLastInterfaceProviderRequest() {
    return std::move(last_interface_provider_request_);
  }

  // Holds on to the request end of the InterfaceProvider interface whose client
  // end is bound to the corresponding RenderFrame's |remote_interfaces_| to
  // facilitate retrieving the most recent |interface_provider_request| in
  // tests.
  void PassLastInterfaceProviderRequest(
      service_manager::mojom::InterfaceProviderRequest
          interface_provider_request) {
    last_interface_provider_request_ = std::move(interface_provider_request);
  }

 protected:
  // mojom::FrameHost:
  void CreateNewWindow(mojom::CreateNewWindowParamsPtr,
                       CreateNewWindowCallback) override {
    NOTREACHED() << "We should never dispatch to the service side signature.";
  }

  bool CreateNewWindow(mojom::CreateNewWindowParamsPtr params,
                       mojom::CreateNewWindowStatus* status,
                       mojom::CreateNewWindowReplyPtr* reply) override {
    *status = mojom::CreateNewWindowStatus::kSuccess;
    *reply = mojom::CreateNewWindowReply::New();
    MockRenderThread* mock_render_thread =
        static_cast<MockRenderThread*>(RenderThread::Get());
    mock_render_thread->OnCreateWindow(*params, reply->get());
    return true;
  }

  void CreatePortal(blink::mojom::PortalRequest request,
                    CreatePortalCallback callback) override {
    std::move(callback).Run(MSG_ROUTING_NONE, base::UnguessableToken());
  }

  void IssueKeepAliveHandle(mojom::KeepAliveHandleRequest request) override {}

  void DidCommitProvisionalLoad(
      std::unique_ptr<FrameHostMsg_DidCommitProvisionalLoad_Params> params,
      service_manager::mojom::InterfaceProviderRequest request) override {
    last_commit_params_ = std::move(params);
    last_interface_provider_request_ = std::move(request);
  }

  void DidCommitSameDocumentNavigation(
      std::unique_ptr<FrameHostMsg_DidCommitProvisionalLoad_Params> params)
      override {
    last_commit_params_ = std::move(params);
  }

  void BeginNavigation(const CommonNavigationParams& common_params,
                       mojom::BeginNavigationParamsPtr begin_params,
                       blink::mojom::BlobURLTokenPtr blob_url_token,
                       mojom::NavigationClientAssociatedPtrInfo,
                       blink::mojom::NavigationInitiatorPtr) override {}

  void SubresourceResponseStarted(const GURL& url,
                                  net::CertStatus cert_status) override {}

  void ResourceLoadComplete(
      mojom::ResourceLoadInfoPtr resource_load_info) override {}

  void DidChangeName(const std::string& name,
                     const std::string& unique_name) override {}

  void EnforceInsecureRequestPolicy(
      blink::WebInsecureRequestPolicy policy) override {}
  void EnforceInsecureNavigationsSet(
      const std::vector<uint32_t>& set) override {}

  void DidSetFramePolicyHeaders(
      blink::WebSandboxFlags sandbox_flags,
      const blink::ParsedFeaturePolicy& parsed_header) override {}

  void CancelInitialHistoryLoad() override {}

  void UpdateEncoding(const std::string& encoding_name) override {}

  void FrameSizeChanged(const gfx::Size& frame_size) override {}

  void FullscreenStateChanged(bool is_fullscreen) override {}

#if defined(OS_ANDROID)
  void UpdateUserGestureCarryoverInfo() override {}
#endif

 private:
  std::unique_ptr<FrameHostMsg_DidCommitProvisionalLoad_Params>
      last_commit_params_;
  service_manager::mojom::InterfaceProviderRequest
      last_interface_provider_request_;

  DISALLOW_COPY_AND_ASSIGN(MockFrameHost);
};

// static
RenderFrameImpl* TestRenderFrame::CreateTestRenderFrame(
    RenderFrameImpl::CreateParams params) {
  return new TestRenderFrame(std::move(params));
}

TestRenderFrame::TestRenderFrame(RenderFrameImpl::CreateParams params)
    : RenderFrameImpl(std::move(params)),
      mock_frame_host_(std::make_unique<MockFrameHost>()) {
  MockRenderThread* mock_render_thread =
      static_cast<MockRenderThread*>(RenderThread::Get());
  mock_frame_host_->PassLastInterfaceProviderRequest(
      mock_render_thread->TakeInitialInterfaceProviderRequestForFrame(
          params.routing_id));
}

TestRenderFrame::~TestRenderFrame() {}

void TestRenderFrame::SetURLOverrideForNextWebURLRequest(const GURL& url) {
  next_request_url_override_ = url;
}

void TestRenderFrame::WillSendRequest(blink::WebURLRequest& request) {
  if (next_request_url_override_.has_value())
    request.SetURL(std::move(next_request_url_override_).value());
  RenderFrameImpl::WillSendRequest(request);
}

void TestRenderFrame::Navigate(const network::ResourceResponseHead& head,
                               const CommonNavigationParams& common_params,
                               const RequestNavigationParams& request_params) {
  CommitNavigation(
      head, common_params, request_params,
      network::mojom::URLLoaderClientEndpointsPtr(),
      std::make_unique<blink::URLLoaderFactoryBundleInfo>(), base::nullopt,
      blink::mojom::ControllerServiceWorkerInfoPtr(),
      network::mojom::URLLoaderFactoryPtr(), base::UnguessableToken::Create(),
      CommitNavigationCallback());
}

void TestRenderFrame::Navigate(const CommonNavigationParams& common_params,
                               const RequestNavigationParams& request_params) {
  Navigate(network::ResourceResponseHead(), common_params, request_params);
}

void TestRenderFrame::SwapOut(
    int proxy_routing_id,
    bool is_loading,
    const FrameReplicationState& replicated_frame_state) {
  OnSwapOut(proxy_routing_id, is_loading, replicated_frame_state);
}

void TestRenderFrame::SetEditableSelectionOffsets(int start, int end) {
  GetFrameInputHandler()->SetEditableSelectionOffsets(start, end);
}

void TestRenderFrame::ExtendSelectionAndDelete(int before, int after) {
  GetFrameInputHandler()->ExtendSelectionAndDelete(before, after);
}

void TestRenderFrame::DeleteSurroundingText(int before, int after) {
  GetFrameInputHandler()->DeleteSurroundingText(before, after);
}

void TestRenderFrame::DeleteSurroundingTextInCodePoints(int before, int after) {
  GetFrameInputHandler()->DeleteSurroundingTextInCodePoints(before, after);
}

void TestRenderFrame::CollapseSelection() {
  GetFrameInputHandler()->CollapseSelection();
}

void TestRenderFrame::SetAccessibilityMode(ui::AXMode new_mode) {
  OnSetAccessibilityMode(new_mode);
}

void TestRenderFrame::SetCompositionFromExistingText(
    int start,
    int end,
    const std::vector<ui::ImeTextSpan>& ime_text_spans) {
  GetFrameInputHandler()->SetCompositionFromExistingText(start, end,
                                                         ime_text_spans);
}

void TestRenderFrame::BeginNavigation(
    std::unique_ptr<blink::WebNavigationInfo> info) {
  if (info->navigation_policy == blink::kWebNavigationPolicyCurrentTab &&
      ((GetWebFrame()->Parent() && info->form.IsNull()) ||
       next_request_url_override_.has_value())) {
    // RenderViewTest::LoadHTML immediately commits navigation for the main
    // frame. However if the loaded html has a subframe,
    // BeginNavigation will be called from Blink and we should avoid
    // going through browser process in this case.
    frame_->CommitNavigation(blink::WebNavigationParams::CreateFromInfo(*info),
                             nullptr /* extra_data */);
    return;
  }
  RenderFrameImpl::BeginNavigation(std::move(info));
}

std::unique_ptr<FrameHostMsg_DidCommitProvisionalLoad_Params>
TestRenderFrame::TakeLastCommitParams() {
  return mock_frame_host_->TakeLastCommitParams();
}

service_manager::mojom::InterfaceProviderRequest
TestRenderFrame::TakeLastInterfaceProviderRequest() {
  return mock_frame_host_->TakeLastInterfaceProviderRequest();
}

mojom::FrameHost* TestRenderFrame::GetFrameHost() {
  // Need to mock this interface directly without going through a binding,
  // otherwise calling its sync methods could lead to a deadlock.
  //
  // Imagine the following sequence of events take place:
  //
  //   1.) GetFrameHost() called for the first time
  //   1.1.) GetRemoteAssociatedInterfaces()->GetInterface(&frame_host_ptr_)
  //   1.1.1) ... plumbing ...
  //   1.1.2) Task posted to bind the request end to the Mock implementation
  //   1.2) The interface pointer end is returned to the caller
  //   2.) GetFrameHost()->CreateNewWindow(...) sync method invoked
  //   2.1.) Mojo sync request sent
  //   2.2.) Waiting for sync response while dispatching incoming sync requests
  //
  // Normally the sync Mojo request would be processed in 2.2. However, the
  // implementation is not yet bound at that point, and will never be, because
  // only sync IPCs are dispatched by 2.2, not posted tasks. So the sync request
  // is never dispatched, the response never arrives.
  //
  // Because the first invocation to GetFrameHost() may come while we are inside
  // a message loop already, pumping messags before 1.2 would constitute a
  // nested message loop and is therefore undesired.
  return mock_frame_host_.get();
}

mojom::FrameInputHandler* TestRenderFrame::GetFrameInputHandler() {
  if (!frame_input_handler_) {
    mojom::FrameInputHandlerRequest frame_input_handler_request =
        mojo::MakeRequest(&frame_input_handler_);
    FrameInputHandlerImpl::CreateMojoService(
        weak_factory_.GetWeakPtr(), std::move(frame_input_handler_request));
  }
  return frame_input_handler_.get();
}

}  // namespace content
