// Copyright 2016 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 <memory>

#include "base/command_line.h"
#include "base/files/file_enumerator.h"
#include "base/files/file_util.h"
#include "base/memory/ptr_util.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "base/threading/thread_restrictions.h"
#include "content/public/browser/permission_manager.h"
#include "content/public/browser/permission_type.h"
#include "content/public/common/url_constants.h"
#include "content/public/test/browser_test.h"
#include "headless/lib/browser/headless_browser_context_impl.h"
#include "headless/lib/browser/headless_web_contents_impl.h"
#include "headless/lib/headless_macros.h"
#include "headless/public/devtools/domains/inspector.h"
#include "headless/public/devtools/domains/network.h"
#include "headless/public/devtools/domains/page.h"
#include "headless/public/headless_browser.h"
#include "headless/public/headless_devtools_client.h"
#include "headless/public/headless_devtools_target.h"
#include "headless/public/headless_web_contents.h"
#include "headless/test/headless_browser_test.h"
#include "headless/test/test_protocol_handler.h"
#include "headless/test/test_url_request_job.h"
#include "net/base/registry_controlled_domains/registry_controlled_domain.h"
#include "net/cookies/cookie_store.h"
#include "net/test/spawned_test_server/spawned_test_server.h"
#include "net/url_request/url_request_context.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/base/clipboard/clipboard.h"
#include "ui/base/clipboard/scoped_clipboard_writer.h"
#include "ui/gfx/geometry/size.h"

using testing::UnorderedElementsAre;

