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

#include "base/base64.h"
#include "base/files/file_util.h"
#include "base/task/post_task.h"
#include "base/task/thread_pool.h"
#include "chrome/browser/profiles/profile.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()) << "No 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(Profile* profile) : profile_(profile) {}

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),
                     &base64_svg);

  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(profile_);
    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_->GetMainFrame()->GetProcess()->AddObserver(this);
  }
}

bool SvgIconTranscoder::PrepareWebContents() {
  if (!web_contents_ready_) {
    // Old web_contents_ may have been destroyed.
    MaybeCreateWebContents();
    if (web_contents_->GetMainFrame()->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_->GetMainFrame()) {
    web_contents_->GetMainFrame()->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) {
            std::vector<unsigned char> compressed;
            if (!bitmap.empty() &&
                gfx::PNGCodec::EncodeBGRASkBitmap(bitmap, false, &compressed)) {
              return std::string(compressed.begin(), compressed.end());
            }
            return std::string();
          },
          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
