// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/barrier_closure.h"
#include "base/files/file_path.h"
#include "base/functional/bind.h"
#include "base/path_service.h"
#include "base/test/metrics/histogram_tester.h"
#include "chrome/browser/chrome_content_browser_client.h"
#include "chrome/browser/preloading/preview/preview_manager.h"
#include "chrome/browser/preloading/preview/preview_test_util.h"
#include "chrome/browser/preloading/preview/preview_zoom_controller.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/test/base/chrome_test_utils.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "chrome/test/base/ui_test_utils.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/common/content_client.h"
#include "content/public/test/browser_test.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/mojo_capability_control_test_util.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "mojo/public/cpp/bindings/remote_set.h"
#include "net/dns/mock_host_resolver.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/common/navigation/preloading_headers.h"

class PreviewBrowserTest : public InProcessBrowserTest {
 public:
  PreviewBrowserTest()
      : helper_(std::make_unique<test::PreviewTestHelper>(
            base::BindRepeating(&PreviewBrowserTest::web_contents,
                                base::Unretained(this)))) {}

  void SetUp() override { InProcessBrowserTest::SetUp(); }

  void SetUpOnMainThread() override {
    https_server_ = std::make_unique<net::EmbeddedTestServer>(
        net::EmbeddedTestServer::TYPE_HTTPS);

    embedded_test_server()->RegisterRequestMonitor(base::BindRepeating(
        &PreviewBrowserTest::MonitorResourceRequest, base::Unretained(this)));
    https_server_->RegisterRequestMonitor(base::BindRepeating(
        &PreviewBrowserTest::MonitorResourceRequest, base::Unretained(this)));
    histogram_tester_ = std::make_unique<base::HistogramTester>();

    host_resolver()->AddRule("*", "127.0.0.1");

    embedded_test_server()->AddDefaultHandlers(GetChromeTestDataDir());
    ASSERT_TRUE(embedded_test_server()->Start());

    https_server_->SetSSLConfig(
        net::test_server::EmbeddedTestServer::CERT_TEST_NAMES);
    https_server_->AddDefaultHandlers(GetChromeTestDataDir());
    ASSERT_TRUE(https_server_->Start());
  }

  void TearDownOnMainThread() override {
    ASSERT_TRUE(embedded_test_server()->ShutdownAndWaitUntilComplete());
    ASSERT_TRUE(https_server_->ShutdownAndWaitUntilComplete());
  }

  GURL GetURL(const std::string& path) {
    return https_server_->GetURL("a.test", path);
  }

  net::test_server::HttpRequest::HeaderMap GetObservedRequestHeadersFor(
      const GURL& url) {
    base::AutoLock auto_lock(lock_);
    std::string path = url.PathForRequest();
    return request_headers_by_path_[path];
  }

  net::EmbeddedTestServer& https_server() { return *https_server_.get(); }

  content::WebContents* web_contents() {
    return chrome_test_utils::GetActiveWebContents(this);
  }

  test::PreviewTestHelper& helper() { return *helper_.get(); }
  base::HistogramTester& histogram_tester() { return *histogram_tester_.get(); }

 private:
  void MonitorResourceRequest(const net::test_server::HttpRequest& request) {
    ASSERT_FALSE(
        content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
    base::AutoLock auto_lock(lock_);
    request_headers_by_path_.emplace(request.GetURL().PathForRequest(),
                                     request.headers);
  }

  std::unique_ptr<net::EmbeddedTestServer> https_server_;

  base::Lock lock_;
  std::map<std::string, net::test_server::HttpRequest::HeaderMap>
      request_headers_by_path_ GUARDED_BY(lock_);

  std::unique_ptr<test::PreviewTestHelper> helper_;
  std::unique_ptr<base::HistogramTester> histogram_tester_;
};

IN_PROC_BROWSER_TEST_F(PreviewBrowserTest, SecPurposeHeader) {
  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), GetURL("/title1.html")));

  GURL preview_url = GetURL("/title2.html");
  helper().InitiatePreview(preview_url);
  helper().WaitUntilLoadFinished();

  net::test_server::HttpRequest::HeaderMap headers =
      GetObservedRequestHeadersFor(preview_url);
  auto it = headers.find(blink::kSecPurposeHeaderName);
  ASSERT_NE(it, headers.end());
  EXPECT_EQ(it->second, blink::kSecPurposePrefetchPrerenderPreviewHeaderValue);
}