namespace headless {

IN_PROC_BROWSER_TEST_F(HeadlessBrowserTest, CreateAndDestroyBrowserContext) {
  HeadlessBrowserContext* browser_context =
      browser()->CreateBrowserContextBuilder().Build();

  EXPECT_THAT(browser()->GetAllBrowserContexts(),
              UnorderedElementsAre(browser_context));

  browser_context->Close();

  EXPECT_TRUE(browser()->GetAllBrowserContexts().empty());
}

IN_PROC_BROWSER_TEST_F(HeadlessBrowserTest,
                       CreateAndDoNotDestroyBrowserContext) {
  HeadlessBrowserContext* browser_context =
      browser()->CreateBrowserContextBuilder().Build();

  EXPECT_THAT(browser()->GetAllBrowserContexts(),
              UnorderedElementsAre(browser_context));

  // We check that HeadlessBrowser correctly handles non-closed BrowserContexts.
  // We can rely on Chromium DCHECKs to capture this.
}

IN_PROC_BROWSER_TEST_F(HeadlessBrowserTest, CreateAndDestroyWebContents) {
  HeadlessBrowserContext* browser_context =
      browser()->CreateBrowserContextBuilder().Build();

  HeadlessWebContents* web_contents =
      browser_context->CreateWebContentsBuilder().Build();
  EXPECT_TRUE(web_contents);

  EXPECT_THAT(browser()->GetAllBrowserContexts(),
              UnorderedElementsAre(browser_context));
  EXPECT_THAT(browser_context->GetAllWebContents(),
              UnorderedElementsAre(web_contents));

  // TODO(skyostil): Verify viewport dimensions once we can.

  web_contents->Close();

  EXPECT_TRUE(browser_context->GetAllWebContents().empty());

  browser_context->Close();

  EXPECT_TRUE(browser()->GetAllBrowserContexts().empty());
}

IN_PROC_BROWSER_TEST_F(HeadlessBrowserTest,
                       WebContentsAreDestroyedWithContext) {
  HeadlessBrowserContext* browser_context =
      browser()->CreateBrowserContextBuilder().Build();

  HeadlessWebContents* web_contents =
      browser_context->CreateWebContentsBuilder().Build();
  EXPECT_TRUE(web_contents);

  EXPECT_THAT(browser()->GetAllBrowserContexts(),
              UnorderedElementsAre(browser_context));
  EXPECT_THAT(browser_context->GetAllWebContents(),
              UnorderedElementsAre(web_contents));

  browser_context->Close();

  EXPECT_TRUE(browser()->GetAllBrowserContexts().empty());

  // If WebContents are not destroyed, Chromium DCHECKs will capture this.
}

IN_PROC_BROWSER_TEST_F(HeadlessBrowserTest, CreateAndDoNotDestroyWebContents) {
  HeadlessBrowserContext* browser_context =
      browser()->CreateBrowserContextBuilder().Build();

  HeadlessWebContents* web_contents =
      browser_context->CreateWebContentsBuilder().Build();
  EXPECT_TRUE(web_contents);

  EXPECT_THAT(browser()->GetAllBrowserContexts(),
              UnorderedElementsAre(browser_context));
  EXPECT_THAT(browser_context->GetAllWebContents(),
              UnorderedElementsAre(web_contents));

  // If WebContents are not destroyed, Chromium DCHECKs will capture this.
}

IN_PROC_BROWSER_TEST_F(HeadlessBrowserTest, DestroyAndCreateTwoWebContents) {
  HeadlessBrowserContext* browser_context1 =
      browser()->CreateBrowserContextBuilder().Build();
  EXPECT_TRUE(browser_context1);
  HeadlessWebContents* web_contents1 =
      browser_context1->CreateWebContentsBuilder().Build();
  EXPECT_TRUE(web_contents1);

  EXPECT_THAT(browser()->GetAllBrowserContexts(),
              UnorderedElementsAre(browser_context1));
  EXPECT_THAT(browser_context1->GetAllWebContents(),
              UnorderedElementsAre(web_contents1));

  HeadlessBrowserContext* browser_context2 =
      browser()->CreateBrowserContextBuilder().Build();
  EXPECT_TRUE(browser_context2);
  HeadlessWebContents* web_contents2 =
      browser_context2->CreateWebContentsBuilder().Build();
  EXPECT_TRUE(web_contents2);

  EXPECT_THAT(browser()->GetAllBrowserContexts(),
              UnorderedElementsAre(browser_context1, browser_context2));
  EXPECT_THAT(browser_context1->GetAllWebContents(),
              UnorderedElementsAre(web_contents1));
  EXPECT_THAT(browser_context2->GetAllWebContents(),
              UnorderedElementsAre(web_contents2));

  browser_context1->Close();

  EXPECT_THAT(browser()->GetAllBrowserContexts(),
              UnorderedElementsAre(browser_context2));
  EXPECT_THAT(browser_context2->GetAllWebContents(),
              UnorderedElementsAre(web_contents2));

  browser_context2->Close();

  EXPECT_TRUE(browser()->GetAllBrowserContexts().empty());
}

IN_PROC_BROWSER_TEST_F(HeadlessBrowserTest, CreateWithBadURL) {
  GURL bad_url("not_valid");

  HeadlessBrowserContext* browser_context =
      browser()->CreateBrowserContextBuilder().Build();

  HeadlessWebContents* web_contents =
      browser_context->CreateWebContentsBuilder()
          .SetInitialURL(bad_url)
          .Build();

  EXPECT_FALSE(web_contents);
  EXPECT_TRUE(browser_context->GetAllWebContents().empty());
}

class HeadlessBrowserTestWithProxy : public HeadlessBrowserTest {
 public:
  HeadlessBrowserTestWithProxy()
      : proxy_server_(net::SpawnedTestServer::TYPE_HTTP,
                      net::SpawnedTestServer::kLocalhost,
                      base::FilePath(FILE_PATH_LITERAL("headless/test/data"))) {
  }

  void SetUp() override {
    ASSERT_TRUE(proxy_server_.Start());
    HeadlessBrowserTest::SetUp();
  }

  void TearDown() override {
    proxy_server_.Stop();
    HeadlessBrowserTest::TearDown();
  }

  net::SpawnedTestServer* proxy_server() { return &proxy_server_; }

