// Copyright 2012 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/convert_user_script.h"

#include <stddef.h>

#include <memory>
#include <string>
#include <utility>
#include <vector>

#include "base/base64.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/json/json_file_value_serializer.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/values.h"
#include "chrome/common/chrome_paths.h"
#include "crypto/hash.h"
#include "extensions/browser/extension_user_script_loader.h"
#include "extensions/common/api/content_scripts.h"
#include "extensions/common/constants.h"
#include "extensions/common/extension.h"
#include "extensions/common/file_util.h"
#include "extensions/common/manifest_constants.h"
#include "extensions/common/mojom/run_location.mojom-shared.h"
#include "extensions/common/user_script.h"
#include "extensions/common/utils/extension_types_utils.h"
#include "url/gurl.h"

namespace extensions {

scoped_refptr<Extension> ConvertUserScriptToExtension(
    const base::FilePath& user_script_path,
    const GURL& original_url,
    const base::FilePath& extensions_dir,
    std::u16string* error) {
  using ContentScript = api::content_scripts::ContentScript;

  std::string content;
  if (!base::ReadFileToString(user_script_path, &content)) {
    *error = u"Could not read source file.";
    return nullptr;
  }

  if (!base::IsStringUTF8(content)) {
    *error = u"User script must be UTF8 encoded.";
    return nullptr;
  }

  UserScript script;
  if (!UserScriptLoader::ParseMetadataHeader(content, &script)) {
    *error = u"Invalid script header.";
    return nullptr;
  }

  base::FilePath install_temp_dir =
      file_util::GetInstallTempDir(extensions_dir);
  if (install_temp_dir.empty()) {
    *error = u"Could not get path to profile temporary directory.";
    return nullptr;
  }

  base::ScopedTempDir temp_dir;
  if (!temp_dir.CreateUniqueTempDirUnderPath(install_temp_dir)) {
    *error = u"Could not create temporary directory.";
    return nullptr;
  }

  // Create the manifest
  base::Value::Dict root;
  std::string script_name;
  if (!script.name().empty() && !script.name_space().empty())
    script_name = script.name_space() + "/" + script.name();
  else
    script_name = original_url.spec();

  // Create the public key.
  // User scripts are not signed, but the public key for an extension doubles as
  // its unique identity, and we need one of those. A user script's unique
  // identity is its namespace+name, so we hash that to create a public key.
  // There will be no corresponding private key, which means user scripts cannot
  // be auto-updated, or claimed in the gallery.
  std::string key =
      base::Base64Encode(crypto::hash::Sha256(base::as_byte_span(script_name)));

  // The script may not have a name field, but we need one for an extension. If
  // it is missing, use the filename of the original URL.
  if (!script.name().empty())
    root.Set(manifest_keys::kName, script.name());
  else
    root.Set(manifest_keys::kName, original_url.ExtractFileName());

  // Not all scripts have a version, but we need one. Default to 1.0 if it is
  // missing.
  if (!script.version().empty())
    root.Set(manifest_keys::kVersion, script.version());
  else
    root.Set(manifest_keys::kVersion, "1.0");

  root.Set(manifest_keys::kDescription, script.description());
  root.Set(manifest_keys::kPublicKey, key);
  root.Set(manifest_keys::kConvertedFromUserScript, true);

  // If the script provides its own match patterns, we use those. Otherwise, we
  // generate some using the include globs.
  std::vector<std::string> matches;
  if (!script.url_patterns().is_empty()) {
    matches.reserve(script.url_patterns().size());
    for (const URLPattern& pattern : script.url_patterns())
      matches.push_back(pattern.GetAsString());
  } else {
    // TODO(aa): Derive tighter matches where possible.
    matches.push_back("http://*/*");
    matches.push_back("https://*/*");
  }

  // Read the exclude matches, if any are present.
  std::vector<std::string> exclude_matches;
  exclude_matches.reserve(script.exclude_url_patterns().size());
  for (const URLPattern& pattern : script.exclude_url_patterns())
    exclude_matches.push_back(pattern.GetAsString());

  ContentScript content_script;
  content_script.matches = std::move(matches);
  content_script.exclude_matches = std::move(exclude_matches);
  content_script.include_globs = script.globs();
  content_script.exclude_globs = script.exclude_globs();

  content_script.js.emplace();
  content_script.js->push_back("script.js");

  content_script.run_at = ConvertRunLocationForAPI(script.run_location());

  base::Value::List content_scripts;
  content_scripts.Append(content_script.ToValue());
  root.Set(api::content_scripts::ManifestKeys::kContentScripts,
           std::move(content_scripts));

  base::FilePath manifest_path = temp_dir.GetPath().Append(kManifestFilename);
  JSONFileValueSerializer serializer(manifest_path);
  if (!serializer.Serialize(root)) {
    *error = u"Could not write JSON.";
    return nullptr;
  }

  // Write the script file.
  if (!base::CopyFile(user_script_path,
                      temp_dir.GetPath().AppendASCII("script.js"))) {
    *error = u"Could not copy script file.";
    return nullptr;
  }

  // TODO(rdevlin.cronin): Continue removing std::string errors and replacing
  // with std::u16string
  std::string utf8_error;
  scoped_refptr<Extension> extension =
      Extension::Create(temp_dir.GetPath(), mojom::ManifestLocation::kInternal,
                        root, Extension::NO_FLAGS, &utf8_error);
  *error = base::UTF8ToUTF16(utf8_error);
  if (!extension.get()) {
    NOTREACHED() << "Could not init extension " << *error;
  }

  temp_dir.Take();  // The caller takes ownership of the directory.
  return extension;
}

}  // namespace extensions
