// Copyright 2020 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/browser/prerender/prerender_host.h"

#include "base/test/scoped_feature_list.h"
#include "build/build_config.h"
#include "content/browser/prerender/prerender_attributes.h"
#include "content/browser/prerender/prerender_host_registry.h"
#include "content/browser/site_instance_impl.h"
#include "content/public/test/mock_web_contents_observer.h"
#include "content/public/test/navigation_simulator.h"
#include "content/public/test/test_browser_context.h"
#include "content/test/mock_commit_deferring_condition.h"
#include "content/test/navigation_simulator_impl.h"
#include "content/test/test_render_frame_host.h"
#include "content/test/test_render_view_host.h"
#include "content/test/test_web_contents.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/common/features.h"
#include "third_party/blink/public/common/loader/loader_constants.h"

namespace content {
namespace {

using ::testing::_;

// TODO(nhiroki): Merge this into TestNavigationObserver for code
// simplification.
class ActivationObserver : public PrerenderHost::Observer {
 public:
  // PrerenderHost::Observer implementations.
  void OnActivated() override { was_activated_ = true; }
  void OnHostDestroyed() override {
    was_host_destroyed_ = true;
    if (quit_closure_) {
      base::SequencedTaskRunnerHandle::Get()->PostTask(
          FROM_HERE, std::move(quit_closure_));
    }
  }

  void WaitUntilHostDestroyed() {
    if (was_host_destroyed_)
      return;
    base::RunLoop run_loop;
    quit_closure_ = run_loop.QuitClosure();
    run_loop.Run();
  }

  bool was_activated() const { return was_activated_; }

 private:
  base::OnceClosure quit_closure_;
  bool was_activated_ = false;
  bool was_host_destroyed_ = false;
};

// Finish a prerendering navigation that was already started with
// CreateAndStartHost().
void CommitPrerenderNavigation(PrerenderHost& host) {
  // Normally we could use EmbeddedTestServer to provide a response, but these
  // tests use RenderViewHostImplTestHarness so the load goes through a
  // TestNavigationURLLoader which we don't have access to in order to
  // complete. Use NavigationSimulator to finish the navigation.
  FrameTreeNode* ftn = FrameTreeNode::From(host.GetPrerenderedMainFrameHost());
  std::unique_ptr<NavigationSimulator> sim =
      NavigationSimulatorImpl::CreateFromPendingInFrame(ftn);
  sim->Commit();
  EXPECT_TRUE(host.is_ready_for_activation());
}

std::unique_ptr<NavigationSimulatorImpl> CreateActivation(
    const GURL& prerendering_url,
    WebContentsImpl& web_contents) {
  std::unique_ptr<NavigationSimulatorImpl> navigation =
      NavigationSimulatorImpl::CreateRendererInitiated(
          prerendering_url, web_contents.GetMainFrame());
  navigation->SetReferrer(blink::mojom::Referrer::New(
      web_contents.GetMainFrame()->GetLastCommittedURL(),
      network::mojom::ReferrerPolicy::kStrictOriginWhenCrossOrigin));
  return navigation;
}

void ActivatePrerenderedPage(const GURL& prerendering_url,
                             WebContentsImpl& web_contents) {
  // Make sure the page for `prerendering_url` has been prerendered.
  PrerenderHostRegistry* registry = web_contents.GetPrerenderHostRegistry();
  PrerenderHost* prerender_host =
      registry->FindHostByUrlForTesting(prerendering_url);
  EXPECT_TRUE(prerender_host);
  int prerender_host_id = prerender_host->frame_tree_node_id();

  ActivationObserver activation_observer;
  prerender_host->AddObserver(&activation_observer);

  // Activate the prerendered page.
  std::unique_ptr<NavigationSimulatorImpl> navigation =
      CreateActivation(prerendering_url, web_contents);
  navigation->Commit();
  activation_observer.WaitUntilHostDestroyed();

  EXPECT_EQ(web_contents.GetMainFrame()->GetLastCommittedURL(),
            prerendering_url);

  EXPECT_TRUE(activation_observer.was_activated());
  EXPECT_EQ(registry->FindReservedHostById(prerender_host_id), nullptr);
}

PrerenderAttributes GeneratePrerenderAttributes(const GURL& url,
                                                RenderFrameHostImpl* rfh) {
  return PrerenderAttributes(
      url, PrerenderTriggerType::kSpeculationRule,
      /*embedder_histogram_suffix=*/"", Referrer(),
      rfh->GetLastCommittedOrigin(), rfh->GetLastCommittedURL(),
      rfh->GetProcess()->GetID(), rfh->GetFrameToken(),
      rfh->GetPageUkmSourceId(), ui::PAGE_TRANSITION_LINK);
}

class TestWebContentsDelegate : public WebContentsDelegate {
 public:
  TestWebContentsDelegate() = default;
  ~TestWebContentsDelegate() override = default;
  bool IsPrerender2Supported() override { return true; }
};

class PrerenderHostTest : public RenderViewHostImplTestHarness {
 public:
  PrerenderHostTest() {
    scoped_feature_list_.InitWithFeatures(
        {blink::features::kPrerender2},
        // Disable the memory requirement of Prerender2 so the test can run on
        // any bot.
        {blink::features::kPrerender2MemoryControls});
  }