 private:
  net::SpawnedTestServer proxy_server_;
};

IN_PROC_BROWSER_TEST_F(HeadlessBrowserTestWithProxy, SetProxyServer) {
  HeadlessBrowserContext* browser_context =
      browser()
          ->CreateBrowserContextBuilder()
          .SetProxyServer(proxy_server()->host_port_pair())
          .Build();

  // Load a page which doesn't actually exist, but for which the our proxy
  // returns valid content anyway.
  HeadlessWebContents* web_contents =
      browser_context->CreateWebContentsBuilder()
          .SetInitialURL(GURL("http://not-an-actual-domain.tld/hello.html"))
          .Build();
  EXPECT_TRUE(WaitForLoad(web_contents));
  EXPECT_THAT(browser()->GetAllBrowserContexts(),
              UnorderedElementsAre(browser_context));
  EXPECT_THAT(browser_context->GetAllWebContents(),
              UnorderedElementsAre(web_contents));
  web_contents->Close();
  EXPECT_TRUE(browser_context->GetAllWebContents().empty());
}

IN_PROC_BROWSER_TEST_F(HeadlessBrowserTest, SetHostResolverRules) {
  EXPECT_TRUE(embedded_test_server()->Start());

  std::string host_resolver_rules =
      base::StringPrintf("MAP not-an-actual-domain.tld 127.0.0.1:%d",
                         embedded_test_server()->host_port_pair().port());

  HeadlessBrowserContext* browser_context =
      browser()
          ->CreateBrowserContextBuilder()
          .SetHostResolverRules(host_resolver_rules)
          .Build();

  // Load a page which doesn't actually exist, but which is turned into a valid
  // address by our host resolver rules.
  HeadlessWebContents* web_contents =
      browser_context->CreateWebContentsBuilder()
          .SetInitialURL(GURL("http://not-an-actual-domain.tld/hello.html"))
          .Build();
  EXPECT_TRUE(web_contents);

  EXPECT_TRUE(WaitForLoad(web_contents));
}

IN_PROC_BROWSER_TEST_F(HeadlessBrowserTest, HttpProtocolHandler) {
  const std::string kResponseBody = "<p>HTTP response body</p>";
  ProtocolHandlerMap protocol_handlers;
  protocol_handlers[url::kHttpScheme] =
      base::MakeUnique<TestProtocolHandler>(kResponseBody);

  HeadlessBrowserContext* browser_context =
      browser()
          ->CreateBrowserContextBuilder()
          .SetProtocolHandlers(std::move(protocol_handlers))
          .Build();

  // Load a page which doesn't actually exist, but which is fetched by our
  // custom protocol handler.
  HeadlessWebContents* web_contents =
      browser_context->CreateWebContentsBuilder()
          .SetInitialURL(GURL("http://not-an-actual-domain.tld/hello.html"))
          .Build();
  EXPECT_TRUE(web_contents);
  EXPECT_TRUE(WaitForLoad(web_contents));

  std::string inner_html;
  EXPECT_TRUE(EvaluateScript(web_contents, "document.body.innerHTML")
                  ->GetResult()
                  ->GetValue()
                  ->GetAsString(&inner_html));
  EXPECT_EQ(kResponseBody, inner_html);
}

IN_PROC_BROWSER_TEST_F(HeadlessBrowserTest, HttpsProtocolHandler) {
  const std::string kResponseBody = "<p>HTTPS response body</p>";
  ProtocolHandlerMap protocol_handlers;
  protocol_handlers[url::kHttpsScheme] =
      base::MakeUnique<TestProtocolHandler>(kResponseBody);

  HeadlessBrowserContext* browser_context =
      browser()
          ->CreateBrowserContextBuilder()
          .SetProtocolHandlers(std::move(protocol_handlers))
          .Build();

  // Load a page which doesn't actually exist, but which is fetched by our
  // custom protocol handler.
  HeadlessWebContents* web_contents =
      browser_context->CreateWebContentsBuilder()
          .SetInitialURL(GURL("https://not-an-actual-domain.tld/hello.html"))
          .Build();
  EXPECT_TRUE(web_contents);
  EXPECT_TRUE(WaitForLoad(web_contents));

  std::string inner_html;
  EXPECT_TRUE(EvaluateScript(web_contents, "document.body.innerHTML")
                  ->GetResult()
                  ->GetValue()
                  ->GetAsString(&inner_html));
  EXPECT_EQ(kResponseBody, inner_html);
}

IN_PROC_BROWSER_TEST_F(HeadlessBrowserTest, WebGLSupported) {
  HeadlessBrowserContext* browser_context =
      browser()->CreateBrowserContextBuilder().Build();

  HeadlessWebContents* web_contents =
      browser_context->CreateWebContentsBuilder().Build();

  bool webgl_supported;
  EXPECT_TRUE(
      EvaluateScript(web_contents,
                     "(document.createElement('canvas').getContext('webgl')"
                     "    instanceof WebGLRenderingContext)")
          ->GetResult()
          ->GetValue()
          ->GetAsBoolean(&webgl_supported));
  EXPECT_TRUE(webgl_supported);
}

IN_PROC_BROWSER_TEST_F(HeadlessBrowserTest, ClipboardCopyPasteText) {
  // Tests copy-pasting text with the clipboard in headless mode.
  ui::Clipboard* clipboard = ui::Clipboard::GetForCurrentThread();
  ASSERT_TRUE(clipboard);
  base::string16 paste_text = base::ASCIIToUTF16("Clippy!");
  for (ui::ClipboardType type :
       {ui::CLIPBOARD_TYPE_COPY_PASTE, ui::CLIPBOARD_TYPE_SELECTION,
        ui::CLIPBOARD_TYPE_DRAG}) {
    if (!ui::Clipboard::IsSupportedClipboardType(type))
      continue;
    {
      ui::ScopedClipboardWriter writer(type);
      writer.WriteText(paste_text);
    }
    base::string16 copy_text;
    clipboard->ReadText(type, &copy_text);
    EXPECT_EQ(paste_text, copy_text);
  }
}

IN_PROC_BROWSER_TEST_F(HeadlessBrowserTest, DefaultSizes) {
  HeadlessBrowserContext* browser_context =
      browser()->CreateBrowserContextBuilder().Build();

  HeadlessWebContents* web_contents =
      browser_context->CreateWebContentsBuilder().Build();

  HeadlessBrowser::Options::Builder builder;
  const HeadlessBrowser::Options kDefaultOptions = builder.Build();

  int screen_width;
  int screen_height;
  int window_width;
  int window_height;

  EXPECT_TRUE(EvaluateScript(web_contents, "screen.width")
                  ->GetResult()
                  ->GetValue()
                  ->GetAsInteger(&screen_width));
  EXPECT_TRUE(EvaluateScript(web_contents, "screen.height")
                  ->GetResult()
                  ->GetValue()
                  ->GetAsInteger(&screen_height));
  EXPECT_TRUE(EvaluateScript(web_contents, "window.innerWidth")
                  ->GetResult()
                  ->GetValue()
                  ->GetAsInteger(&window_width));
  EXPECT_TRUE(EvaluateScript(web_contents, "window.innerHeight")
                  ->GetResult()
                  ->GetValue()
                  ->GetAsInteger(&window_height));

#if !defined(OS_MACOSX)
  // On Mac headless does not override the screen dimensions, so they are
  // left with the actual screen values.
  EXPECT_EQ(kDefaultOptions.window_size.width(), screen_width);
  EXPECT_EQ(kDefaultOptions.window_size.height(), screen_height);
#endif  // !defined(OS_MACOSX)
  EXPECT_EQ(kDefaultOptions.window_size.width(), window_width);
  EXPECT_EQ(kDefaultOptions.window_size.height(), window_height);
}

namespace {

// True if the request method is "safe" (per section 4.2.1 of RFC 7231).
bool IsMethodSafe(const std::string& method) {
  return method == "GET" || method == "HEAD" || method == "OPTIONS" ||
         method == "TRACE";
}

class ProtocolHandlerWithCookies
    : public net::URLRequestJobFactory::ProtocolHandler {
 public:
  explicit ProtocolHandlerWithCookies(net::CookieList* sent_cookies);
  ~ProtocolHandlerWithCookies() override {}

  net::URLRequestJob* MaybeCreateJob(
      net::URLRequest* request,
      net::NetworkDelegate* network_delegate) const override;

 private:
  net::CookieList* sent_cookies_;  // Not owned.

  DISALLOW_COPY_AND_ASSIGN(ProtocolHandlerWithCookies);
};

class URLRequestJobWithCookies : public TestURLRequestJob {
 public:
  URLRequestJobWithCookies(net::URLRequest* request,
                           net::NetworkDelegate* network_delegate,
                           net::CookieList* sent_cookies);
  ~URLRequestJobWithCookies() override {}

