// Copyright 2024 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/test/scoped_feature_list.h"
#include "base/test/test_future.h"
#include "build/buildflag.h"
#include "cc/base/features.h"
#include "cc/test/pixel_comparator.h"
#include "cc/test/pixel_test_utils.h"
#include "components/viz/common/features.h"
#include "components/viz/common/frame_sinks/copy_output_result.h"
#include "components/viz/host/host_frame_sink_manager.h"
#include "content/browser/compositor/surface_utils.h"
#include "content/browser/renderer_host/frame_tree_node.h"
#include "content/browser/renderer_host/render_process_host_impl.h"
#include "content/browser/renderer_host/view_transition_opt_in_state.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/web_contents_observer.h"
#include "content/public/common/content_features.h"
#include "content/public/test/back_forward_cache_util.h"
#include "content/public/test/browser_test.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/content_browser_test.h"
#include "content/shell/browser/shell.h"
#include "content/shell/browser/shell_download_manager_delegate.h"
#include "content/test/content_browser_test_utils_internal.h"
#include "mojo/public/cpp/bindings/sync_call_restrictions.h"
#include "net/dns/mock_host_resolver.h"
#include "net/test/embedded_test_server/default_handlers.h"
#include "services/viz/privileged/mojom/compositing/features.mojom-features.h"
#include "third_party/blink/public/common/features.h"
#include "third_party/blink/public/common/features_generated.h"
#include "ui/gfx/geometry/size.h"

namespace content {

class ViewTransitionBrowserTest : public ContentBrowserTest {
 public:
  class TestCondition : public CommitDeferringCondition {
   public:
    TestCondition(NavigationRequest& request, base::RunLoop* run_loop)
        : CommitDeferringCondition(request), run_loop_(run_loop) {}
    ~TestCondition() override = default;

    Result WillCommitNavigation(base::OnceClosure resume) override {
      GetUIThreadTaskRunner()->PostTask(FROM_HERE, run_loop_->QuitClosure());
      return Result::kDefer;
    }

    const char* TraceEventName() const override { return "TestCondition"; }

   private:
    raw_ptr<base::RunLoop> run_loop_;
  };

  ViewTransitionBrowserTest() {
    feature_list_.InitWithFeatures(
        /*enabled_features=*/
        {viz::mojom::EnableVizTestApis},
        /*disabled_features=*/{});
  }

  void SetUpOnMainThread() override {
    ContentBrowserTest::SetUpOnMainThread();
    host_resolver()->AddRule("*", "127.0.0.1");
    embedded_test_server()->ServeFilesFromSourceDirectory(
        GetTestDataFilePath());
    net::test_server::RegisterDefaultHandlers(embedded_test_server());
    ASSERT_TRUE(embedded_test_server()->Start());
  }

  void WaitForConditionsDone(NavigationRequest* request) {
    // Inject a condition to know when the VT response has been received but
    // before the NavigationRequest is notified.
    run_loop_ = std::make_unique<base::RunLoop>();
    request->RegisterCommitDeferringConditionForTesting(
        std::make_unique<TestCondition>(*request, run_loop_.get()));
    run_loop_->Run();
  }

  bool HasVTOptIn(RenderFrameHost* rfh) {
    auto* opt_in_state = ViewTransitionOptInState::GetForCurrentDocument(
        static_cast<RenderFrameHostImpl*>(rfh));
    return opt_in_state &&
           opt_in_state->same_origin_opt_in() ==
               blink::mojom::ViewTransitionSameOriginOptIn::kEnabled;
  }

