// Copyright 2014 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 "extensions/renderer/programmatic_script_injector.h"

#include <utility>
#include <vector>

#include "base/values.h"
#include "content/public/common/url_constants.h"
#include "content/public/renderer/render_frame.h"
#include "extensions/common/error_utils.h"
#include "extensions/common/extension_messages.h"
#include "extensions/common/manifest_constants.h"
#include "extensions/common/permissions/api_permission.h"
#include "extensions/common/permissions/permissions_data.h"
#include "extensions/renderer/injection_host.h"
#include "extensions/renderer/renderer_extension_registry.h"
#include "extensions/renderer/script_context.h"
#include "third_party/blink/public/platform/web_string.h"
#include "third_party/blink/public/web/web_document.h"
#include "third_party/blink/public/web/web_local_frame.h"
#include "third_party/blink/public/web/web_script_source.h"

namespace extensions {

ProgrammaticScriptInjector::ProgrammaticScriptInjector(
    const ExtensionMsg_ExecuteCode_Params& params)
    : params_(new ExtensionMsg_ExecuteCode_Params(params)),
      finished_(false) {
}

ProgrammaticScriptInjector::~ProgrammaticScriptInjector() {
}

UserScript::InjectionType ProgrammaticScriptInjector::script_type()
    const {
  return UserScript::PROGRAMMATIC_SCRIPT;
}

bool ProgrammaticScriptInjector::ShouldExecuteInMainWorld() const {
  return params_->in_main_world;
}

bool ProgrammaticScriptInjector::IsUserGesture() const {
  return params_->user_gesture;
}

base::Optional<CSSOrigin> ProgrammaticScriptInjector::GetCssOrigin() const {
  return params_->css_origin;
}

const base::Optional<std::string>
ProgrammaticScriptInjector::GetInjectionKey() const {
  return params_->injection_key;
}

bool ProgrammaticScriptInjector::ExpectsResults() const {
  return params_->wants_result;
}

bool ProgrammaticScriptInjector::ShouldInjectJs(
    UserScript::RunLocation run_location,
    const std::set<std::string>& executing_scripts) const {
  return params_->run_at == run_location && params_->is_javascript;
}

bool ProgrammaticScriptInjector::ShouldInjectCss(
    UserScript::RunLocation run_location,
    const std::set<std::string>& injected_stylesheets) const {
  return params_->run_at == run_location && !params_->is_javascript;
}

PermissionsData::PageAccess ProgrammaticScriptInjector::CanExecuteOnFrame(
    const InjectionHost* injection_host,
    blink::WebLocalFrame* frame,
    int tab_id) {
  // Note: we calculate url_ now and not in the constructor because with
  // PlzNavigate we won't have the URL at that point when loads start. The
  // browser issues the request and only when it has a response does the
  // renderer see the provisional data source which the method below uses.
  url_ = ScriptContext::GetDocumentLoaderURLForFrame(frame);
  if (url_.SchemeIs(url::kAboutScheme)) {
    origin_for_about_error_ = frame->GetSecurityOrigin().ToString().Utf8();
  }
  GURL effective_document_url = ScriptContext::GetEffectiveDocumentURL(
      frame, frame->GetDocument().Url(), params_->match_about_blank);
  if (params_->is_web_view) {
    if (frame->Parent()) {
      // This is a subframe inside <webview>, so allow it.
      return PermissionsData::PageAccess::kAllowed;
    }

    return effective_document_url == params_->webview_src
               ? PermissionsData::PageAccess::kAllowed
               : PermissionsData::PageAccess::kDenied;
  }
  DCHECK_EQ(injection_host->id().type(), HostID::EXTENSIONS);

  return injection_host->CanExecuteOnFrame(
      effective_document_url,
      content::RenderFrame::FromWebFrame(frame),
      tab_id,
      true /* is_declarative */);
}

std::vector<blink::WebScriptSource> ProgrammaticScriptInjector::GetJsSources(
    UserScript::RunLocation run_location,
    std::set<std::string>* executing_scripts,
    size_t* num_injected_js_scripts) const {
  DCHECK_EQ(params_->run_at, run_location);
  DCHECK(params_->is_javascript);

  return std::vector<blink::WebScriptSource>(
      1, blink::WebScriptSource(blink::WebString::FromUTF8(params_->code),
                                params_->file_url));
}

std::vector<blink::WebString> ProgrammaticScriptInjector::GetCssSources(
    UserScript::RunLocation run_location,
    std::set<std::string>* injected_stylesheets,
    size_t* num_injected_stylesheets) const {
  DCHECK_EQ(params_->run_at, run_location);
  DCHECK(!params_->is_javascript);

  return std::vector<blink::WebString>(
      1, blink::WebString::FromUTF8(params_->code));
}

void ProgrammaticScriptInjector::OnInjectionComplete(
    std::unique_ptr<base::Value> execution_result,
    UserScript::RunLocation run_location,
    content::RenderFrame* render_frame) {
  DCHECK(results_.empty());
  if (execution_result)
    results_.Append(std::move(execution_result));
  Finish(std::string(), render_frame);
}

void ProgrammaticScriptInjector::OnWillNotInject(
    InjectFailureReason reason,
    content::RenderFrame* render_frame) {
  std::string error;
  switch (reason) {
    case NOT_ALLOWED:
      if (!CanShowUrlInError()) {
        error = manifest_errors::kCannotAccessPage;
      } else if (!origin_for_about_error_.empty()) {
        error = ErrorUtils::FormatErrorMessage(
            manifest_errors::kCannotAccessAboutUrl, url_.spec(),
            origin_for_about_error_);
      } else {
        error = ErrorUtils::FormatErrorMessage(
            manifest_errors::kCannotAccessPageWithUrl, url_.spec());
      }
      break;
    case EXTENSION_REMOVED:  // no special error here.
    case WONT_INJECT:
      break;
  }
  Finish(error, render_frame);
}

bool ProgrammaticScriptInjector::CanShowUrlInError() const {
  if (params_->host_id.type() != HostID::EXTENSIONS)
    return false;
  const Extension* extension =
      RendererExtensionRegistry::Get()->GetByID(params_->host_id.id());
  if (!extension)
    return false;
  return extension->permissions_data()->active_permissions().HasAPIPermission(
      APIPermission::kTab);
}

void ProgrammaticScriptInjector::Finish(const std::string& error,
                                        content::RenderFrame* render_frame) {
  DCHECK(!finished_);
  finished_ = true;

  // It's possible that the render frame was destroyed in the course of
  // injecting scripts. Don't respond if it was (the browser side watches for
  // frame deletions so nothing is left hanging).
  if (render_frame) {
    render_frame->Send(
        new ExtensionHostMsg_ExecuteCodeFinished(
            render_frame->GetRoutingID(), params_->request_id,
            error, url_, results_));
  }
}

}  // namespace extensions
