// Copyright 2021 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 "base/command_line.h"
#include "base/test/scoped_feature_list.h"
#include "chrome/browser/policy/policy_test_utils.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/common/pref_names.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "components/network_session_configurator/common/network_switches.h"
#include "components/policy/core/common/policy_map.h"
#include "components/policy/policy_constants.h"
#include "components/prefs/pref_service.h"
#include "content/public/browser/web_contents.h"
#include "content/public/common/content_features.h"
#include "content/public/test/browser_test.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/content_browser_test_utils.h"
#include "net/test/embedded_test_server/embedded_test_server.h"

namespace policy {

// This is a Chrome test since we need to access the Profile and Preferences.
class ChromeSharedArrayBufferBrowserTest : public PolicyTest {
 public:
  using WebFeature = blink::mojom::WebFeature;

  ChromeSharedArrayBufferBrowserTest() {
    feature_list_.InitWithFeatures(
        // Enabled:
        {},
        // Disabled:
        {
            features::kSharedArrayBuffer,
            features::kSharedArrayBufferOnDesktop,
        });
  }

  content::WebContents* web_contents() const {
    return browser()->tab_strip_model()->GetActiveWebContents();
  }

  void SetPolicyAndRestartBrowser() {
    // The preference is false by default.
    EXPECT_FALSE(browser()->profile()->GetPrefs()->GetBoolean(
        prefs::kSharedArrayBufferUnrestrictedAccessAllowed));

    PolicyMap policies;
    policies.Set(key::kSharedArrayBufferUnrestrictedAccessAllowed,
                 POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD,
                 base::Value(true), nullptr);
    UpdateProviderPolicy(policies);

    // Now the preference should be true.
    EXPECT_TRUE(browser()->profile()->GetPrefs()->GetBoolean(
        prefs::kSharedArrayBufferUnrestrictedAccessAllowed));

    // The old browser has already created the ContentBrowserClient which reads
    // the preference, so it can't create renderers with SABs enabled by policy.
    // Create a new browser that will pick up the preference and enable SABs for
    // new renderer processes.
    Browser* new_browser = CreateBrowser(browser()->profile());
    CloseBrowserSynchronously(browser());
    SelectFirstBrowser();
    ASSERT_EQ(browser(), new_browser);

    // Navigate the new browser to 'localhost', so the tests will get new
    // renderer processes when they navigate to xxx.com origins.
    GURL local_host = embedded_test_server()->GetURL("/empty.html");
    EXPECT_TRUE(NavigateToURL(web_contents(), local_host));
  }

 private:
  void SetUpOnMainThread() final {
    PolicyTest::SetUpOnMainThread();

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

    ASSERT_FALSE(base::FeatureList::IsEnabled(features::kSharedArrayBuffer));
    ASSERT_FALSE(
        base::FeatureList::IsEnabled(features::kSharedArrayBufferOnDesktop));
  }

  void SetUpCommandLine(base::CommandLine* command_line) final {
    PolicyTest::SetUpCommandLine(command_line);
    command_line->AppendSwitch(switches::kIgnoreCertificateErrors);
  }

  base::test::ScopedFeatureList feature_list_;
};

IN_PROC_BROWSER_TEST_F(ChromeSharedArrayBufferBrowserTest,
                       PolicyEnablesSabConstructor) {
  SetPolicyAndRestartBrowser();

  GURL url = embedded_test_server()->GetURL("a.com", "/empty.html");
  EXPECT_TRUE(NavigateToURL(web_contents(), url));
  EXPECT_EQ(true, content::EvalJs(web_contents(),
                                  "'SharedArrayBuffer' in globalThis"));
}

IN_PROC_BROWSER_TEST_F(ChromeSharedArrayBufferBrowserTest,
                       NoPolicyNoSabConstructor) {
  GURL url = embedded_test_server()->GetURL("a.com", "/empty.html");
  EXPECT_TRUE(NavigateToURL(web_contents(), url));
  EXPECT_EQ(false, content::EvalJs(web_contents(),
                                   "'SharedArrayBuffer' in globalThis"));
}

IN_PROC_BROWSER_TEST_F(ChromeSharedArrayBufferBrowserTest,
                       PolicyEnablesSharing) {
  SetPolicyAndRestartBrowser();

  GURL main_url = embedded_test_server()->GetURL("a.com", "/empty.html");
  GURL sub_url = embedded_test_server()->GetURL("a.com", "/empty.html");

  EXPECT_TRUE(content::NavigateToURL(web_contents(), main_url));
  content::RenderFrameHost* main_document = web_contents()->GetMainFrame();

  EXPECT_TRUE(content::ExecJs(main_document, content::JsReplace(R"(
    g_sab_size = new Promise(resolve => {
      addEventListener("message", event => resolve(event.data.byteLength));
    });

    g_iframe = document.createElement('iframe');
    g_iframe.src = $1;
    document.body.appendChild(g_iframe);
  )",
                                                                sub_url)));
  WaitForLoadStop(web_contents());
  content::RenderFrameHost* sub_document = ChildFrameAt(main_document, 0);

  EXPECT_EQ(false, EvalJs(main_document, "self.crossOriginIsolated"));
  EXPECT_EQ(false, EvalJs(sub_document, "self.crossOriginIsolated"));

  EXPECT_TRUE(ExecJs(sub_document, R"(
    let sab = new SharedArrayBuffer(1234);
    parent.postMessage(sab, "*");
  )"));

  EXPECT_EQ(1234, EvalJs(main_document, "g_sab_size"));
}

IN_PROC_BROWSER_TEST_F(ChromeSharedArrayBufferBrowserTest, NoPolicyNoSharing) {
  GURL main_url = embedded_test_server()->GetURL("a.com", "/empty.html");
  GURL sub_url = embedded_test_server()->GetURL("a.com", "/empty.html");

  EXPECT_TRUE(content::NavigateToURL(web_contents(), main_url));
  content::RenderFrameHost* main_document = web_contents()->GetMainFrame();

  EXPECT_TRUE(content::ExecJs(web_contents(), content::JsReplace(R"(
    g_sab_size = new Promise(resolve => {
      addEventListener("message", event => resolve(event.data.byteLength));
    });

    g_iframe = document.createElement('iframe');
    g_iframe.src = $1;
    document.body.appendChild(g_iframe);
  )",
                                                                 sub_url)));
  WaitForLoadStop(web_contents());
  content::RenderFrameHost* sub_document = ChildFrameAt(main_document, 0);

  EXPECT_EQ(false, EvalJs(main_document, "self.crossOriginIsolated"));
  EXPECT_EQ(false, EvalJs(sub_document, "self.crossOriginIsolated"));

  auto postSharedArrayBuffer = EvalJs(main_document, R"(
    // Create a WebAssembly Memory to bypass the SAB constructor restriction.
    const sab =
        new WebAssembly.Memory({ shared:true, initial:1, maximum:1 }).buffer;
    g_iframe.contentWindow.postMessage(sab,"*");
  )");
  EXPECT_THAT(
      postSharedArrayBuffer.error,
      testing::HasSubstr("Failed to execute 'postMessage' on 'Window': "));
}

}  // namespace policy