  // net::URLRequestJob implementation:
  void Start() override;

 private:
  void SaveCookiesAndStart(const net::CookieList& cookie_list);

  net::CookieList* sent_cookies_;  // Not owned.
  base::WeakPtrFactory<URLRequestJobWithCookies> weak_factory_;
  DISALLOW_COPY_AND_ASSIGN(URLRequestJobWithCookies);
};

ProtocolHandlerWithCookies::ProtocolHandlerWithCookies(
    net::CookieList* sent_cookies)
    : sent_cookies_(sent_cookies) {}

net::URLRequestJob* ProtocolHandlerWithCookies::MaybeCreateJob(
    net::URLRequest* request,
    net::NetworkDelegate* network_delegate) const {
  return new URLRequestJobWithCookies(request, network_delegate, sent_cookies_);
}

URLRequestJobWithCookies::URLRequestJobWithCookies(
    net::URLRequest* request,
    net::NetworkDelegate* network_delegate,
    net::CookieList* sent_cookies)
    // Return an empty response for every request.
    : TestURLRequestJob(request, network_delegate, ""),
      sent_cookies_(sent_cookies),
      weak_factory_(this) {}

void URLRequestJobWithCookies::Start() {
  net::CookieStore* cookie_store = request_->context()->cookie_store();
  net::CookieOptions options;
  options.set_include_httponly();

  // See net::URLRequestHttpJob::AddCookieHeaderAndStart().
  url::Origin requested_origin(request_->url());
  url::Origin site_for_cookies(request_->first_party_for_cookies());

  if (net::registry_controlled_domains::SameDomainOrHost(
          requested_origin, site_for_cookies,
          net::registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES)) {
    if (net::registry_controlled_domains::SameDomainOrHost(
            requested_origin, request_->initiator(),
            net::registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES)) {
      options.set_same_site_cookie_mode(
          net::CookieOptions::SameSiteCookieMode::INCLUDE_STRICT_AND_LAX);
    } else if (IsMethodSafe(request_->method())) {
      options.set_same_site_cookie_mode(
          net::CookieOptions::SameSiteCookieMode::INCLUDE_LAX);
    }
  }
  cookie_store->GetCookieListWithOptionsAsync(
      request_->url(), options,
      base::Bind(&URLRequestJobWithCookies::SaveCookiesAndStart,
                 weak_factory_.GetWeakPtr()));
}

void URLRequestJobWithCookies::SaveCookiesAndStart(
    const net::CookieList& cookie_list) {
  *sent_cookies_ = cookie_list;
  NotifyHeadersComplete();
}

}  // namespace

IN_PROC_BROWSER_TEST_F(HeadlessBrowserTest, ReadCookiesInProtocolHandler) {
  net::CookieList sent_cookies;
  ProtocolHandlerMap protocol_handlers;
  protocol_handlers[url::kHttpsScheme] =
      base::MakeUnique<ProtocolHandlerWithCookies>(&sent_cookies);

  HeadlessBrowserContext* browser_context =
      browser()
          ->CreateBrowserContextBuilder()
          .SetProtocolHandlers(std::move(protocol_handlers))
          .Build();

  HeadlessWebContents* web_contents =
      browser_context->CreateWebContentsBuilder()
          .SetInitialURL(GURL("https://example.com/cookie.html"))
          .Build();
  EXPECT_TRUE(WaitForLoad(web_contents));

  // The first load has no cookies.
  EXPECT_EQ(0u, sent_cookies.size());

  // Set a cookie and reload the page.
  EXPECT_FALSE(EvaluateScript(
                   web_contents,
                   "document.cookie = 'shape=oblong', window.location.reload()")
                   ->HasExceptionDetails());
  EXPECT_TRUE(WaitForLoad(web_contents));

  // We should have sent the cookie this time.
  EXPECT_EQ(1u, sent_cookies.size());
  EXPECT_EQ("shape", sent_cookies[0].Name());
  EXPECT_EQ("oblong", sent_cookies[0].Value());
}

namespace {

class CookieSetter {
 public:
  CookieSetter(HeadlessBrowserTest* browser_test,
               HeadlessWebContents* web_contents,
               std::unique_ptr<network::SetCookieParams> set_cookie_params)
      : browser_test_(browser_test),
        web_contents_(web_contents),
        devtools_client_(HeadlessDevToolsClient::Create()) {
    web_contents_->GetDevToolsTarget()->AttachClient(devtools_client_.get());
    devtools_client_->GetNetwork()->GetExperimental()->SetCookie(
        std::move(set_cookie_params),
        base::Bind(&CookieSetter::OnSetCookieResult, base::Unretained(this)));
  }