 private:
  base::test::ScopedFeatureList feature_list_;
  std::unique_ptr<base::RunLoop> run_loop_;
};

IN_PROC_BROWSER_TEST_F(ViewTransitionBrowserTest,
                       NavigationCancelledAfterScreenshot) {
  // Start with a page which has an opt-in for VT.
  GURL test_url(
      embedded_test_server()->GetURL("/view_transitions/basic-vt-opt-in.html"));
  ASSERT_TRUE(NavigateToURL(shell()->web_contents(), test_url));
  WaitForCopyableViewInWebContents(shell()->web_contents());

  TestNavigationManager navigation_manager(shell()->web_contents(), test_url);
  ASSERT_TRUE(
      ExecJs(shell()->web_contents(), "location.href = location.href;"));

  // Wait for response and resume. The navigation should be blocked by the view
  // transition condition.
  ASSERT_TRUE(navigation_manager.WaitForResponse());
  navigation_manager.ResumeNavigation();

  auto* navigation_request =
      NavigationRequest::From(navigation_manager.GetNavigationHandle());
  ASSERT_TRUE(navigation_request);
  ASSERT_TRUE(
      navigation_request->IsCommitDeferringConditionDeferredForTesting());
  ASSERT_FALSE(navigation_request->commit_params().view_transition_state);

  WaitForConditionsDone(navigation_request);
  ASSERT_TRUE(navigation_request->commit_params().view_transition_state);

  mojo::ScopedAllowSyncCallForTesting allow_sync;

  bool has_resources = false;
  GetHostFrameSinkManager()
      ->GetFrameSinkManagerTestApi()
      .HasUnclaimedViewTransitionResources(&has_resources);
  ASSERT_TRUE(has_resources);

  shell()->web_contents()->Stop();
  ASSERT_FALSE(navigation_manager.was_committed());
  GetHostFrameSinkManager()
      ->GetFrameSinkManagerTestApi()
      .HasUnclaimedViewTransitionResources(&has_resources);
  ASSERT_FALSE(has_resources);

  // Ensure the old renderer discards the outgoing transition.
  EXPECT_TRUE(ExecJs(
      shell()->web_contents()->GetPrimaryMainFrame(),
      "(async () => { await document.startViewTransition().ready; })()"));
}

IN_PROC_BROWSER_TEST_F(ViewTransitionBrowserTest,
                       NavigationCancelledBeforeScreenshot) {
  // Start with a page which has an opt-in for VT.
  GURL test_url(
      embedded_test_server()->GetURL("/view_transitions/basic-vt-opt-in.html"));
  ASSERT_TRUE(NavigateToURL(shell()->web_contents(), test_url));
  WaitForCopyableViewInWebContents(shell()->web_contents());

  TestNavigationManager navigation_manager(shell()->web_contents(), test_url);
  ASSERT_TRUE(
      ExecJs(shell()->web_contents(), "location.href = location.href;"));

  // Wait for response and resume. The navigation should be blocked by the view
  // transition condition.
  ASSERT_TRUE(navigation_manager.WaitForResponse());
  navigation_manager.ResumeNavigation();

  auto* navigation_request =
      NavigationRequest::From(navigation_manager.GetNavigationHandle());
  ASSERT_TRUE(navigation_request);
  ASSERT_TRUE(
      navigation_request->IsCommitDeferringConditionDeferredForTesting());
  ASSERT_FALSE(navigation_request->commit_params().view_transition_state);

  // Stop the navigation while the screenshot request is in flight.
  shell()->web_contents()->Stop();
  ASSERT_FALSE(navigation_manager.was_committed());

  // Ensure the old renderer discards the outgoing transition.
  EXPECT_TRUE(ExecJs(
      shell()->web_contents()->GetPrimaryMainFrame(),
      "(async () => { await document.startViewTransition().ready; })()"));
}

IN_PROC_BROWSER_TEST_F(ViewTransitionBrowserTest,
                       OwnershipTransferredToNewRenderer) {
  // Start with a page which has an opt-in for VT.
  GURL test_url(
      embedded_test_server()->GetURL("/view_transitions/basic-vt-opt-in.html"));
  ASSERT_TRUE(NavigateToURL(shell()->web_contents(), test_url));
  WaitForCopyableViewInWebContents(shell()->web_contents());

  TestNavigationManager navigation_manager(shell()->web_contents(), test_url);
  ASSERT_TRUE(
      ExecJs(shell()->web_contents(), "location.href = location.href;"));
  ASSERT_TRUE(navigation_manager.WaitForNavigationFinished());
  ASSERT_TRUE(static_cast<RenderWidgetHostViewBase*>(
                  shell()->web_contents()->GetRenderWidgetHostView())
                  ->HasViewTransitionResourcesForTesting());
}

// Ensure a browser-initiated navigation (i.e. typing URL into omnibox) does
// not trigger a view transitions.
IN_PROC_BROWSER_TEST_F(ViewTransitionBrowserTest,
                       NoOpOnBrowserInitiatedNavigations) {
  // Start with a page which has an opt-in for VT.
  GURL test_url(
      embedded_test_server()->GetURL("/view_transitions/basic-vt-opt-in.html"));
  ASSERT_TRUE(NavigateToURL(shell()->web_contents(), test_url));

  GURL test_url_next(embedded_test_server()->GetURL(
      "/view_transitions/basic-vt-opt-in.html?next"));
  ASSERT_TRUE(NavigateToURL(shell()->web_contents(), test_url_next));
  WaitForCopyableViewInWebContents(shell()->web_contents());

  EXPECT_EQ(false, EvalJs(shell()->web_contents(), "had_incoming_transition"));
}

class ViewTransitionDownloadBrowserTest : public ViewTransitionBrowserTest {
 public:
  void SetUpOnMainThread() override {
    ViewTransitionBrowserTest::SetUpOnMainThread();

    // Set up a test download directory, in order to prevent prompting for
    // handling downloads.
    ASSERT_TRUE(downloads_directory_.CreateUniqueTempDir());
    ShellDownloadManagerDelegate* delegate =
        static_cast<ShellDownloadManagerDelegate*>(
            shell()
                ->web_contents()
                ->GetBrowserContext()
                ->GetDownloadManagerDelegate());
    delegate->SetDownloadBehaviorForTesting(downloads_directory_.GetPath());
  }