IN_PROC_BROWSER_TEST_F(PreviewBrowserTest, CancelWhenPrimaryPageChanged) {
  TabStripModel* tab_strip_model = browser()->tab_strip_model();

  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), GetURL("/title1.html")));

  helper().InitiatePreview(GetURL("/title2.html"));
  helper().WaitUntilLoadFinished();

  base::WeakPtr<content::WebContents> preview_web_contents =
      helper().GetWebContentsForPreviewTab();
  ASSERT_TRUE(preview_web_contents);

  EXPECT_EQ(1, tab_strip_model->count());
  EXPECT_EQ(true,
            content::EvalJs(preview_web_contents, "document.prerendering"));

  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), GetURL("/title1.html")));

  ASSERT_FALSE(preview_web_contents);
}

IN_PROC_BROWSER_TEST_F(PreviewBrowserTest, PromoteToNewTab) {
  TabStripModel* tab_strip_model = browser()->tab_strip_model();

  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), GetURL("/title1.html")));

  helper().InitiatePreview(GetURL("/title2.html"));
  helper().WaitUntilLoadFinished();

  base::WeakPtr<content::WebContents> preview_web_contents =
      helper().GetWebContentsForPreviewTab();
  ASSERT_TRUE(preview_web_contents);

  EXPECT_EQ(1, tab_strip_model->count());
  EXPECT_EQ(true,
            content::EvalJs(preview_web_contents, "document.prerendering"));

  helper().PromoteToNewTab();

  EXPECT_EQ(2, tab_strip_model->count());
  EXPECT_EQ(false,
            content::EvalJs(preview_web_contents, "document.prerendering"));
}

IN_PROC_BROWSER_TEST_F(PreviewBrowserTest, TrivialSessionHistory) {
  const std::string title1_path = "/title1.html";
  const GURL title1_url = GetURL(title1_path);
  const GURL title2_url = GetURL("/title2.html");
  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), title1_url));

  helper().InitiatePreview(title2_url);
  helper().WaitUntilLoadFinished();

  base::WeakPtr<content::WebContents> preview_web_contents =
      helper().GetWebContentsForPreviewTab();
  ASSERT_TRUE(preview_web_contents);

  EXPECT_EQ(title2_url, preview_web_contents->GetLastCommittedURL());
  EXPECT_EQ(1, preview_web_contents->GetController().GetEntryCount());
  EXPECT_EQ(
      1, EvalJs(preview_web_contents->GetPrimaryMainFrame(), "history.length"));

  ASSERT_EQ(title1_path, EvalJs(preview_web_contents->GetPrimaryMainFrame(),
                                "location = '/title1.html';"));
  helper().WaitUntilLoadFinished();

  EXPECT_EQ(title1_url, preview_web_contents->GetLastCommittedURL());
  EXPECT_EQ(1, preview_web_contents->GetController().GetEntryCount());
  EXPECT_EQ(
      1, EvalJs(preview_web_contents->GetPrimaryMainFrame(), "history.length"));
}

class MojoCapabilityControlTestContentBrowserClient
    : public ChromeContentBrowserClient,
      public content::test::MojoCapabilityControlTestHelper {
 public:
  MojoCapabilityControlTestContentBrowserClient() {
    previous_client_ = content::SetBrowserClientForTesting(this);
  }
  ~MojoCapabilityControlTestContentBrowserClient() override {
    content::SetBrowserClientForTesting(previous_client_);
  }
  MojoCapabilityControlTestContentBrowserClient(
      const MojoCapabilityControlTestContentBrowserClient&) = delete;
  MojoCapabilityControlTestContentBrowserClient& operator=(
      const MojoCapabilityControlTestContentBrowserClient&) = delete;

 private:
  // ChromeContentBrowserClient implementation.
  void RegisterBrowserInterfaceBindersForFrame(
      content::RenderFrameHost* render_frame_host,
      mojo::BinderMapWithContext<content::RenderFrameHost*>* map) override {
    if (previous_client_) {
      previous_client_->RegisterBrowserInterfaceBindersForFrame(
          render_frame_host, map);
    }
    RegisterTestBrowserInterfaceBindersForFrame(render_frame_host, map);
  }
  void RegisterMojoBinderPoliciesForPreview(
      content::MojoBinderPolicyMap& policy_map) override {
    RegisterTestMojoBinderPolicies(policy_map);
  }

  raw_ptr<content::ContentBrowserClient> previous_client_;
};