  ~CookieSetter() {
    web_contents_->GetDevToolsTarget()->DetachClient(devtools_client_.get());
  }

  void OnSetCookieResult(std::unique_ptr<network::SetCookieResult> result) {
    result_ = std::move(result);
    browser_test_->FinishAsynchronousTest();
  }

  std::unique_ptr<network::SetCookieResult> TakeResult() {
    return std::move(result_);
  }

 private:
  HeadlessBrowserTest* browser_test_;  // Not owned.
  HeadlessWebContents* web_contents_;  // Not owned.
  std::unique_ptr<HeadlessDevToolsClient> devtools_client_;

  std::unique_ptr<network::SetCookieResult> result_;

  DISALLOW_COPY_AND_ASSIGN(CookieSetter);
};

}  // namespace

IN_PROC_BROWSER_TEST_F(HeadlessBrowserTest, SetCookiesWithDevTools) {
  net::CookieList sent_cookies;
  ProtocolHandlerMap protocol_handlers;
  protocol_handlers[url::kHttpsScheme] =
      base::WrapUnique(new ProtocolHandlerWithCookies(&sent_cookies));

  HeadlessBrowserContext* browser_context =
      browser()
          ->CreateBrowserContextBuilder()
          .SetProtocolHandlers(std::move(protocol_handlers))
          .Build();

  HeadlessWebContents* web_contents =
      browser_context->CreateWebContentsBuilder()
          .SetInitialURL(GURL("https://example.com/cookie.html"))
          .Build();
  EXPECT_TRUE(WaitForLoad(web_contents));

  // The first load has no cookies.
  EXPECT_EQ(0u, sent_cookies.size());

  // Set some cookies.
  {
    std::unique_ptr<network::SetCookieParams> set_cookie_params =
        network::SetCookieParams::Builder()
            .SetUrl("https://example.com")
            .SetName("shape")
            .SetValue("oblong")
            .Build();
    CookieSetter cookie_setter(this, web_contents,
                               std::move(set_cookie_params));
    RunAsynchronousTest();
    std::unique_ptr<network::SetCookieResult> result =
        cookie_setter.TakeResult();
    EXPECT_TRUE(result->GetSuccess());
  }
  {
    // Try setting all the fields so we notice if the protocol for any of them
    // changes.
    std::unique_ptr<network::SetCookieParams> set_cookie_params =
        network::SetCookieParams::Builder()
            .SetUrl("https://other.com")
            .SetName("shape")
            .SetValue("trapezoid")
            .SetDomain("other.com")
            .SetPath("")
            .SetSecure(true)
            .SetHttpOnly(true)
            .SetSameSite(network::CookieSameSite::EXACT)
            .SetExpirationDate(0)
            .Build();
    CookieSetter cookie_setter(this, web_contents,
                               std::move(set_cookie_params));
    RunAsynchronousTest();
    std::unique_ptr<network::SetCookieResult> result =
        cookie_setter.TakeResult();
    EXPECT_TRUE(result->GetSuccess());
  }

  // Reload the page.
  EXPECT_FALSE(EvaluateScript(web_contents, "window.location.reload();")
                   ->HasExceptionDetails());
  EXPECT_TRUE(WaitForLoad(web_contents));

  // We should have sent the matching cookies this time.
  EXPECT_EQ(1u, sent_cookies.size());
  EXPECT_EQ("shape", sent_cookies[0].Name());
  EXPECT_EQ("oblong", sent_cookies[0].Value());
}

// TODO(skyostil): This test currently relies on being able to run a shell
// script.
#if defined(OS_POSIX)
IN_PROC_BROWSER_TEST_F(HeadlessBrowserTest, RendererCommandPrefixTest) {
  base::ThreadRestrictions::SetIOAllowed(true);
  base::FilePath launcher_stamp;
  base::CreateTemporaryFile(&launcher_stamp);

  base::FilePath launcher_script;
  FILE* launcher_file = base::CreateAndOpenTemporaryFile(&launcher_script);
  fprintf(launcher_file, "#!/bin/sh\n");
  fprintf(launcher_file, "echo $@ > %s\n", launcher_stamp.value().c_str());
  fprintf(launcher_file, "exec $@\n");
  fclose(launcher_file);
  base::SetPosixFilePermissions(launcher_script,
                                base::FILE_PERMISSION_READ_BY_USER |
                                    base::FILE_PERMISSION_EXECUTE_BY_USER);

  base::CommandLine::ForCurrentProcess()->AppendSwitch("--no-sandbox");
  base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
      "--renderer-cmd-prefix", launcher_script.value());