 private:
  base::ScopedTempDir downloads_directory_;
};

IN_PROC_BROWSER_TEST_F(ViewTransitionDownloadBrowserTest,
                       NavigationToDownloadLink) {
  GURL test_url(
      embedded_test_server()->GetURL("/view_transitions/basic-vt-opt-in.html"));
  ASSERT_TRUE(NavigateToURL(shell()->web_contents(), test_url));
  WaitForCopyableViewInWebContents(shell()->web_contents());

  GURL download_url(embedded_test_server()->GetURL("/download-test1.lib"));
  TestNavigationManager navigation_manager(shell()->web_contents(),
                                           download_url);
  ASSERT_TRUE(ExecJs(shell()->web_contents(),
                     JsReplace("location.href = $1", download_url)));

  // Wait for response and resume. The navigation should not be blocked by the
  // view transition condition.
  ASSERT_TRUE(navigation_manager.WaitForRequestStart());

  ASSERT_TRUE(HasVTOptIn(shell()->web_contents()->GetPrimaryMainFrame()));
  auto* navigation_request =
      NavigationRequest::From(navigation_manager.GetNavigationHandle());
  ASSERT_EQ(
      shell()->web_contents()->GetPrimaryMainFrame()->GetLastCommittedOrigin(),
      navigation_request->GetTentativeOriginAtRequestTime());

  ASSERT_TRUE(navigation_manager.WaitForNavigationFinished());
  ASSERT_FALSE(navigation_manager.was_committed());
}

class ViewTransitionBrowserTestTraverse
    : public ViewTransitionBrowserTest,
      public testing::WithParamInterface<bool> {
 public:
  bool BFCacheEnabled() const { return GetParam(); }

  bool NavigateBack(GURL back_url, WebContents* contents = nullptr) {
    if (!contents) {
      contents = shell()->web_contents();
    }
    // We need to trigger the navigation *after* executing the script below so
    // the event handlers the script relies on are set before they're dispatched
    // by the navigation.
    //
    // We pass this as a callback to EvalJs so the navigation is initiated
    // before we wait for the script result since it relies on events dispatched
    // during the navigation.
    auto trigger_navigation = base::BindOnce(
        &ViewTransitionBrowserTestTraverse::TriggerBackNavigation,
        base::Unretained(this), back_url, contents);

    auto result =
        EvalJs(contents,
               JsReplace(
                   R"(
    (async () => {
      let navigateFired = false;
      navigation.onnavigate = (event) => {
        navigateFired = (event.navigationType === "traverse");
      };
      let pageswapfired = new Promise((resolve) => {
        onpageswap = (e) => {
          if (!navigateFired || e.viewTransition == null) {
            resolve(null);
            return;
          }
          activation = e.activation;
          resolve(activation);
        };
      });
      let result = await pageswapfired;
      return result != null;
    })();
  )"),
               EXECUTE_SCRIPT_DEFAULT_OPTIONS, ISOLATED_WORLD_ID_GLOBAL,
               std::move(trigger_navigation));
    return result.ExtractBool();
  }

  void TriggerBackNavigation(GURL back_url, WebContents* web_contents) {
    if (BFCacheEnabled()) {
      TestActivationManager manager(web_contents, back_url);
      web_contents->GetController().GoBack();
      manager.WaitForNavigationFinished();
    } else {
      TestNavigationManager manager(web_contents, back_url);
      web_contents->GetController().GoBack();
      ASSERT_TRUE(manager.WaitForNavigationFinished());
    }
  }
};

IN_PROC_BROWSER_TEST_P(ViewTransitionBrowserTestTraverse,
                       NavigateEventFiresBeforeCapture) {
  if (!BFCacheEnabled()) {
    DisableBackForwardCacheForTesting(
        shell()->web_contents(),
        BackForwardCache::DisableForTestingReason::TEST_REQUIRES_NO_CACHING);
  } else if (!base::FeatureList::IsEnabled(features::kBackForwardCache)) {
    GTEST_SKIP();
  }

  GURL test_url(
      embedded_test_server()->GetURL("/view_transitions/basic-vt-opt-in.html"));
  ASSERT_TRUE(NavigateToURL(shell()->web_contents(), test_url));
  GURL second_url(embedded_test_server()->GetURL(
      "/view_transitions/basic-vt-opt-in.html?new"));
  ASSERT_TRUE(NavigateToURL(shell()->web_contents(), second_url));
  WaitForCopyableViewInWebContents(shell()->web_contents());
  auto& nav_controller = static_cast<NavigationControllerImpl&>(
      shell()->web_contents()->GetController());
  ASSERT_TRUE(nav_controller.CanGoBack());
  ASSERT_TRUE(NavigateBack(test_url));
}

// A session restore (e.g. "Duplicate Tab", "Undo Close Tab") uses RESTORE
// navigation types when traversing the session history. Ensure these
// navigations trigger a view transition.
IN_PROC_BROWSER_TEST_P(ViewTransitionBrowserTestTraverse,
                       TransitionOnSessionRestoreTraversal) {
  // A restored session will never have its session history in BFCache so
  // there's no need to run a BFCache version of the test.
  if (BFCacheEnabled()) {
    GTEST_SKIP();
  }

  // Start with a page which has an opt-in for VT.
  GURL url_a(
      embedded_test_server()->GetURL("/view_transitions/basic-vt-opt-in.html"));
  ASSERT_TRUE(NavigateToURL(shell()->web_contents(), url_a));

  // Navigate to another page with an opt-in. (There's no transition due to
  // being browser-initiated)
  GURL url_b(embedded_test_server()->GetURL(
      "/view_transitions/basic-vt-opt-in.html?next"));
  ASSERT_TRUE(NavigateToURL(shell()->web_contents(), url_b));

  // Clone the tab and load the page. Note: the cloned web contents must be put
  // into a window to generate BeginFrames which are required since a view
  // transition will not trigger unless a frame has been generated and the page
  // revealed.
  std::unique_ptr<WebContents> new_tab = shell()->web_contents()->Clone();
  WebContentsImpl* new_tab_impl = static_cast<WebContentsImpl*>(new_tab.get());
  shell()->AddNewContents(nullptr, std::move(new_tab), url_b,
                          WindowOpenDisposition::NEW_FOREGROUND_TAB,
                          blink::mojom::WindowFeatures(), false, nullptr);
  NavigationController& new_controller = new_tab_impl->GetController();

  {
    TestNavigationObserver clone_observer(new_tab_impl);
    new_controller.LoadIfNecessary();
    clone_observer.Wait();
  }

  // Ensure the page has been revealed before navigating back so that a
  // transition will be triggered.
  WaitForCopyableViewInWebContents(new_tab_impl);

  // TODO(crbug.com/331226127) Intentionally ignore the return value as the
  // navigation API (erroneously?) doesn't fire events for restored traversals.
  NavigateBack(url_a, new_tab_impl);

  // Ensure a frame has been generated so that the reveal event would have been
  // fired.
  WaitForCopyableViewInWebContents(new_tab_impl);

  EXPECT_EQ(true, EvalJs(new_tab_impl, "had_incoming_transition"));
}

INSTANTIATE_TEST_SUITE_P(P,
                         ViewTransitionBrowserTestTraverse,
                         ::testing::Bool());

class ViewTransitionCaptureTest
    : public ContentBrowserTest,
      public ::testing::WithParamInterface<std::pair<bool, std::string>> {
 public:
  ViewTransitionCaptureTest() {
    EnablePixelOutput(1.f);
    feature_list_.InitWithFeatures(
        /*enabled_features=*/
        {viz::mojom::EnableVizTestApis,
         features::kViewTransitionCaptureAndDisplay},
        /*disabled_features=*/
        {blink::features::kPaintHolding});
  }

  void SetUpOnMainThread() override {
    ContentBrowserTest::SetUpOnMainThread();
    host_resolver()->AddRule("*", "127.0.0.1");
    embedded_test_server()->ServeFilesFromSourceDirectory(
        GetTestDataFilePath());
    net::test_server::RegisterDefaultHandlers(embedded_test_server());
    ASSERT_TRUE(embedded_test_server()->Start());
  }

 protected:
  SkBitmap TakeScreenshot() {
    base::test::TestFuture<const viz::CopyOutputBitmapWithMetadata&>
        future_bitmap;
    shell()->web_contents()->GetRenderWidgetHostView()->CopyFromSurface(
        gfx::Rect(), gfx::Size(), future_bitmap.GetCallback());
    return future_bitmap.Take().bitmap;
  }

  void WaitForSurfaceAnimationManager(RenderFrameHost* render_frame_host) {
    mojo::ScopedAllowSyncCallForTesting sync_scope;
    GetHostFrameSinkManager()
        ->GetFrameSinkManagerTestApi()
        .WaitForSurfaceAnimationManager(
            static_cast<RenderFrameHostImpl*>(render_frame_host)
                ->GetRenderWidgetHost()
                ->GetFrameSinkId());
  }

 private:
  base::test::ScopedFeatureList feature_list_;
};

// TODO(https://crbug.com/400187507): Disabled due to continuous flakiness.
IN_PROC_BROWSER_TEST_P(ViewTransitionCaptureTest,
                       DISABLED_ViewTransitionNoArtifactDuringCapture) {
  const auto& [frametest, url] = GetParam();
  GURL test_url(embedded_test_server()->GetURL(url));
  auto* web_contents = shell()->web_contents();
  ASSERT_TRUE(NavigateToURL(web_contents, test_url));
  shell()->ResizeWebContentForTests(gfx::Size(100, 100));

  ASSERT_EQ(EvalJs(web_contents, JsReplace(R"(
            new Promise(resolve => {
              requestAnimationFrame(() => {
                requestAnimationFrame(() => resolve("ok"));
              });
            }))")),
            "ok");
  WaitForCopyableViewInWebContents(shell()->web_contents());
  SkBitmap before_bitmap = TakeScreenshot();

  // Sanity to see that we've captured something.
  ASSERT_NE(before_bitmap.getColor(5, 5), 0u);
  // This starts a view transition with a callback that signals that we're ok
  // to capture, but otherwise never finishes running the callback.
  if (frametest) {
    ASSERT_EQ(EvalJs(web_contents, JsReplace(R"(
                new Promise(dom_callback_started => {
                  frame.contentDocument.startViewTransition(async () => {
                    dom_callback_started('ok');
                    await new Promise(() => {});
                  });
                }))")),
              "ok");
  } else {
    ASSERT_EQ(EvalJs(web_contents, JsReplace(R"(
                new Promise(dom_callback_started => {
                  document.startViewTransition(async () => {
                    dom_callback_started('ok');
                    await new Promise(() => {});
                  });
                }))")),
              "ok");
  }
  WaitForSurfaceAnimationManager(
      shell()->web_contents()->GetPrimaryMainFrame());
  auto after_bitmap = TakeScreenshot();
  ASSERT_EQ(before_bitmap.width(), after_bitmap.width());
  ASSERT_EQ(before_bitmap.height(), after_bitmap.height());

  cc::FuzzyPixelComparator comparator;
  // Allow 50% of pixels to different by at most 3 in all channels.
  // The small differences on some platforms seem to be noise, and don't
  // invalidate the test intent.
  comparator.SetAbsErrorLimit(255, 3);
  comparator.SetErrorPixelsPercentageLimit(0, 50);
  EXPECT_TRUE(cc::MatchesBitmap(after_bitmap, before_bitmap, comparator));
}

INSTANTIATE_TEST_SUITE_P(
    P,
    ViewTransitionCaptureTest,
    // The pair parameter has the following meaning:
    //  - The first boolean indicates whether this test should invoke
    //    startViewTransition() on the `frame` DOM element's contentDocument (if
    //    true) or on the main frame's document (if false).
    //    - The second string indicates the location of the test to load.
    testing::Values(
        std::make_pair(false, "/view_transitions/parent-child.html"),
        std::make_pair(false, "/view_transitions/parent-child-opacity.html"),
        std::make_pair(true,
                       "/view_transitions/parent-child-opacity-iframe.html")));

class ViewTransitionProcessShutdownTest : public ViewTransitionBrowserTest {
 public:
  ViewTransitionProcessShutdownTest() {
    EnablePixelOutput(1.f);
    feature_list_.InitWithFeatures(
        /*enabled_features=*/
        {::features::kAckCopyOutputRequestEarlyForViewTransition,
         blink::features::kDelayLayerTreeViewDeletionOnLocalSwap,
         ::features::kRenderDocument},
        /*disabled_features=*/{});
  }

 private:
  base::test::ScopedFeatureList feature_list_;
};

IN_PROC_BROWSER_TEST_F(ViewTransitionProcessShutdownTest,
                       ResourcesAvailableAfterCrossProcessNavigation) {
  DisableBackForwardCacheForTesting(
      shell()->web_contents(),
      BackForwardCache::DisableForTestingReason::TEST_REQUIRES_NO_CACHING);

  GURL test_url(embedded_test_server()->GetURL(
      "a.com", "/view_transitions/basic-vt-opt-in.html"));
  ASSERT_TRUE(NavigateToURL(shell()->web_contents(), test_url));
  WaitForCopyableViewInWebContents(shell()->web_contents());

  // Navigate to another page with an opt-in. Use a.com to ensure same-origin
  // (triggers VT). Use COOP to force a new BrowsingInstance and process swap.
  GURL second_url(embedded_test_server()->GetURL(
      "a.com",
      "/view_transitions/"
      "basic-vt-opt-in.html?new&pipe=header(Cross-Origin-Opener-Policy,same-"
      "origin)"));
  TestNavigationManager navigation_manager(shell()->web_contents(), second_url);
  ASSERT_TRUE(ExecJs(shell()->web_contents(),
                     JsReplace("location.href = $1", second_url)));
  ASSERT_TRUE(navigation_manager.WaitForNavigationFinished());

  WaitForCopyableViewInWebContents(shell()->web_contents());
  auto& nav_controller = static_cast<NavigationControllerImpl&>(
      shell()->web_contents()->GetController());
  ASSERT_EQ(nav_controller.GetLastCommittedEntry()->GetURL(), second_url);

  // Ensure the new renderer has the resources.
  ASSERT_TRUE(static_cast<RenderWidgetHostViewBase*>(
                  shell()->web_contents()->GetRenderWidgetHostView())
                  ->HasViewTransitionResourcesForTesting());
}
}  // namespace content