IN_PROC_BROWSER_TEST_F(PreviewBrowserTest, MojoCapabilityControl) {
  MojoCapabilityControlTestContentBrowserClient test_browser_client;

  const GURL kInitialUrl = GetURL("/title1.html");
  const GURL kPreviewUrl = GetURL("/page_with_iframe.html");

  // Navigate to an initial page.
  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), kInitialUrl));
  ASSERT_EQ(web_contents()->GetLastCommittedURL(), kInitialUrl);

  // Open the target page in preview mode.
  helper().InitiatePreview(kPreviewUrl);
  helper().WaitUntilLoadFinished();

  // Gather RenderFrameHosts for the preview tab.
  std::vector<content::RenderFrameHost*> frames;
  base::WeakPtr<content::WebContents> preview_web_contents =
      helper().GetWebContentsForPreviewTab();
  ASSERT_TRUE(preview_web_contents);
  preview_web_contents->GetPrimaryMainFrame()->ForEachRenderFrameHost(
      [&](content::RenderFrameHost* rfh) { frames.push_back(rfh); });
  CHECK_EQ(frames.size(), 2U);

  // A barrier closure to wait until a deferred interface is granted on all
  // frames.
  base::RunLoop run_loop;
  auto barrier_closure =
      base::BarrierClosure(frames.size(), run_loop.QuitClosure());

  mojo::RemoteSet<content::mojom::TestInterfaceForDefer> defer_remote_set;
  mojo::RemoteSet<content::mojom::TestInterfaceForGrant> grant_remote_set;
  for (auto* frame : frames) {
    // Try to bind a kDefer interface.
    mojo::Remote<content::mojom::TestInterfaceForDefer> defer_remote;
    test_browser_client.GetInterface(frame,
                                     defer_remote.BindNewPipeAndPassReceiver());
    //  The barrier closure will be called after the deferred interface is
    //  granted.
    defer_remote->Ping(barrier_closure);
    defer_remote_set.Add(std::move(defer_remote));

    // Try to bind a kGrant interface.
    mojo::Remote<content::mojom::TestInterfaceForGrant> grant_remote;
    test_browser_client.GetInterface(frame,
                                     grant_remote.BindNewPipeAndPassReceiver());
    grant_remote_set.Add(std::move(grant_remote));
  }

  // Verify that BrowserInterfaceBrokerImpl defers running binders whose
  // policies are kDefer until the prerendered page is activated.
  EXPECT_EQ(test_browser_client.GetDeferReceiverSetSize(), 0U);
  // Verify that BrowserInterfaceBrokerImpl executes kGrant binders immediately.
  EXPECT_EQ(test_browser_client.GetGrantReceiverSetSize(), frames.size());

  // Activate the prerendered page.
  helper().PromoteToNewTab();

  // Wait until the deferred interface is granted on all frames.
  run_loop.Run();
  EXPECT_EQ(test_browser_client.GetDeferReceiverSetSize(), frames.size());
}

IN_PROC_BROWSER_TEST_F(PreviewBrowserTest, ErrorOnNonHttpsUrl) {
  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), GetURL("/title1.html")));

  helper().InitiatePreview(embedded_test_server()->GetURL("/title2.html"));
  helper().WaitUntilLoadFinished();

  base::WeakPtr<content::WebContents> preview_web_contents =
      helper().GetWebContentsForPreviewTab();
  ASSERT_TRUE(preview_web_contents);

  EXPECT_EQ("Can't preview non-HTTPS URL",
            content::EvalJs(preview_web_contents,
                            "document.querySelector('h1 span').textContent")
                .ExtractString());
}

