// Copyright 2014 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef EXTENSIONS_BROWSER_API_EXECUTE_CODE_FUNCTION_IMPL_H_
#define EXTENSIONS_BROWSER_API_EXECUTE_CODE_FUNCTION_IMPL_H_

#include "extensions/browser/api/execute_code_function.h"

#include <algorithm>
#include <optional>
#include <utility>

#include "base/functional/bind.h"
#include "base/strings/escape.h"
#include "base/strings/string_util.h"
#include "extensions/browser/extension_api_frame_id_map.h"
#include "extensions/browser/extensions_browser_client.h"
#include "extensions/browser/load_and_localize_file.h"
#include "extensions/browser/safe_browsing_delegate.h"
#include "extensions/common/error_utils.h"
#include "extensions/common/extension.h"
#include "extensions/common/extension_resource.h"
#include "extensions/common/mojom/css_origin.mojom-shared.h"
#include "extensions/common/mojom/run_location.mojom-shared.h"
#include "extensions/common/utils/content_script_utils.h"
#include "extensions/common/utils/extension_types_utils.h"

namespace {

// Error messages
const char kNoCodeOrFileToExecuteError[] = "No source code or file specified.";
const char kMoreThanOneValuesError[] =
    "Code and file should not be specified "
    "at the same time in the second argument.";
const char kBadFileEncodingError[] =
    "Could not load file '*' for content script. It isn't UTF-8 encoded.";
const char kCSSOriginForNonCSSError[] =
    "CSS origin should be specified only for CSS code.";

}