  EXPECT_TRUE(embedded_test_server()->Start());

  HeadlessBrowserContext* browser_context =
      browser()->CreateBrowserContextBuilder().Build();

  HeadlessWebContents* web_contents =
      browser_context->CreateWebContentsBuilder()
          .SetInitialURL(embedded_test_server()->GetURL("/hello.html"))
          .Build();
  EXPECT_TRUE(WaitForLoad(web_contents));

  // Make sure the launcher was invoked when starting the renderer.
  std::string stamp;
  EXPECT_TRUE(base::ReadFileToString(launcher_stamp, &stamp));
  EXPECT_GE(stamp.find("--type=renderer"), 0u);

  base::DeleteFile(launcher_script, false);
  base::DeleteFile(launcher_stamp, false);
}
#endif  // defined(OS_POSIX)

class CrashReporterTest : public HeadlessBrowserTest,
                          public HeadlessWebContents::Observer,
                          inspector::ExperimentalObserver {
 public:
  CrashReporterTest() : devtools_client_(HeadlessDevToolsClient::Create()) {}
  ~CrashReporterTest() override {}

  void SetUp() override {
    base::ThreadRestrictions::SetIOAllowed(true);
    base::CreateNewTempDirectory(FILE_PATH_LITERAL("CrashReporterTest"),
                                 &crash_dumps_dir_);
    EXPECT_FALSE(options()->enable_crash_reporter);
    options()->enable_crash_reporter = true;
    options()->crash_dumps_dir = crash_dumps_dir_;
    HeadlessBrowserTest::SetUp();
  }

  void TearDown() override {
    base::ThreadRestrictions::SetIOAllowed(true);
    base::DeleteFile(crash_dumps_dir_, /* recursive */ false);
  }

  // HeadlessWebContents::Observer implementation:
  void DevToolsTargetReady() override {
    EXPECT_TRUE(web_contents_->GetDevToolsTarget());
    web_contents_->GetDevToolsTarget()->AttachClient(devtools_client_.get());
    devtools_client_->GetInspector()->GetExperimental()->AddObserver(this);
  }

  // inspector::ExperimentalObserver implementation:
  void OnTargetCrashed(const inspector::TargetCrashedParams&) override {
    FinishAsynchronousTest();
  }

 protected:
  HeadlessBrowserContext* browser_context_ = nullptr;
  HeadlessWebContents* web_contents_ = nullptr;
  std::unique_ptr<HeadlessDevToolsClient> devtools_client_;
  base::FilePath crash_dumps_dir_;
};

