// 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 "chrome/browser/extensions/extension_browser_test_util.h"

#include "base/files/file_util.h"
#include "base/json/json_file_value_serializer.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/threading/thread_restrictions.h"
#include "base/values.h"
#include "extensions/common/api/web_accessible_resources.h"
#include "extensions/common/api/web_accessible_resources_mv2.h"
#include "extensions/common/constants.h"
#include "extensions/common/file_util.h"
#include "extensions/common/manifest_constants.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace extensions::browser_test_util {
namespace {

// Creates a copy of `source` within `temp_dir` and populates `out` with the
// destination path. Returns true on success.
bool CreateTempDirectoryCopy(const base::FilePath& temp_dir,
                             const base::FilePath& source,
                             base::FilePath* out) {
  base::ScopedAllowBlockingForTesting allow_blocking;

  base::FilePath temp_subdir;
  if (!base::CreateTemporaryDirInDir(temp_dir, base::FilePath::StringType(),
                                     &temp_subdir)) {
    ADD_FAILURE() << "Could not create temporary dir for test under "
                  << temp_dir;
    return false;
  }

  // Copy all files from `source` to `temp_subdir`.
  if (!base::CopyDirectory(source, temp_subdir, true /* recursive */)) {
    ADD_FAILURE() << source.value() << " could not be copied to "
                  << temp_subdir.value();
    return false;
  }

  *out = temp_subdir.Append(source.BaseName());
  return true;
}

// Moves match patterns from the `permissions_key` list to the
// `host_permissions_key` list.
void DoMoveHostPermissions(base::Value::Dict& manifest_dict,
                           const char* permissions_key,
                           const char* host_permissions_key) {
  base::Value::List* const permissions =
      manifest_dict.FindList(permissions_key);
  if (!permissions) {
    return;
  }

  // Add the permissions to the appropriate destinations, then update/add
  // the target lists as appropriate.
  base::Value::List permissions_list;
  base::Value::List host_permissions_list;
  for (auto& value : *permissions) {
    CHECK(value.is_string());
    const std::string& str_value = value.GetString();
    if (str_value == "<all_urls>" ||
        str_value.find("://") != std::string::npos) {
      host_permissions_list.Append(std::move(value));
    } else {
      permissions_list.Append(std::move(value));
    }
  }

  if (permissions_list.empty()) {
    manifest_dict.Remove(permissions_key);
  } else {
    *permissions = std::move(permissions_list);
  }

  if (!host_permissions_list.empty()) {
    manifest_dict.Set(host_permissions_key, std::move(host_permissions_list));
  }
}

// Moves match patterns from permissions/optional_permissions to the
// host_permissions/optional_host_permissions.
void MoveHostPermissions(base::Value::Dict& manifest_dict) {
  DoMoveHostPermissions(manifest_dict, manifest_keys::kPermissions,
                        manifest_keys::kHostPermissions);
  DoMoveHostPermissions(manifest_dict, manifest_keys::kOptionalPermissions,
                        manifest_keys::kOptionalHostPermissions);
}

using web_accessible_resource =
    api::web_accessible_resources::WebAccessibleResource;

// Upgrades MV2 format to MV3 format.
void UpgradeWebAccessibleResources(base::Value::Dict& manifest_dict) {
  base::Value::List* const web_accessible_resources = manifest_dict.FindList(
      api::web_accessible_resources::ManifestKeys::kWebAccessibleResources);
  if (!web_accessible_resources) {
    return;
  }

  // Copy all of the entries to a single dictionary entry that matches all
  // URLs.
  auto war_dict = base::Value::Dict()
                      .Set(web_accessible_resource::kResources,
                           web_accessible_resources->Clone())
                      .Set(web_accessible_resource::kMatches,
                           base::Value::List().Append("<all_urls>"));

  // Clear the list and append the dictionary.
  web_accessible_resources->clear();
  web_accessible_resources->Append(std::move(war_dict));
}

// Modifies `manifest_dict` changing its manifest version to 3.
bool ModifyManifestForManifestVersion3(base::Value::Dict& manifest_dict) {
  // This should only be used for manifest v2 extension.
  std::optional<int> current_manifest_version =
      manifest_dict.FindInt(manifest_keys::kManifestVersion);
  if (!current_manifest_version || *current_manifest_version != 2) {
    ADD_FAILURE() << manifest_dict << " should have a manifest version of 2.";
    return false;
  }

  UpgradeWebAccessibleResources(manifest_dict);
  MoveHostPermissions(manifest_dict);

  manifest_dict.Set(manifest_keys::kManifestVersion, 3);

  return true;
}

// Modifies extension at `extension_root` and its `manifest_dict` converting it
// to a service worker based extension.
// NOTE: The conversion works only for extensions with background.scripts and
// requires the background.persistent key. The background.page key is not
// supported.
bool ModifyExtensionForServiceWorker(const base::FilePath& extension_root,
                                     base::Value::Dict& manifest_dict) {
  base::ScopedAllowBlockingForTesting allow_blocking;

  // Retrieve the value of the `background` key and verify that it has
  // the `persistent` key and specifies JS files.
  // Background pages that specify HTML files are not supported.
  base::Value::Dict* background_dict = manifest_dict.FindDict("background");
  if (!background_dict) {
    ADD_FAILURE() << extension_root.value()
                  << " 'background' key not found in manifest.json";
    return false;
  }
  {
    std::optional<bool> background_persistent =
        background_dict->FindBool("persistent");
    if (!background_persistent.has_value()) {
      ADD_FAILURE() << extension_root.value()
                    << ": The \"persistent\" key must be specified to run as a "
                       "Service Worker-based extension.";
      return false;
    }
  }
  base::Value::List* background_scripts_list =
      background_dict->FindList("scripts");
  // Number of JS scripts must be >= 1.
  if (!background_scripts_list || background_scripts_list->empty()) {
    ADD_FAILURE() << extension_root.value()
                  << ": Only extensions with JS script(s) can be loaded "
                     "as a sw-based extension.";
    return false;
  }

  std::string service_worker_script;

  // If there's just one script, use it directly in the "service_worker" key.
  if (background_scripts_list->size() == 1) {
    service_worker_script = (*background_scripts_list)[0].GetString();
  } else {
    // Otherwise, generate a script that uses importScripts() to import
    // all of the scripts.
    service_worker_script = "generated_service_worker__.js";
    std::vector<std::string> script_filenames;
    for (const base::Value& script : *background_scripts_list) {
      script_filenames.push_back(base::StrCat({"'", script.GetString(), "'"}));
    }

    base::FilePath combined_script_filepath =
        extension_root.AppendASCII(service_worker_script);
    // Collision with generated script filename.
    if (base::PathExists(combined_script_filepath)) {
      ADD_FAILURE() << combined_script_filepath.value()
                    << " already exists, make sure " << extension_root.value()
                    << " does not contained file named "
                    << service_worker_script;
      return false;
    }
    std::string generated_sw_script_content = base::StringPrintf(
        "importScripts(%s);", base::JoinString(script_filenames, ",").c_str());
    if (!base::WriteFile(combined_script_filepath,
                         generated_sw_script_content)) {
      ADD_FAILURE() << "Could not write combined Service Worker script to: "
                    << combined_script_filepath.value();
      return false;
    }
  }

  // Remove the existing background specification and replace it with a service
  // worker.
  background_dict->Remove("persistent");
  background_dict->Remove("scripts");
  background_dict->Set("service_worker", std::move(service_worker_script));

  return true;
}

}  // namespace

