// 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 <algorithm>
#include <memory>
#include <optional>
#include <string>
#include <vector>

#include "base/command_line.h"
#include "base/containers/span.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/functional/bind.h"
#include "base/logging.h"
#include "base/run_loop.h"
#include "base/strings/string_util.h"
#include "base/strings/to_string.h"
#include "base/test/test_timeouts.h"
#include "base/test/values_test_util.h"
#include "base/threading/platform_thread.h"
#include "base/values.h"
#include "build/build_config.h"
#include "chrome/browser/headless/headless_mode_browsertest.h"
#include "chrome/common/chrome_switches.h"
#include "components/headless/command_handler/headless_command_handler.h"
#include "components/headless/command_handler/headless_command_switches.h"
#include "components/headless/test/bitmap_utils.h"
#include "components/headless/test/capture_std_stream.h"
#include "components/headless/test/pdf_utils.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
#include "pdf/pdf.h"
#include "printing/buildflags/buildflags.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "third_party/skia/include/core/SkColor.h"
#include "ui/display/display_switches.h"
#include "ui/gfx/codec/png_codec.h"
#include "url/gurl.h"

namespace headless {

class HeadlessModeCommandBrowserTest : public HeadlessModeBrowserTest {
 public:
  HeadlessModeCommandBrowserTest() = default;

  void SetUp() override {
    ASSERT_TRUE(embedded_test_server()->Start());

    HeadlessCommandHandler::SetDoneCallbackForTesting(base::BindOnce(
        &HeadlessModeCommandBrowserTest::FinishTest, base::Unretained(this)));

    HeadlessModeBrowserTest::SetUp();
  }

 protected:
  // Override this to provide the test specific target page.
  virtual std::string GetTargetPage() { return "/hello.html"; }

  GURL GetTargetUrl(const std::string& url) {
    return embedded_test_server()->GetURL(url);
  }

  std::optional<HeadlessCommandHandler::Result> ProcessCommands() {
    if (!test_complete_) {
      run_loop_ = std::make_unique<base::RunLoop>();
      run_loop_->Run();
      run_loop_.reset();
    }

    return result_;
  }

 private:
  void FinishTest(HeadlessCommandHandler::Result result) {
    result_ = result;
    test_complete_ = true;
    if (run_loop_) {
      run_loop_->Quit();
    }
  }

