// Copyright 2017 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 "chrome/browser/devtools/protocol/page_handler.h"

#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/web_applications/web_app_helpers.h"
#include "components/subresource_filter/content/browser/devtools_interaction_tracker.h"
#include "third_party/blink/public/common/features.h"
#include "third_party/blink/public/common/manifest/manifest_util.h"
#include "ui/gfx/image/image.h"

#if BUILDFLAG(ENABLE_PRINTING)
#include "components/printing/browser/print_to_pdf/pdf_print_utils.h"
#endif

#if BUILDFLAG(ENABLE_PRINTING)
template <typename T>
absl::optional<T> OptionalFromMaybe(const protocol::Maybe<T>& maybe) {
  return maybe.isJust() ? absl::optional<T>(maybe.fromJust()) : absl::nullopt;
}
#endif

PageHandler::PageHandler(scoped_refptr<content::DevToolsAgentHost> agent_host,
                         content::WebContents* web_contents,
                         protocol::UberDispatcher* dispatcher)
    : agent_host_(agent_host), web_contents_(web_contents->GetWeakPtr()) {
  protocol::Page::Dispatcher::wire(dispatcher, this);
}

PageHandler::~PageHandler() {
  ToggleAdBlocking(/* enabled= */ false);
}

void PageHandler::ToggleAdBlocking(bool enabled) {
  if (!web_contents_)
    return;

  // Create the DevtoolsInteractionTracker lazily (note that this call is a
  // no-op if the object was already created).
  subresource_filter::DevtoolsInteractionTracker::CreateForWebContents(
      web_contents_.get());

  subresource_filter::DevtoolsInteractionTracker::FromWebContents(
      web_contents_.get())
      ->ToggleForceActivation(enabled);
}

protocol::Response PageHandler::Enable() {
  enabled_ = true;
  // Do not mark the command as handled. Let it fall through instead, so that
  // the handler in content gets a chance to process the command.
  return protocol::Response::FallThrough();
}

protocol::Response PageHandler::Disable() {
  enabled_ = false;
  ToggleAdBlocking(false /* enable */);
  // Do not mark the command as handled. Let it fall through instead, so that
  // the handler in content gets a chance to process the command.
  return protocol::Response::FallThrough();
}

protocol::Response PageHandler::SetAdBlockingEnabled(bool enabled) {
  if (!enabled_)
    return protocol::Response::ServerError("Page domain is disabled.");
  ToggleAdBlocking(enabled);
  return protocol::Response::Success();
}

void PageHandler::GetInstallabilityErrors(
    std::unique_ptr<GetInstallabilityErrorsCallback> callback) {
  auto errors = std::make_unique<protocol::Array<std::string>>();
  webapps::InstallableManager* manager =
      web_contents_
          ? webapps::InstallableManager::FromWebContents(web_contents_.get())
          : nullptr;
  if (!manager) {
    callback->sendFailure(
        protocol::Response::ServerError("Unable to fetch errors for target"));
    return;
  }
  manager->GetAllErrors(base::BindOnce(&PageHandler::GotInstallabilityErrors,
                                       std::move(callback)));
}

// static
void PageHandler::GotInstallabilityErrors(
    std::unique_ptr<GetInstallabilityErrorsCallback> callback,
    std::vector<content::InstallabilityError> installability_errors) {
  auto result_installability_errors =
      std::make_unique<protocol::Array<protocol::Page::InstallabilityError>>();
  for (const auto& installability_error : installability_errors) {
    auto installability_error_arguments = std::make_unique<
        protocol::Array<protocol::Page::InstallabilityErrorArgument>>();
    for (const auto& error_argument :
         installability_error.installability_error_arguments) {
      installability_error_arguments->emplace_back(
          protocol::Page::InstallabilityErrorArgument::Create()
              .SetName(error_argument.name)
              .SetValue(error_argument.value)
              .Build());
    }
    result_installability_errors->emplace_back(
        protocol::Page::InstallabilityError::Create()
            .SetErrorId(installability_error.error_id)
            .SetErrorArguments(std::move(installability_error_arguments))
            .Build());
  }
  callback->sendSuccess(std::move(result_installability_errors));
}

void PageHandler::GetManifestIcons(
    std::unique_ptr<GetManifestIconsCallback> callback) {
  webapps::InstallableManager* manager =
      web_contents_
          ? webapps::InstallableManager::FromWebContents(web_contents_.get())
          : nullptr;

  if (!manager) {
    callback->sendFailure(
        protocol::Response::ServerError("Unable to fetch icons for target"));
    return;
  }

  manager->GetPrimaryIcon(
      base::BindOnce(&PageHandler::GotManifestIcons, std::move(callback)));
}

void PageHandler::GotManifestIcons(
    std::unique_ptr<GetManifestIconsCallback> callback,
    const SkBitmap* primary_icon) {
  protocol::Maybe<protocol::Binary> primaryIconAsBinary;

  if (primary_icon && !primary_icon->empty()) {
    primaryIconAsBinary = std::move(protocol::Binary::fromRefCounted(
        gfx::Image::CreateFrom1xBitmap(*primary_icon).As1xPNGBytes()));
  }

  callback->sendSuccess(std::move(primaryIconAsBinary));
}