// TODO(skyostil): Minidump generation currently is only supported on Linux.
#if defined(HEADLESS_USE_BREAKPAD)
#define MAYBE_GenerateMinidump GenerateMinidump
#else
#define MAYBE_GenerateMinidump DISABLED_GenerateMinidump
#endif  // defined(HEADLESS_USE_BREAKPAD)
IN_PROC_BROWSER_TEST_F(CrashReporterTest, MAYBE_GenerateMinidump) {
  // Navigates a tab to chrome://crash and checks that a minidump is generated.
  // Note that we only test renderer crashes here -- browser crashes need to be
  // tested with a separate harness.
  //
  // The case where crash reporting is disabled is covered by
  // HeadlessCrashObserverTest.
  browser_context_ = browser()->CreateBrowserContextBuilder().Build();

  web_contents_ = browser_context_->CreateWebContentsBuilder()
                      .SetInitialURL(GURL(content::kChromeUICrashURL))
                      .Build();

  web_contents_->AddObserver(this);
  RunAsynchronousTest();

  // The target has crashed and should no longer be there.
  EXPECT_FALSE(web_contents_->GetDevToolsTarget());

  // Check that one minidump got created.
  {
    base::ThreadRestrictions::SetIOAllowed(true);
    base::FileEnumerator it(crash_dumps_dir_, /* recursive */ false,
                            base::FileEnumerator::FILES);
    base::FilePath minidump = it.Next();
    EXPECT_FALSE(minidump.empty());
    EXPECT_EQ(FILE_PATH_LITERAL(".dmp"), minidump.Extension());
    EXPECT_TRUE(it.Next().empty());
  }

  web_contents_->RemoveObserver(this);
  web_contents_->Close();
  web_contents_ = nullptr;

  browser_context_->Close();
  browser_context_ = nullptr;
}

IN_PROC_BROWSER_TEST_F(HeadlessBrowserTest, PermissionManagerAlwaysASK) {
  GURL url("https://example.com");

  HeadlessBrowserContext* browser_context =
      browser()->CreateBrowserContextBuilder().Build();

  HeadlessWebContents* headless_web_contents =
      browser_context->CreateWebContentsBuilder().Build();
  EXPECT_TRUE(headless_web_contents);

  HeadlessWebContentsImpl* web_contents =
      HeadlessWebContentsImpl::From(headless_web_contents);

  content::PermissionManager* permission_manager =
      web_contents->browser_context()->GetPermissionManager();
  EXPECT_NE(nullptr, permission_manager);

  // Check that the permission manager returns ASK for a given permission type.
  EXPECT_EQ(blink::mojom::PermissionStatus::ASK,
            permission_manager->GetPermissionStatus(
                content::PermissionType::NOTIFICATIONS, url, url));
}

}  // namespace headless