IN_PROC_BROWSER_TEST_F(PreviewBrowserTest, ErrorOnRedirectionToNonHttpsUrl) {
  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), GetURL("/title1.html")));

  GURL http_url = embedded_test_server()->GetURL("/title2.html");
  GURL preview_url = GetURL("/server-redirect?" + http_url.spec());
  helper().InitiatePreview(preview_url);
  helper().WaitUntilLoadFinished();

  base::WeakPtr<content::WebContents> preview_web_contents =
      helper().GetWebContentsForPreviewTab();
  ASSERT_TRUE(preview_web_contents);

  EXPECT_EQ("Can't preview non-HTTPS URL",
            content::EvalJs(preview_web_contents,
                            "document.querySelector('h1 span').textContent")
                .ExtractString());
}

IN_PROC_BROWSER_TEST_F(PreviewBrowserTest, ZoomUsageRecordedOnCancel) {
  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), GetURL("/title1.html")));

  helper().InitiatePreview(GetURL("/title2.html"));
  helper().WaitUntilLoadFinished();

  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), GetURL("/title1.html")));

  histogram_tester().ExpectTotalCount("LinkPreview.Experimental.ZoomUsage", 1);
  histogram_tester().ExpectBucketCount(
      "LinkPreview.Experimental.ZoomUsage",
      PreviewZoomController::ZoomUsage::kOnlyDefaultUsed, 1);
}

IN_PROC_BROWSER_TEST_F(PreviewBrowserTest, ZoomUsageRecordedOnPromoteToNewTab) {
  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), GetURL("/title1.html")));

  helper().InitiatePreview(GetURL("/title2.html"));
  helper().WaitUntilLoadFinished();

  helper().PromoteToNewTab();
  // Wait a task destructing PreviewTab.
  base::RunLoop().RunUntilIdle();

  histogram_tester().ExpectTotalCount("LinkPreview.Experimental.ZoomUsage", 1);
  histogram_tester().ExpectBucketCount(
      "LinkPreview.Experimental.ZoomUsage",
      PreviewZoomController::ZoomUsage::kOnlyDefaultUsed, 1);
}

IN_PROC_BROWSER_TEST_F(PreviewBrowserTest, ZoomIsDurableForHost) {
  GURL url_a = https_server().GetURL("a.test", "/title1.html");
  GURL url_b = https_server().GetURL("b.test", "/title1.html");

  auto expect = [this](int x, int y) {
    histogram_tester().ExpectTotalCount("LinkPreview.Experimental.ZoomUsage",
                                        x + y);
    histogram_tester().ExpectBucketCount(
        "LinkPreview.Experimental.ZoomUsage",
        PreviewZoomController::ZoomUsage::kOnlyDefaultUsed, x);
    histogram_tester().ExpectBucketCount(
        "LinkPreview.Experimental.ZoomUsage",
        PreviewZoomController::ZoomUsage::kNonDefaultUsed, y);
  };

  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url_a));
  helper().InitiatePreview(url_a);
  helper().WaitUntilLoadFinished();

  // This preview contributes to kNonDefaultUsed.
  helper().GetManager().PreviewZoomControllerForTesting()->Zoom(
      content::PAGE_ZOOM_IN);

  // Navigate out and cancel preview.
  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url_b));

  expect(0, 1);

  // This preview will be shown with the default zoom level because host
  // differs.
  helper().InitiatePreview(url_b);
  helper().WaitUntilLoadFinished();

  // Navigate out and cancel preview.
  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url_a));

  expect(1, 1);

  // This preview will be shown with zoom-in due to the effect of first preview.
  helper().InitiatePreview(url_a);
  helper().WaitUntilLoadFinished();

  // This preview contributes to kNonDefaultUsed. The next doesn't.
  helper().GetManager().PreviewZoomControllerForTesting()->Zoom(
      content::PAGE_ZOOM_RESET);

  // Navigate out and cancel preview.
  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url_a));

  expect(1, 2);

  helper().InitiatePreview(url_a);
  helper().WaitUntilLoadFinished();

  // Navigate out and cancel preview.
  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url_a));

  expect(2, 2);
}
