// 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 <utility>

#include "base/functional/bind.h"
#include "base/ranges/algorithm.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/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"
#include "third_party/abseil-cpp/absl/types/optional.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,
    absl::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(ExtensionApiFrameIdMap::kTopFrameId);

  ScriptExecutor::MatchAboutBlank match_about_blank =
      details_->match_about_blank.value_or(false)
          ? ScriptExecutor::MATCH_ABOUT_BLANK
          : ScriptExecutor::DONT_MATCH_ABOUT_BLANK;

  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) {
    absl::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,
        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()->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;
  }
  script_url_ = extension()->GetResourceURL(file);

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

  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 = base::ranges::find(
      results, root_frame_id_, &ScriptExecutor::FrameResult::frame_id);

  DCHECK(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_