  std::unique_ptr<base::RunLoop> run_loop_;
  bool test_complete_ = false;
  std::optional<HeadlessCommandHandler::Result> result_;
};

#define HEADLESS_MODE_COMMAND_BROWSER_TEST_WITH_TARGET_URL(                \
    test_fixture, test_name, target_url)                                   \
  class HeadlessModeCommandBrowserTest_##test_name : public test_fixture { \
   public:                                                                 \
    HeadlessModeCommandBrowserTest_##test_name() = default;                \
    std::string GetTargetPage() override {                                 \
      return target_url;                                                   \
    }                                                                      \
  };                                                                       \
  IN_PROC_BROWSER_TEST_F(HeadlessModeCommandBrowserTest_##test_name, test_name)

class HeadlessModeCommandBrowserTestWithTempDir
    : public HeadlessModeCommandBrowserTest {
 public:
  HeadlessModeCommandBrowserTestWithTempDir() = default;

  void SetUp() override {
    ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
    ASSERT_TRUE(base::IsDirectoryEmpty(temp_dir()));

    HeadlessModeCommandBrowserTest::SetUp();
  }

  void TearDown() override {
    HeadlessModeCommandBrowserTest::TearDown();

    ASSERT_TRUE(temp_dir_.Delete());
  }

  const base::FilePath& temp_dir() const { return temp_dir_.GetPath(); }

 private:
  base::ScopedTempDir temp_dir_;
};

// DumpDom command tests ----------------------------------------------

class HeadlessModeDumpDomCommandBrowserTestBase
    : public HeadlessModeCommandBrowserTest {
 public:
  HeadlessModeDumpDomCommandBrowserTestBase() = default;

  void SetUpCommandLine(base::CommandLine* command_line) override {
    HeadlessModeCommandBrowserTest::SetUpCommandLine(command_line);
    command_line->AppendSwitch(switches::kDumpDom);
    command_line->AppendArg(GetTargetUrl(GetTargetPage()).spec());

    capture_stdout_.StartCapture();
  }

 protected:
  CaptureStdOut capture_stdout_;
};

class HeadlessModeDumpDomCommandBrowserTest
    : public HeadlessModeDumpDomCommandBrowserTestBase,
      public testing::WithParamInterface<bool> {
 public:
  HeadlessModeDumpDomCommandBrowserTest() = default;

 private:
  bool IsIncognito() override { return GetParam(); }
};

INSTANTIATE_TEST_SUITE_P(/* no prefix */,
                         HeadlessModeDumpDomCommandBrowserTest,
                         ::testing::Bool());

// TODO(crbug.com/40266323): Reenable once deflaked.
#if BUILDFLAG(IS_MAC)
#define MAYBE_HeadlessDumpDom DISABLED_HeadlessDumpDom
#else
#define MAYBE_HeadlessDumpDom HeadlessDumpDom
#endif
IN_PROC_BROWSER_TEST_P(HeadlessModeDumpDomCommandBrowserTest,
                       MAYBE_HeadlessDumpDom) {
  ASSERT_THAT(ProcessCommands(),
              testing::Eq(HeadlessCommandHandler::Result::kSuccess));

  capture_stdout_.StopCapture();
  std::string captured_stdout = capture_stdout_.TakeCapturedData();

  static const char kDomDump[] =
      "<!DOCTYPE html>\n"
      "<html><head></head><body><h1>Hello headless world!</h1>\n"
      "</body></html>\n";
  EXPECT_THAT(captured_stdout, testing::HasSubstr(kDomDump));
}

class HeadlessModeDumpDomCommandBrowserTestWithTimeoutBase
    : public HeadlessModeDumpDomCommandBrowserTestBase {
 public:
  HeadlessModeDumpDomCommandBrowserTestWithTimeoutBase() = default;

  void SetUpCommandLine(base::CommandLine* command_line) override {
    HeadlessModeDumpDomCommandBrowserTestBase::SetUpCommandLine(command_line);
    command_line->AppendSwitchASCII(switches::kTimeout,
                                    base::ToString(timeout().InMilliseconds()));
  }

  base::TimeDelta timeout() { return TestTimeouts::action_timeout(); }
};

class HeadlessModeDumpDomCommandBrowserTestWithTimeout
    : public HeadlessModeDumpDomCommandBrowserTestWithTimeoutBase {
 public:
  HeadlessModeDumpDomCommandBrowserTestWithTimeout() = default;

  void SetUp() override {
    embedded_test_server()->RegisterRequestHandler(base::BindRepeating(
        &HeadlessModeDumpDomCommandBrowserTestWithTimeout::RequestHandler,
        base::Unretained(this)));

    HeadlessModeDumpDomCommandBrowserTestWithTimeoutBase::SetUp();
  }

 private:
  std::string GetTargetPage() override { return "/page.html"; }

  std::unique_ptr<net::test_server::HttpResponse> RequestHandler(
      const net::test_server::HttpRequest& request) {
    if (request.relative_url == "/page.html") {
      auto response = std::make_unique<net::test_server::DelayedHttpResponse>(
          timeout() * 2);
      response->set_code(net::HTTP_OK);
      response->set_content_type("text/html");
      response->set_content(R"(<div>Hi, I'm headless!</div>)");

      return response;
    }

    return nullptr;
  }
};

IN_PROC_BROWSER_TEST_F(HeadlessModeDumpDomCommandBrowserTestWithTimeout,
                       HeadlessDumpDomWithTimeout) {
  // Main page timeout should be reported.
  EXPECT_THAT(ProcessCommands(),
              testing::Eq(HeadlessCommandHandler::Result::kPageLoadTimeout));

  capture_stdout_.StopCapture();
  std::string captured_stdout = capture_stdout_.TakeCapturedData();
  std::erase_if(captured_stdout, isspace);

  // Expect about:blank page DOM.
  EXPECT_THAT(captured_stdout,
              testing::HasSubstr("<html><head></head><body></body></html>"));
}

class HeadlessModeDumpDomCommandBrowserTestWithSubResourceTimeout
    : public HeadlessModeDumpDomCommandBrowserTestWithTimeoutBase,
      public testing::WithParamInterface<bool> {
 public:
  HeadlessModeDumpDomCommandBrowserTestWithSubResourceTimeout() = default;

  bool delay_response() { return GetParam(); }

  void SetUp() override {
    embedded_test_server()->RegisterRequestHandler(base::BindRepeating(
        &HeadlessModeDumpDomCommandBrowserTestWithSubResourceTimeout::
            RequestHandler,
        base::Unretained(this)));

    HeadlessModeDumpDomCommandBrowserTestWithTimeoutBase::SetUp();
  }

 private:
  std::string GetTargetPage() override { return "/page.html"; }

  std::unique_ptr<net::test_server::HttpResponse> RequestHandler(
      const net::test_server::HttpRequest& request) {
    if (request.relative_url == "/page.html") {
      auto response = std::make_unique<net::test_server::BasicHttpResponse>();
      response->set_code(net::HTTP_OK);
      response->set_content_type("text/html");
      response->set_content(R"(
        <html><body>
        <div id="thediv">INITIAL</div>
        <script src="./script.js"></script>
        </body></html>
      )");

      return response;
    }

    if (request.relative_url == "/script.js") {
      std::unique_ptr<net::test_server::BasicHttpResponse> response;
      if (delay_response()) {
        response = std::make_unique<net::test_server::DelayedHttpResponse>(
            timeout() * 2);
      } else {
        response = std::make_unique<net::test_server::BasicHttpResponse>();
      }

      response->set_code(net::HTTP_OK);
      response->set_content_type("text/javascript");
      response->set_content(R"(
        document.getElementById("thediv").innerText="REPLACED";
      )");

      return response;
    }

    return nullptr;
  }
};

INSTANTIATE_TEST_SUITE_P(
    All,
    HeadlessModeDumpDomCommandBrowserTestWithSubResourceTimeout,
    testing::Bool());

IN_PROC_BROWSER_TEST_P(
    HeadlessModeDumpDomCommandBrowserTestWithSubResourceTimeout,
    HeadlessDumpDomWithSubResourceTimeout) {
  std::optional<HeadlessCommandHandler::Result> result = ProcessCommands();

  capture_stdout_.StopCapture();
  std::string captured_stdout = capture_stdout_.TakeCapturedData();
  std::erase_if(captured_stdout, isspace);

  if (delay_response()) {
    EXPECT_THAT(result,
                testing::Eq(HeadlessCommandHandler::Result::kPageLoadTimeout));
    EXPECT_THAT(captured_stdout,
                testing::HasSubstr(
                    "<html><head></head><body><divid=\"thediv\">INITIAL</"
                    "div><scriptsrc=\"./script.js\"></script></body></html>"));
  } else {
    EXPECT_THAT(result, testing::Eq(HeadlessCommandHandler::Result::kSuccess));
    EXPECT_THAT(captured_stdout,
                testing::HasSubstr(
                    "<html><head></head><body><divid=\"thediv\">REPLACED</"
                    "div><scriptsrc=\"./script.js\"></script></body></html>"));
  }
}

HEADLESS_MODE_COMMAND_BROWSER_TEST_WITH_TARGET_URL(
    HeadlessModeDumpDomCommandBrowserTestBase,
    DumpDomWithBeforeUnloadPreventDefault,
    "/before_unload_prevent_default.html") {
  // Make sure that 'beforeunload' that prevents default action does not stall
  // the command processing. The "Leave site" popup should not appear because
  // command target was not user activated.
  EXPECT_THAT(ProcessCommands(),
              testing::Eq(HeadlessCommandHandler::Result::kSuccess));
}

// Screenshot command tests -------------------------------------------

class HeadlessModeScreenshotCommandBrowserTest
    : public HeadlessModeCommandBrowserTestWithTempDir {
 public:
  HeadlessModeScreenshotCommandBrowserTest() = default;

#if BUILDFLAG(IS_WIN)
  void SetUp() override {
    // Use software compositing instead of GL which causes blank screenshots on
    // Windows, especially under ASAN. See https://crbug.com/1442606 and
    // https://crbug.com/328195816.
    UseSoftwareCompositing();

    HeadlessModeCommandBrowserTestWithTempDir::SetUp();
  }
#endif

  void SetUpCommandLine(base::CommandLine* command_line) override {
    HeadlessModeCommandBrowserTestWithTempDir::SetUpCommandLine(command_line);

    screenshot_filename_ =
        temp_dir().Append(FILE_PATH_LITERAL("screenshot.png"));
    command_line->AppendSwitchPath(switches::kScreenshot, screenshot_filename_);
    command_line->AppendArg(GetTargetUrl("/centered_blue_box.html").spec());
  }

 protected:
  base::FilePath screenshot_filename_;
};

IN_PROC_BROWSER_TEST_F(HeadlessModeScreenshotCommandBrowserTest,
                       HeadlessScreenshot) {
  ASSERT_THAT(ProcessCommands(),
              testing::Eq(HeadlessCommandHandler::Result::kSuccess));

  base::ScopedAllowBlockingForTesting allow_blocking;

  std::optional<std::vector<uint8_t>> png_data =
      base::ReadFileToBytes(screenshot_filename_);

  SkBitmap bitmap = gfx::PNGCodec::Decode(png_data.value());
  ASSERT_FALSE(bitmap.isNull());

  // Expect a centered blue rectangle on white background.
  EXPECT_TRUE(CheckColoredRect(bitmap, SkColorSetRGB(0x00, 0x00, 0xff),
                               SkColorSetRGB(0xff, 0xff, 0xff)));
}

class HeadlessModeScreenshotCommandWithWindowSizeBrowserTest
    : public HeadlessModeScreenshotCommandBrowserTest {
 public:
  HeadlessModeScreenshotCommandWithWindowSizeBrowserTest() = default;

  void SetUpCommandLine(base::CommandLine* command_line) override {
    HeadlessModeScreenshotCommandBrowserTest::SetUpCommandLine(command_line);

    command_line->AppendSwitchASCII(::switches::kWindowSize, "2345,1234");
    command_line->AppendSwitchASCII(::switches::kForceDeviceScaleFactor, "1");
  }
};

IN_PROC_BROWSER_TEST_F(HeadlessModeScreenshotCommandWithWindowSizeBrowserTest,
                       HeadlessScreenshotWithWindowSize) {
  ASSERT_THAT(ProcessCommands(),
              testing::Eq(HeadlessCommandHandler::Result::kSuccess));

  base::ScopedAllowBlockingForTesting allow_blocking;

  std::optional<std::vector<uint8_t>> png_data =
      base::ReadFileToBytes(screenshot_filename_);

  SkBitmap bitmap = gfx::PNGCodec::Decode(png_data.value());
  ASSERT_FALSE(bitmap.isNull());

  EXPECT_EQ(bitmap.width(), 2345);
  EXPECT_EQ(bitmap.height(), 1234);

  // Expect a centered blue rectangle on white background.
  EXPECT_TRUE(CheckColoredRect(bitmap, SkColorSetRGB(0x00, 0x00, 0xff),
                               SkColorSetRGB(0xff, 0xff, 0xff)));
}

class HeadlessModeScreenshotCommandWithBackgroundBrowserTest
    : public HeadlessModeScreenshotCommandBrowserTest {
 public:
  HeadlessModeScreenshotCommandWithBackgroundBrowserTest() = default;

  void SetUpCommandLine(base::CommandLine* command_line) override {
    HeadlessModeScreenshotCommandBrowserTest::SetUpCommandLine(command_line);

    command_line->AppendSwitchASCII(switches::kDefaultBackgroundColor,
                                    "ff0000");
  }
};

IN_PROC_BROWSER_TEST_F(HeadlessModeScreenshotCommandWithBackgroundBrowserTest,
                       HeadlessScreenshotWithBackground) {
  ASSERT_THAT(ProcessCommands(),
              testing::Eq(HeadlessCommandHandler::Result::kSuccess));

  base::ScopedAllowBlockingForTesting allow_blocking;

  std::optional<std::vector<uint8_t>> png_data =
      base::ReadFileToBytes(screenshot_filename_);

  SkBitmap bitmap = gfx::PNGCodec::Decode(png_data.value());
  ASSERT_FALSE(bitmap.isNull());

  // Expect a centered blue rectangle on red background.
  EXPECT_TRUE(CheckColoredRect(bitmap, SkColorSetRGB(0x00, 0x00, 0xff),
                               SkColorSetRGB(0xff, 0x00, 0x00)));
}

// PrintToPDF command tests -------------------------------------------

class HeadlessModePrintToPdfCommandBrowserTestBase
    : public HeadlessModeCommandBrowserTestWithTempDir {
 public:
  HeadlessModePrintToPdfCommandBrowserTestBase() = default;

  void SetUpCommandLine(base::CommandLine* command_line) override {
    HeadlessModeCommandBrowserTestWithTempDir::SetUpCommandLine(command_line);

    print_to_pdf_filename_ =
        temp_dir().Append(FILE_PATH_LITERAL("print-to.pdf"));
    command_line->AppendSwitchPath(switches::kPrintToPDF,
                                   print_to_pdf_filename_);
    command_line->AppendSwitch(switches::kNoPDFHeaderFooter);

    command_line->AppendArg(GetTargetUrl(GetTargetPage()).spec());
  }

 protected:
  base::FilePath print_to_pdf_filename_;
};

class HeadlessModePrintToPdfCommandBrowserTest
    : public HeadlessModePrintToPdfCommandBrowserTestBase {
 public:
  HeadlessModePrintToPdfCommandBrowserTest() = default;

  std::string GetTargetPage() override { return "/centered_blue_box.html"; }
};

// TODO(crbug.com/40266323): Reenable once deflaked.
#if BUILDFLAG(IS_MAC)
#define MAYBE_HeadlessPrintToPdf DISABLED_HeadlessPrintToPdf
#else
#define MAYBE_HeadlessPrintToPdf HeadlessPrintToPdf
#endif
IN_PROC_BROWSER_TEST_F(HeadlessModePrintToPdfCommandBrowserTest,
                       MAYBE_HeadlessPrintToPdf) {
  ASSERT_THAT(ProcessCommands(),
              testing::Eq(HeadlessCommandHandler::Result::kSuccess));

  base::ScopedAllowBlockingForTesting allow_blocking;

  std::optional<std::vector<uint8_t>> pdf_data =
      base::ReadFileToBytes(print_to_pdf_filename_);
  ASSERT_TRUE(pdf_data.has_value()) << print_to_pdf_filename_;

  PDFPageBitmap page_bitmap;
  ASSERT_TRUE(page_bitmap.Render(pdf_data.value(), /*page_index=*/0));

  // Expect blue rectangle on white background.
  EXPECT_TRUE(page_bitmap.CheckColoredRect(SkColorSetRGB(0x00, 0x00, 0xff),
                                           SkColorSetRGB(0xff, 0xff, 0xff)));
}

HEADLESS_MODE_COMMAND_BROWSER_TEST_WITH_TARGET_URL(
    HeadlessModePrintToPdfCommandBrowserTestBase,
    PrintToPdfWithLazyLoading,
    "/page_with_lazy_image.html") {
  ASSERT_THAT(ProcessCommands(),
              testing::Eq(HeadlessCommandHandler::Result::kSuccess));

  base::ScopedAllowBlockingForTesting allow_blocking;

  std::optional<std::vector<uint8_t>> pdf_data =
      base::ReadFileToBytes(print_to_pdf_filename_);
  ASSERT_TRUE(pdf_data.has_value()) << print_to_pdf_filename_;

  PDFPageBitmap page_bitmap;
  ASSERT_TRUE(page_bitmap.Render(pdf_data.value(), /*page_index=*/4));

  // Expect green rectangle on white background.
  EXPECT_TRUE(page_bitmap.CheckColoredRect(SkColorSetRGB(0x00, 0x64, 0x00),
                                           SkColorSetRGB(0xff, 0xff, 0xff)));
}

class HeadlessModeTaggedPrintToPdfCommandBrowserTest
    : public HeadlessModePrintToPdfCommandBrowserTestBase,
      public ::testing::WithParamInterface<bool> {
 public:
  HeadlessModeTaggedPrintToPdfCommandBrowserTest() = default;

  bool generate_tagged_pdf() { return GetParam(); }

  std::string GetTargetPage() override { return "/hello.html"; }

  void SetUpCommandLine(base::CommandLine* command_line) override {
    HeadlessModePrintToPdfCommandBrowserTestBase::SetUpCommandLine(
        command_line);
    if (!generate_tagged_pdf()) {
      command_line->AppendSwitch(switches::kDisablePDFTagging);
    }
  }
};

const char kExpectedStructTreeJSON[] = R"({
   "lang": "en-US",
   "type": "Document",
   "~children": [ {
      "type": "H1",
      "~children": [ {
         "type": "NonStruct"
      } ]
   } ]
}
)";