  ~PrerenderHostTest() override = default;

  void SetUp() override {
    RenderViewHostImplTestHarness::SetUp();
    browser_context_ = std::make_unique<TestBrowserContext>();
  }

  void TearDown() override {
    browser_context_.reset();
    RenderViewHostImplTestHarness::TearDown();
  }

  void ExpectFinalStatus(PrerenderHost::FinalStatus status) {
    histogram_tester_.ExpectUniqueSample(
        "Prerender.Experimental.PrerenderHostFinalStatus", status, 1);
  }

  std::unique_ptr<TestWebContents> CreateWebContents(const GURL& url) {
    std::unique_ptr<TestWebContents> web_contents(TestWebContents::Create(
        browser_context_.get(),
        SiteInstanceImpl::Create(browser_context_.get())));
    web_contents_delegate_ = std::make_unique<TestWebContentsDelegate>();
    web_contents->SetDelegate(web_contents_delegate_.get());
    web_contents->NavigateAndCommit(url);
    return web_contents;
  }

 private:
  base::test::ScopedFeatureList scoped_feature_list_;

  std::unique_ptr<TestBrowserContext> browser_context_;
  std::unique_ptr<TestWebContentsDelegate> web_contents_delegate_;
  base::HistogramTester histogram_tester_;
};

TEST_F(PrerenderHostTest, Activate) {
  const GURL kOriginUrl("https://example.com/");
  std::unique_ptr<TestWebContents> web_contents = CreateWebContents(kOriginUrl);
  PrerenderHostRegistry* registry = web_contents->GetPrerenderHostRegistry();

  // Start prerendering a page.
  const GURL kPrerenderingUrl("https://example.com/next");
  int prerender_frame_tree_node_id =
      web_contents->AddPrerender(kPrerenderingUrl);
  PrerenderHost* prerender_host =
      registry->FindNonReservedHostById(prerender_frame_tree_node_id);
  CommitPrerenderNavigation(*prerender_host);

  // Perform a navigation in the primary frame tree which activates the
  // prerendered page.
  ActivatePrerenderedPage(kPrerenderingUrl, *web_contents);
  ExpectFinalStatus(PrerenderHost::FinalStatus::kActivated);
}

TEST_F(PrerenderHostTest, DontActivate) {
  std::unique_ptr<TestWebContents> web_contents =
      CreateWebContents(GURL("https://example.com/"));
  PrerenderHostRegistry* registry = web_contents->GetPrerenderHostRegistry();
  const GURL kPrerenderingUrl("https://example.com/next");

  // Start the prerendering navigation, but don't activate it.
  const int prerender_frame_tree_node_id =
      web_contents->AddPrerender(kPrerenderingUrl);
  registry->CancelHost(prerender_frame_tree_node_id,
                       PrerenderHost::FinalStatus::kDestroyed);
  ExpectFinalStatus(PrerenderHost::FinalStatus::kDestroyed);
}

// Tests that main frame navigations in a prerendered page cannot occur even if
// they start after the prerendered page has been reserved for activation.
TEST_F(PrerenderHostTest, MainFrameNavigationForReservedHost) {
  const GURL kOriginUrl("https://example.com/");
  std::unique_ptr<TestWebContents> web_contents = CreateWebContents(kOriginUrl);
  PrerenderHostRegistry* registry = web_contents->GetPrerenderHostRegistry();

  // Start prerendering a page.
  const GURL kPrerenderingUrl("https://example.com/next");
  RenderFrameHostImpl* prerender_rfh =
      web_contents->AddPrerenderAndCommitNavigation(kPrerenderingUrl);
  const int prerender_ftn_id = prerender_rfh->GetFrameTreeNodeId();
  PrerenderHost* prerender_host =
      registry->FindNonReservedHostById(prerender_ftn_id);
  FrameTreeNode* ftn = prerender_rfh->frame_tree_node();
  EXPECT_FALSE(ftn->HasNavigation());

  ActivationObserver activation_observer;
  prerender_host->AddObserver(&activation_observer);

  // Now navigate the primary page to the prerendered URL so that we activate
  // the prerender. Use a CommitDeferringCondition to pause activation
  // before it completes.
  std::unique_ptr<NavigationSimulatorImpl> navigation;
  MockCommitDeferringConditionWrapper condition(/*is_ready_to_commit=*/false);
  {
    MockCommitDeferringConditionInstaller installer(condition.PassToDelegate());

    // Start trying to activate the prerendered page.
    navigation = CreateActivation(kPrerenderingUrl, *web_contents);
    navigation->Start();

    // Wait for the condition to pause the activation.
    condition.WaitUntilInvoked();
  }

  // The request should be deferred by the condition.
  NavigationRequest* navigation_request =
      static_cast<NavigationRequest*>(navigation->GetNavigationHandle());
  EXPECT_TRUE(
      navigation_request->IsCommitDeferringConditionDeferredForTesting());

  // The primary page should still be the original page.
  EXPECT_EQ(web_contents->GetLastCommittedURL(), kOriginUrl);

  const GURL kBadUrl("https://example2.test/");
  TestNavigationManager tno(web_contents.get(), kBadUrl);

  // Start a cross-origin navigation in the prerendered page. It should be
  // cancelled.
  auto navigation_2 =
      NavigationSimulatorImpl::CreateRendererInitiated(kBadUrl, prerender_rfh);
  navigation_2->Start();
  EXPECT_EQ(NavigationThrottle::CANCEL,
            navigation_2->GetLastThrottleCheckResult());
  tno.WaitForNavigationFinished();
  EXPECT_FALSE(tno.was_committed());

  // The cross-origin navigation cancels the activation.
  condition.CallResumeClosure();
  activation_observer.WaitUntilHostDestroyed();
  EXPECT_FALSE(activation_observer.was_activated());
  EXPECT_EQ(registry->FindHostByUrlForTesting(kPrerenderingUrl), nullptr);
  ExpectFinalStatus(PrerenderHost::FinalStatus::kMainFrameNavigation);

  // The activation falls back to regular navigation.
  navigation->Commit();
  EXPECT_EQ(web_contents->GetMainFrame()->GetLastCommittedURL(),
            kPrerenderingUrl);
}

// Tests that an activation can successfully commit after the prerendering page
// has updated its PageState.
TEST_F(PrerenderHostTest, ActivationAfterPageStateUpdate) {
  std::unique_ptr<TestWebContents> web_contents =
      CreateWebContents(GURL("https://example.com/"));
  RenderFrameHostImpl* initiator_rfh = web_contents->GetMainFrame();
  PrerenderHostRegistry* registry = web_contents->GetPrerenderHostRegistry();

  // Start prerendering a page.
  const GURL kPrerenderingUrl("https://example.com/next");
  const int prerender_frame_tree_node_id = registry->CreateAndStartHost(
      GeneratePrerenderAttributes(kPrerenderingUrl, initiator_rfh),
      *web_contents);
  PrerenderHost* prerender_host =
      registry->FindNonReservedHostById(prerender_frame_tree_node_id);
  CommitPrerenderNavigation(*prerender_host);

  FrameTreeNode* prerender_root_ftn =
      FrameTreeNode::GloballyFindByID(prerender_frame_tree_node_id);
  RenderFrameHostImpl* prerender_rfh = prerender_root_ftn->current_frame_host();
  NavigationEntryImpl* prerender_nav_entry =
      prerender_root_ftn->frame_tree()->controller().GetLastCommittedEntry();
  FrameNavigationEntry* prerender_root_fne =
      prerender_nav_entry->GetFrameEntry(prerender_root_ftn);

  blink::PageState page_state =
      blink::PageState::CreateForTestingWithSequenceNumbers(
          GURL("about:blank"), prerender_root_fne->item_sequence_number(),
          prerender_root_fne->document_sequence_number());

  // Update PageState for prerender RFH, causing it to become different from
  // the one stored in RFH's last commit params.
  static_cast<mojom::FrameHost*>(prerender_rfh)->UpdateState(page_state);

  // Perform a navigation in the primary frame tree which activates the
  // prerendered page. The main expectation is that this navigation commits
  // successfully and doesn't hit any DCHECKs.
  ActivatePrerenderedPage(kPrerenderingUrl, *web_contents);
  ExpectFinalStatus(PrerenderHost::FinalStatus::kActivated);

  // Ensure that the the page_state was preserved.
  EXPECT_EQ(web_contents->GetMainFrame(), prerender_rfh);
  NavigationEntryImpl* activated_nav_entry =
      web_contents->GetController().GetLastCommittedEntry();
  EXPECT_EQ(page_state,
            activated_nav_entry
                ->GetFrameEntry(web_contents->GetPrimaryFrameTree().root())
                ->page_state());
}

// Test that WebContentsObserver::LoadProgressChanged is not invoked when the
// page gets loaded while prerendering but is invoked on prerender activation.
// Check that in case the load is incomplete with load progress
// `kPartialLoadProgress`, we would see
// LoadProgressChanged(kPartialLoadProgress) called on activation.
TEST_F(PrerenderHostTest, LoadProgressChangedInvokedOnActivation) {
  const GURL kOriginUrl("https://example.com/");
  std::unique_ptr<TestWebContents> web_contents = CreateWebContents(kOriginUrl);
  WebContentsImpl* web_contents_impl =
      static_cast<WebContentsImpl*>(web_contents.get());

  web_contents_impl->set_minimum_delay_between_loading_updates_for_testing(
      base::Milliseconds(0));

  // Initialize a MockWebContentsObserver and ensure that LoadProgressChanged is
  // not invoked while prerendering.
  testing::NiceMock<MockWebContentsObserver> observer(web_contents_impl);
  testing::InSequence s;
  EXPECT_CALL(observer, LoadProgressChanged(testing::_)).Times(0);

  // Start prerendering a page and commit prerender navigation.
  const GURL kPrerenderingUrl("https://example.com/next");
  constexpr double kPartialLoadProgress = 0.7;
  RenderFrameHostImpl* prerender_rfh =
      web_contents->AddPrerenderAndCommitNavigation(kPrerenderingUrl);
  FrameTreeNode* ftn = prerender_rfh->frame_tree_node();
  EXPECT_FALSE(ftn->HasNavigation());

  // Verify and clear all expectations on the mock observer before setting new
  // ones.
  testing::Mock::VerifyAndClearExpectations(&observer);

  // Activate the prerendered page. This should result in invoking
  // LoadProgressChanged for the following cases:
  {
    // 1) During DidStartLoading LoadProgressChanged is invoked with
    // kInitialLoadProgress value.
    EXPECT_CALL(observer, LoadProgressChanged(blink::kInitialLoadProgress));

    // Verify that DidFinishNavigation is invoked before final load progress
    // notification.
    EXPECT_CALL(observer, DidFinishNavigation(testing::_));

    // 2) After DidCommitNavigationInternal on activation with
    // LoadProgressChanged is invoked with kPartialLoadProgress value.
    EXPECT_CALL(observer, LoadProgressChanged(kPartialLoadProgress));

    // 3) During DidStopLoading LoadProgressChanged is invoked with
    // kFinalLoadProgress.
    EXPECT_CALL(observer, LoadProgressChanged(blink::kFinalLoadProgress));
  }

  // Set load_progress value to kPartialLoadProgress in prerendering state,
  // this should result in invoking LoadProgressChanged(kPartialLoadProgress) on
  // activation.
  prerender_rfh->GetPage().set_load_progress(kPartialLoadProgress);

  // Perform a navigation in the primary frame tree which activates the
  // prerendered page.
  ActivatePrerenderedPage(kPrerenderingUrl, *web_contents);
  ExpectFinalStatus(PrerenderHost::FinalStatus::kActivated);
}

TEST_F(PrerenderHostTest, CancelPrerenderWhenTriggerGetsHidden) {
  std::unique_ptr<TestWebContents> web_contents =
      CreateWebContents(GURL("https://example.com/"));
  const GURL kPrerenderingUrl = GURL("https://example.com/empty.html");
  RenderFrameHostImpl* initiator_rfh = web_contents->GetMainFrame();
  PrerenderHostRegistry* registry = web_contents->GetPrerenderHostRegistry();
  const int prerender_frame_tree_node_id = registry->CreateAndStartHost(
      GeneratePrerenderAttributes(kPrerenderingUrl, initiator_rfh),
      *web_contents);
  PrerenderHost* prerender_host =
      registry->FindNonReservedHostById(prerender_frame_tree_node_id);
  ASSERT_NE(prerender_host, nullptr);
  CommitPrerenderNavigation(*prerender_host);

  // Changing the visibility state to HIDDEN will cause prerendering cancelled.
  web_contents->WasHidden();
  ExpectFinalStatus(PrerenderHost::FinalStatus::kTriggerBackgrounded);
}

TEST_F(PrerenderHostTest, DontCancelPrerenderWhenTriggerGetsVisible) {
  std::unique_ptr<TestWebContents> web_contents =
      CreateWebContents(GURL("https://example.com/"));
  const GURL kPrerenderingUrl = GURL("https://example.com/empty.html");
  RenderFrameHostImpl* initiator_rfh = web_contents->GetMainFrame();
  PrerenderHostRegistry* registry = web_contents->GetPrerenderHostRegistry();
  const int prerender_frame_tree_node_id = registry->CreateAndStartHost(
      GeneratePrerenderAttributes(kPrerenderingUrl, initiator_rfh),
      *web_contents);
  PrerenderHost* prerender_host =
      registry->FindNonReservedHostById(prerender_frame_tree_node_id);
  ASSERT_NE(prerender_host, nullptr);
  CommitPrerenderNavigation(*prerender_host);

  // Changing the visibility state to VISIBLE will not affect prerendering.
  web_contents->WasShown();
  ActivatePrerenderedPage(kPrerenderingUrl, *web_contents);
  ExpectFinalStatus(PrerenderHost::FinalStatus::kActivated);
}

// Skip this test on Android as it doesn't support the OCCLUDED state.
#if !defined(OS_ANDROID)
TEST_F(PrerenderHostTest, DontCancelPrerenderWhenTriggerGetsOcculded) {
  std::unique_ptr<TestWebContents> web_contents =
      CreateWebContents(GURL("https://example.com/"));
  const GURL kPrerenderingUrl = GURL("https://example.com/empty.html");
  RenderFrameHostImpl* initiator_rfh = web_contents->GetMainFrame();
  PrerenderHostRegistry* registry = web_contents->GetPrerenderHostRegistry();
  const int prerender_frame_tree_node_id = registry->CreateAndStartHost(
      GeneratePrerenderAttributes(kPrerenderingUrl, initiator_rfh),
      *web_contents);
  PrerenderHost* prerender_host =
      registry->FindNonReservedHostById(prerender_frame_tree_node_id);
  ASSERT_NE(prerender_host, nullptr);
  CommitPrerenderNavigation(*prerender_host);

  // Changing the visibility state to OCCLUDED will not affect prerendering.
  web_contents->WasOccluded();
  ActivatePrerenderedPage(kPrerenderingUrl, *web_contents);
  ExpectFinalStatus(PrerenderHost::FinalStatus::kActivated);
}
#endif

}  // namespace
}  // namespace content