namespace extensions {

using api::extension_types::InjectDetails;

ExecuteCodeFunction::ExecuteCodeFunction() {
}

ExecuteCodeFunction::~ExecuteCodeFunction() {
}

void ExecuteCodeFunction::DidLoadAndLocalizeFile(
    const std::string& file,
    std::vector<std::unique_ptr<std::string>> data,
    std::optional<std::string> load_error) {
  if (load_error) {
    // TODO(viettrungluu): bug: there's no particular reason the path should be
    // UTF-8, in which case this may fail.
    Respond(Error(std::move(*load_error)));
    return;
  }

  DCHECK_EQ(1u, data.size());
  auto& file_data = data.front();
  if (!base::IsStringUTF8(*file_data)) {
    Respond(Error(ErrorUtils::FormatErrorMessage(kBadFileEncodingError, file)));
    return;
  }

  std::string error;
  if (!Execute(*file_data, &error))
    Respond(Error(std::move(error)));

  // If Execute() succeeds, the function will respond in
  // OnExecuteCodeFinished().
}

bool ExecuteCodeFunction::Execute(const std::string& code_string,
                                  std::string* error) {
  ScriptExecutor* executor = GetScriptExecutor(error);
  if (!executor)
    return false;

  // TODO(lazyboy): Set |error|?
  if (!extension() && !IsWebView())
    return false;

  DCHECK(!(ShouldInsertCSS() && ShouldRemoveCSS()));

  ScriptExecutor::FrameScope frame_scope =
      details_->all_frames.value_or(false) ? ScriptExecutor::INCLUDE_SUB_FRAMES
                                           : ScriptExecutor::SPECIFIED_FRAMES;

  root_frame_id_ = details_->frame_id.value_or(GetRootFrameId());

  mojom::MatchOriginAsFallbackBehavior match_about_blank =
      details_->match_about_blank.value_or(false)
          ? mojom::MatchOriginAsFallbackBehavior::
                kMatchForAboutSchemeAndClimbTree
          : mojom::MatchOriginAsFallbackBehavior::kNever;

  mojom::RunLocation run_at = ConvertRunLocation(details_->run_at);

  mojom::CSSOrigin css_origin = mojom::CSSOrigin::kAuthor;
  switch (details_->css_origin) {
    case api::extension_types::CSSOrigin::kNone:
    case api::extension_types::CSSOrigin::kAuthor:
      css_origin = mojom::CSSOrigin::kAuthor;
      break;
    case api::extension_types::CSSOrigin::kUser:
      css_origin = mojom::CSSOrigin::kUser;
      break;
  }

  mojom::CodeInjectionPtr injection;
  bool is_css_injection = ShouldInsertCSS() || ShouldRemoveCSS();
  if (is_css_injection) {
    std::optional<std::string> injection_key;
    if (host_id_.type == mojom::HostID::HostType::kExtensions) {
      injection_key = ScriptExecutor::GenerateInjectionKey(
          host_id_, script_url_, code_string);
    }
    mojom::CSSInjection::Operation operation =
        ShouldInsertCSS() ? mojom::CSSInjection::Operation::kAdd
                          : mojom::CSSInjection::Operation::kRemove;
    std::vector<mojom::CSSSourcePtr> sources;
    sources.push_back(
        mojom::CSSSource::New(code_string, std::move(injection_key)));
    injection = mojom::CodeInjection::NewCss(
        mojom::CSSInjection::New(std::move(sources), css_origin, operation));
  } else {
    bool wants_result = has_callback();
    std::vector<mojom::JSSourcePtr> sources;
    sources.push_back(mojom::JSSource::New(code_string, script_url_));
    // tabs.executeScript does not support waiting for promises (only
    // scripting.executeScript does).
    injection = mojom::CodeInjection::NewJs(mojom::JSInjection::New(
        std::move(sources), mojom::ExecutionWorld::kIsolated,
        /*world_id=*/std::nullopt,
        wants_result ? blink::mojom::WantResultOption::kWantResult
                     : blink::mojom::WantResultOption::kNoResult,
        user_gesture() ? blink::mojom::UserActivationOption::kActivate
                       : blink::mojom::UserActivationOption::kDoNotActivate,
        blink::mojom::PromiseResultOption::kDoNotWait));
  }

  executor->ExecuteScript(
      host_id_, std::move(injection), frame_scope, {root_frame_id_},
      match_about_blank, run_at,
      IsWebView() ? ScriptExecutor::WEB_VIEW_PROCESS
                  : ScriptExecutor::DEFAULT_PROCESS,
      GetWebViewSrc(),
      base::BindOnce(&ExecuteCodeFunction::OnExecuteCodeFinished, this));
  return true;
}

ExtensionFunction::ResponseAction ExecuteCodeFunction::Run() {
  InitResult init_result = Init();
  EXTENSION_FUNCTION_VALIDATE(init_result != VALIDATION_FAILURE);
  if (init_result == FAILURE)
    return RespondNow(Error(init_error_.value_or(kUnknownErrorDoNotUse)));

  if (!details_->code && !details_->file)
    return RespondNow(Error(kNoCodeOrFileToExecuteError));

  if (details_->code && details_->file)
    return RespondNow(Error(kMoreThanOneValuesError));

  if (details_->css_origin != api::extension_types::CSSOrigin::kNone &&
      !ShouldInsertCSS() && !ShouldRemoveCSS()) {
    return RespondNow(Error(kCSSOriginForNonCSSError));
  }

  std::string error;
  if (!CanExecuteScriptOnPage(&error))
    return RespondNow(Error(std::move(error)));

  if (details_->code) {
    if (!IsWebView() && extension()) {
      ExtensionsBrowserClient::Get()
          ->GetSafeBrowsingDelegate()
          ->NotifyExtensionApiTabExecuteScript(browser_context(),
                                               extension_id(), *details_->code);
    }

    if (!Execute(*details_->code, &error))
      return RespondNow(Error(std::move(error)));
    return did_respond() ? AlreadyResponded() : RespondLater();
  }

  DCHECK(details_->file);
  if (!LoadFile(*details_->file, &error))
    return RespondNow(Error(std::move(error)));

  // LoadFile will respond asynchronously later.
  return RespondLater();
}

bool ExecuteCodeFunction::LoadFile(const std::string& file,
                                   std::string* error) {
  ExtensionResource resource = extension()->GetResource(file);
  if (resource.extension_root().empty() || resource.relative_path().empty()) {
    *error = kNoCodeOrFileToExecuteError;
    return false;
  }

  bool is_css_injection = ShouldInsertCSS() || ShouldRemoveCSS();

  if (!script_parsing::ValidateMimeTypeFromFileExtension(
          resource.relative_path(),
          is_css_injection ? script_parsing::ContentScriptType::kCss
                           : script_parsing::ContentScriptType::kJs,
          error)) {
    return false;
  }

  script_url_ = extension()->GetResourceURL(base::EscapePath(file));

  bool might_require_localization = is_css_injection;

  std::string relative_path = resource.relative_path().AsUTF8Unsafe();
  LoadAndLocalizeResources(
      *extension(), {std::move(resource)}, might_require_localization,
      script_parsing::GetMaxScriptLength(),
      base::BindOnce(&ExecuteCodeFunction::DidLoadAndLocalizeFile, this,
                     relative_path));

  return true;
}

void ExecuteCodeFunction::OnExecuteCodeFinished(
    std::vector<ScriptExecutor::FrameResult> results) {
  DCHECK(!results.empty());

  auto root_frame_result = std::ranges::find(
      results, root_frame_id_, &ScriptExecutor::FrameResult::frame_id);

  CHECK(root_frame_result != results.end());

  // We just error out if we never injected in the root frame.
  // TODO(devlin): That's a bit odd, because other injections may have
  // succeeded. It seems like it might be worth passing back the values
  // anyway.
  if (!root_frame_result->error.empty()) {
    // If the frame never responded (e.g. the frame was removed or didn't
    // exist), we provide a different error message for backwards
    // compatibility.
    if (!root_frame_result->frame_responded) {
      root_frame_result->error =
          root_frame_id_ == ExtensionApiFrameIdMap::kTopFrameId
              ? "The tab was closed."
              : "The frame was removed.";
    }

    Respond(Error(std::move(root_frame_result->error)));
    return;
  }

  if (ShouldInsertCSS() || ShouldRemoveCSS()) {
    // insertCSS and removeCSS don't have a result argument.
    Respond(NoArguments());
    return;
  }

  // Place the root frame result at the beginning.
  std::iter_swap(root_frame_result, results.begin());
  base::Value::List result_list;
  for (auto& result : results) {
    if (result.error.empty())
      result_list.Append(std::move(result.value));
  }

  Respond(WithArguments(std::move(result_list)));
}

}  // namespace extensions

#endif  // EXTENSIONS_BROWSER_API_EXECUTE_CODE_FUNCTION_IMPL_H_