void PageHandler::PrintToPDF(protocol::Maybe<bool> landscape,
                             protocol::Maybe<bool> display_header_footer,
                             protocol::Maybe<bool> print_background,
                             protocol::Maybe<double> scale,
                             protocol::Maybe<double> paper_width,
                             protocol::Maybe<double> paper_height,
                             protocol::Maybe<double> margin_top,
                             protocol::Maybe<double> margin_bottom,
                             protocol::Maybe<double> margin_left,
                             protocol::Maybe<double> margin_right,
                             protocol::Maybe<protocol::String> page_ranges,
                             protocol::Maybe<bool> ignore_invalid_page_ranges,
                             protocol::Maybe<protocol::String> header_template,
                             protocol::Maybe<protocol::String> footer_template,
                             protocol::Maybe<bool> prefer_css_page_size,
                             protocol::Maybe<protocol::String> transfer_mode,
                             std::unique_ptr<PrintToPDFCallback> callback) {
  DCHECK(callback);

#if BUILDFLAG(ENABLE_PRINTING)
  if (!web_contents_) {
    callback->sendFailure(
        protocol::Response::ServerError("No web contents to print"));
    return;
  }

  absl::variant<printing::mojom::PrintPagesParamsPtr, std::string>
      print_pages_params = print_to_pdf::GetPrintPagesParams(
          web_contents_->GetMainFrame()->GetLastCommittedURL(),
          OptionalFromMaybe<bool>(landscape),
          OptionalFromMaybe<bool>(display_header_footer),
          OptionalFromMaybe<bool>(print_background),
          OptionalFromMaybe<double>(scale),
          OptionalFromMaybe<double>(paper_width),
          OptionalFromMaybe<double>(paper_height),
          OptionalFromMaybe<double>(margin_top),
          OptionalFromMaybe<double>(margin_bottom),
          OptionalFromMaybe<double>(margin_left),
          OptionalFromMaybe<double>(margin_right),
          OptionalFromMaybe<std::string>(header_template),
          OptionalFromMaybe<std::string>(footer_template),
          OptionalFromMaybe<bool>(prefer_css_page_size));
  if (absl::holds_alternative<std::string>(print_pages_params)) {
    callback->sendFailure(protocol::Response::InvalidParams(
        absl::get<std::string>(print_pages_params)));
    return;
  }

  DCHECK(absl::holds_alternative<printing::mojom::PrintPagesParamsPtr>(
      print_pages_params));

  bool return_as_stream =
      transfer_mode.fromMaybe("") ==
      protocol::Page::PrintToPDF::TransferModeEnum::ReturnAsStream;

  if (auto* print_manager =
          print_to_pdf::PdfPrintManager::FromWebContents(web_contents_.get())) {
    print_manager->PrintToPdf(
        web_contents_->GetMainFrame(), page_ranges.fromMaybe(""),
        ignore_invalid_page_ranges.fromMaybe(false),
        std::move(absl::get<printing::mojom::PrintPagesParamsPtr>(
            print_pages_params)),
        base::BindOnce(&PageHandler::OnPDFCreated,
                       weak_ptr_factory_.GetWeakPtr(), return_as_stream,
                       std::move(callback)));
  } else {
    callback->sendFailure(
        protocol::Response::ServerError("Printing is not available"));
  }
#else
  callback->sendFailure(
      protocol::Response::ServerError("Printing is not enabled"));
#endif  // BUILDFLAG(ENABLE_PRINTING)
}

void PageHandler::GetAppId(std::unique_ptr<GetAppIdCallback> callback) {
  webapps::InstallableManager* manager =
      web_contents_
          ? webapps::InstallableManager::FromWebContents(web_contents_.get())
          : nullptr;

  if (!manager) {
    callback->sendFailure(
        protocol::Response::ServerError("Unable to fetch app id for target"));
    return;
  }

  webapps::InstallableParams params;
  manager->GetData(params, base::BindOnce(&PageHandler::OnDidGetManifest,
                                          weak_ptr_factory_.GetWeakPtr(),
                                          std::move(callback)));
}

void PageHandler::OnDidGetManifest(std::unique_ptr<GetAppIdCallback> callback,
                                   const webapps::InstallableData& data) {
  if (blink::IsEmptyManifest(data.manifest) ||
      !base::FeatureList::IsEnabled(blink::features::kWebAppEnableManifestId)) {
    callback->sendSuccess(protocol::Maybe<protocol::String>(),
                          protocol::Maybe<protocol::String>());
    return;
  }
  absl::optional<std::string> id;
  if (data.manifest.id.has_value()) {
    id = base::UTF16ToUTF8(data.manifest.id.value());
  }
  callback->sendSuccess(
      web_app::GenerateAppIdUnhashed(id, data.manifest.start_url),
      web_app::GenerateRecommendedId(data.manifest.start_url));
}

#if BUILDFLAG(ENABLE_PRINTING)
void PageHandler::OnPDFCreated(
    bool return_as_stream,
    std::unique_ptr<PrintToPDFCallback> callback,
    print_to_pdf::PdfPrintManager::PrintResult print_result,
    scoped_refptr<base::RefCountedMemory> data) {
  if (print_result != print_to_pdf::PdfPrintManager::PRINT_SUCCESS) {
    callback->sendFailure(protocol::Response::ServerError(
        print_to_pdf::PdfPrintManager::PrintResultToString(print_result)));
    return;
  }

  if (return_as_stream) {
    std::string handle = agent_host_->CreateIOStreamFromData(data);
    callback->sendSuccess(protocol::Binary(), handle);
  } else {
    callback->sendSuccess(protocol::Binary::fromRefCounted(data),
                          protocol::Maybe<std::string>());
  }
}
#endif  // BUILDFLAG(ENABLE_PRINTING)