INSTANTIATE_TEST_SUITE_P(/* no prefix */,
                         HeadlessModeTaggedPrintToPdfCommandBrowserTest,
                         ::testing::Bool());

IN_PROC_BROWSER_TEST_P(HeadlessModeTaggedPrintToPdfCommandBrowserTest,
                       HeadlessTaggedPrintToPdf) {
  ASSERT_THAT(ProcessCommands(),
              testing::Eq(HeadlessCommandHandler::Result::kSuccess));

  base::ScopedAllowBlockingForTesting allow_blocking;

  std::optional<std::vector<uint8_t>> pdf_data =
      base::ReadFileToBytes(print_to_pdf_filename_);
  ASSERT_TRUE(pdf_data.has_value()) << print_to_pdf_filename_;

  auto pdf_span = base::as_byte_span(pdf_data.value());

  int num_pages;
  ASSERT_TRUE(chrome_pdf::GetPDFDocInfo(pdf_span, &num_pages,
                                        /*max_page_width=*/nullptr));

  EXPECT_THAT(num_pages, testing::Eq(1));

  ASSERT_THAT(chrome_pdf::IsPDFDocTagged(pdf_span),
              testing::Optional(generate_tagged_pdf()));

  if (generate_tagged_pdf()) {
    base::Value struct_tree =
        chrome_pdf::GetPDFStructTreeForPage(pdf_span, /*page_index=*/0);
    EXPECT_THAT(kExpectedStructTreeJSON, base::test::IsJson((struct_tree)));
  }
}

}  // namespace headless