bool IsServiceWorkerContext(ContextType context_type) {
  return context_type == ContextType::kServiceWorker ||
         context_type == ContextType::kServiceWorkerMV2;
}

bool ModifyExtensionIfNeeded(const LoadOptions& options,
                             ContextType context_type,
                             size_t test_pre_count,
                             const base::FilePath& temp_dir_path,
                             const base::FilePath& input_path,
                             base::FilePath* out_path) {
  base::ScopedAllowBlockingForTesting scoped_allow_blocking;

  const ContextType context_type_to_use =
      options.context_type == ContextType::kNone ? context_type
                                                 : options.context_type;

  // Use context_type_ if LoadOptions.context_type is unspecified.
  // Otherwise, use LoadOptions.context_type.
  const bool load_as_service_worker =
      IsServiceWorkerContext(context_type_to_use);

  // Early return if no modification is needed.
  if (!load_as_service_worker && !options.load_as_manifest_version_3) {
    *out_path = input_path;
    return true;
  }

  // Tests that have a PRE_ stage need to exist in a temporary directory that
  // persists after the test fixture is destroyed. The test bots are configured
  // to use a unique temp directory that's cleaned up after the tests run, so
  // this won't pollute the system tmp directory.
  base::FilePath temp_dir;
  if (test_pre_count == 0) {
    temp_dir = temp_dir_path;
  } else if (!base::GetTempDir(&temp_dir)) {
    ADD_FAILURE() << "Could not get temporary dir for test.";
    return false;
  }

  base::FilePath extension_root;
  if (!CreateTempDirectoryCopy(temp_dir, input_path, &extension_root)) {
    return false;
  }

  std::string error;
  std::optional<base::Value::Dict> manifest_dict =
      extensions::file_util::LoadManifest(extension_root, &error);
  if (!manifest_dict) {
    ADD_FAILURE() << extension_root.value()
                  << " could not load manifest: " << error;
    return false;
  }

  if (load_as_service_worker &&
      !ModifyExtensionForServiceWorker(extension_root, *manifest_dict)) {
    return false;
  }

  const bool is_service_worker_mv3 =
      context_type_to_use == ContextType::kServiceWorker;

  // Update the manifest if converting to a service worker MV3-based
  // extension or if requested in `options`.
  if ((is_service_worker_mv3 || options.load_as_manifest_version_3) &&
      !ModifyManifestForManifestVersion3(*manifest_dict)) {
    return false;
  }

  // Write out manifest.json.
  base::FilePath manifest_path = extension_root.Append(kManifestFilename);
  if (!JSONFileValueSerializer(manifest_path).Serialize(*manifest_dict)) {
    ADD_FAILURE() << "Could not write manifest file to "
                  << manifest_path.value();
    return false;
  }

  *out_path = extension_root;
  return true;
}

}  // namespace extensions::browser_test_util
