// Copyright 2021 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/icon_transcoder/svg_icon_transcoder.h"

#include "base/base64.h"
#include "base/containers/span.h"
#include "base/files/file_util.h"
#include "base/strings/string_util.h"
#include "base/strings/string_view_util.h"
#include "base/task/thread_pool.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/web_contents.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "ui/gfx/codec/png_codec.h"

namespace apps {

namespace {

constexpr char kSvgDataUrlPrefix[] = "data:image/svg+xml;base64,";

std::string ReadSvgOnFileThread(base::FilePath svg_path) {
  std::string svg_data;
  if (base::PathExists(svg_path)) {
    base::ReadFileToString(svg_path, &svg_data);
    LOG_IF(ERROR, svg_data.empty()) << "Empty svg data at path " << svg_path;
  }
  return svg_data;
}

void SaveIconOnFileThread(const base::FilePath& icon_path,
                          const std::string& content) {
  DCHECK(!content.empty());

  base::File::Error file_error;
  if (!base::CreateDirectoryAndGetError(icon_path.DirName(), &file_error)) {
    LOG(ERROR) << "Failed to create dir " << icon_path.DirName()
               << " with error " << file_error;
    return;
  }

  if (!base::WriteFile(icon_path, content)) {
    LOG(ERROR) << "Failed to write icon file: " << icon_path;
    if (!base::DeleteFile(icon_path)) {
      LOG(ERROR) << "Couldn't delete broken icon file" << icon_path;
    }
  }
}

}  // namespace

SvgIconTranscoder::SvgIconTranscoder(content::BrowserContext* context)
    : browser_context_(context) {}

SvgIconTranscoder::~SvgIconTranscoder() {
  RemoveObserver();
}

// Reads the svg data at svg_path and invokes the string Transcode method.
// |callback| is invoked with and empty string on failure. Blocking call.
void SvgIconTranscoder::Transcode(const base::FilePath&& svg_path,
                                  const base::FilePath&& png_path,
                                  gfx::Size preferred_size,
                                  IconContentCallback callback) {
  base::ThreadPool::PostTaskAndReplyWithResult(
      FROM_HERE, {base::MayBlock(), base::TaskPriority::BEST_EFFORT},
      base::BindOnce(&ReadSvgOnFileThread, std::move(svg_path)),
      base::BindOnce(
          [](base::WeakPtr<SvgIconTranscoder> weak_this,
             const base::FilePath&& png_path, gfx::Size preferred_size,
             IconContentCallback callback, std::string svg_data) {
            if (weak_this && !svg_data.empty()) {
              weak_this->Transcode(std::move(svg_data), std::move(png_path),
                                   preferred_size, std::move(callback));
              return;
            }

            std::move(callback).Run(std::string());
          },
          GetWeakPtr(), std::move(png_path), preferred_size,
          std::move(callback)));
}

// Validates and trims the svg_data before base64 encoding and dispatching to
// |web_contents_| in a data: URI.  |callback| is invoked with and empty
// string on failure. Blocking call.
void SvgIconTranscoder::Transcode(const std::string& svg_data,
                                  const base::FilePath&& png_path,
                                  gfx::Size preferred_size,
                                  IconContentCallback callback) {
  if (!PrepareWebContents()) {
    LOG(ERROR) << "Can't transcode svg. WebContents not ready.";
    std::move(callback).Run(std::string());
    return;
  }

  auto pos = svg_data.find("<svg");
  if (pos == std::string::npos) {
    LOG(ERROR) << "Invalid data. Couldn't find <svg.";
    std::move(callback).Run(std::string());
    return;
  }
  // Form a data: uri from the svg_data starting at the <svg. Excess ASCII
  // whitespace is also removed.
  std::string base64_svg = base::Base64Encode(
      base::CollapseWhitespaceASCII(svg_data.substr(pos), false));

  GURL data_url(kSvgDataUrlPrefix + base64_svg);

  web_contents_->DownloadImage(
      data_url, /*is_favicon=*/false, preferred_size, /*max_bitmap_size=*/0,
      /*bypass_cache=*/true,
      base::BindOnce(&SvgIconTranscoder::OnDownloadImage, GetWeakPtr(),
                     std::move(png_path), std::move(callback)));
}

void SvgIconTranscoder::MaybeCreateWebContents() {
  if (!web_contents_) {
    auto params = content::WebContents::CreateParams(browser_context_);
    params.initially_hidden = true;
    params.desired_renderer_state =
        content::WebContents::CreateParams::kInitializeAndWarmupRendererProcess;
    web_contents_ = content::WebContents::Create(params);
    // When we observe RenderProcessExited, we will need to recreate.
    web_contents_->GetPrimaryMainFrame()->GetProcess()->AddObserver(this);
  }
}

bool SvgIconTranscoder::PrepareWebContents() {
  if (!web_contents_ready_) {
    // Old web_contents_ may have been destroyed.
    MaybeCreateWebContents();
    if (web_contents_->GetPrimaryMainFrame()->IsRenderFrameLive()) {
      web_contents_ready_ = true;
    }
    VLOG(1) << "web_contents "
            << (web_contents_ready_ ? "ready " : "not ready");
  }
  return web_contents_ready_;
}

void SvgIconTranscoder::RenderProcessReady(content::RenderProcessHost* host) {
  web_contents_ready_ = true;
}

void SvgIconTranscoder::RenderProcessExited(
    content::RenderProcessHost* host,
    const content::ChildProcessTerminationInfo& info) {
  web_contents_ready_ = false;
  RemoveObserver();
  web_contents_.reset();
}

void SvgIconTranscoder::RemoveObserver() {
  if (web_contents_ && web_contents_->GetPrimaryMainFrame()) {
    web_contents_->GetPrimaryMainFrame()->GetProcess()->RemoveObserver(this);
  }
}

// Compresses the first received bitmap and  saves compressed data to
// |png_path| if non-empty. If the file can't be saved, that's not considered
// and error. Next time lucky.
void SvgIconTranscoder::OnDownloadImage(base::FilePath png_path,
                                        IconContentCallback callback,
                                        int id,
                                        int http_status_code,
                                        const GURL& image_url,
                                        const std::vector<SkBitmap>& bitmaps,
                                        const std::vector<gfx::Size>& sizes) {
  if (bitmaps.empty()) {
    VLOG(1) << "status " << http_status_code << " for download id " << id;
    VLOG(1) << "Failed to download image from " << image_url;
    std::move(callback).Run(std::string());
    return;
  }

  const SkBitmap& bitmap = bitmaps[0];

  base::ThreadPool::PostTaskAndReplyWithResult(
      FROM_HERE, {base::MayBlock(), base::TaskPriority::BEST_EFFORT},
      base::BindOnce(
          [](const SkBitmap& bitmap) {
            if (bitmap.empty()) {
              return std::string();
            }
            std::optional<std::vector<uint8_t>> compressed =
                gfx::PNGCodec::EncodeBGRASkBitmap(
                    bitmap, /*discard_transparency=*/false);
            return std::string(base::as_string_view(
                compressed.value_or(std::vector<uint8_t>())));
          },
          bitmap),
      base::BindOnce(
          [](base::FilePath png_path, IconContentCallback callback,
             std::string compressed) {
            if (!compressed.empty() && !png_path.empty()) {
              base::ThreadPool::PostTaskAndReply(
                  FROM_HERE,
                  {base::MayBlock(), base::TaskPriority::BEST_EFFORT},
                  base::BindOnce(&SaveIconOnFileThread, std::move(png_path),
                                 compressed),
                  base::BindOnce(std::move(callback), compressed));
            } else {
              std::move(callback).Run(std::move(compressed));
            }
          },
          std::move(png_path), std::move(callback)));
}

}  // namespace apps
