// Copyright 2015 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 "third_party/blink/renderer/modules/image_downloader/image_downloader_impl.h"

#include <utility>

#include "base/bind.h"
#include "base/check.h"
#include "skia/ext/image_operations.h"
#include "third_party/blink/public/mojom/fetch/fetch_api_request.mojom-blink.h"
#include "third_party/blink/public/platform/interface_registry.h"
#include "third_party/blink/public/platform/web_data.h"
#include "third_party/blink/public/platform/web_size.h"
#include "third_party/blink/public/platform/web_string.h"
#include "third_party/blink/public/platform/web_vector.h"
#include "third_party/blink/public/web/web_image.h"
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/frame/local_dom_window.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/modules/image_downloader/multi_resolution_image_resource_fetcher.h"
#include "third_party/blink/renderer/platform/heap/visitor.h"
#include "third_party/blink/renderer/platform/network/network_utils.h"
#include "third_party/blink/renderer/platform/weborigin/kurl.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"
#include "ui/gfx/geometry/size.h"

namespace {

WTF::Vector<SkBitmap> DecodeImageData(const std::string& data,
                                      const std::string& mime_type,
                                      const blink::WebSize& preferred_size) {
  // Decode the image using Blink's image decoder.
  blink::WebData buffer(data.data(), data.size());
  WTF::Vector<SkBitmap> bitmaps;
  if (mime_type == "image/svg+xml") {
    SkBitmap bitmap = blink::WebImage::DecodeSVG(buffer, preferred_size);
    if (!bitmap.drawsNothing())
      bitmaps.push_back(bitmap);
  } else {
    blink::WebVector<SkBitmap> original_bitmaps =
        blink::WebImage::FramesFromData(buffer);
    bitmaps.AppendRange(std::make_move_iterator(original_bitmaps.begin()),
                        std::make_move_iterator(original_bitmaps.end()));
    bitmaps.Reverse();
  }
  return bitmaps;
}

// Decodes a data: URL into one or more images, or no images in case of failure.
WTF::Vector<SkBitmap> ImagesFromDataUrl(const blink::KURL& url,
                                        const blink::WebSize& preferred_size) {
  std::string mime_type, data;
  if (!blink::network_utils::IsDataURLMimeTypeSupported(url, &data,
                                                        &mime_type) ||
      data.empty())
    return WTF::Vector<SkBitmap>();
  return DecodeImageData(data, mime_type, preferred_size);
}

//  Proportionally resizes the |image| to fit in a box of size
// |max_image_size|.
SkBitmap ResizeImage(const SkBitmap& image, uint32_t max_image_size) {
  if (max_image_size == 0)
    return image;
  uint32_t max_dimension = std::max(image.width(), image.height());
  if (max_dimension <= max_image_size)
    return image;
  // Proportionally resize the minimal image to fit in a box of size
  // max_image_size.
  return skia::ImageOperations::Resize(
      image, skia::ImageOperations::RESIZE_BEST,
      static_cast<uint32_t>(image.width()) * max_image_size / max_dimension,
      static_cast<uint32_t>(image.height()) * max_image_size / max_dimension);
}

// Filters the array of bitmaps, removing all images that do not fit in a box of
// size |max_image_size|. Returns the result if it is not empty. Otherwise,
// find the smallest image in the array and resize it proportionally to fit
// in a box of size |max_image_size|.
// Sets |original_image_sizes| to the sizes of |images| before resizing. Both
// output vectors are guaranteed to have the same size.
void FilterAndResizeImagesForMaximalSize(
    const WTF::Vector<SkBitmap>& unfiltered,
    uint32_t max_image_size,
    WTF::Vector<SkBitmap>* images,
    WTF::Vector<gfx::Size>* original_image_sizes) {
  images->clear();
  original_image_sizes->clear();

  if (unfiltered.IsEmpty())
    return;

  if (max_image_size == 0)
    max_image_size = std::numeric_limits<uint32_t>::max();

  const SkBitmap* min_image = nullptr;
  uint32_t min_image_size = std::numeric_limits<uint32_t>::max();
  // Filter the images by |max_image_size|, and also identify the smallest image
  // in case all the images are bigger than |max_image_size|.
  for (auto* it = unfiltered.begin(); it != unfiltered.end(); ++it) {
    const SkBitmap& image = *it;
    uint32_t current_size = std::max(it->width(), it->height());
    if (current_size < min_image_size) {
      min_image = &image;
      min_image_size = current_size;
    }
    if (static_cast<uint32_t>(image.width()) <= max_image_size &&
        static_cast<uint32_t>(image.height()) <= max_image_size) {
      images->push_back(image);
      original_image_sizes->push_back(gfx::Size(image.width(), image.height()));
    }
  }
  DCHECK(min_image);
  if (images->size())
    return;
  // Proportionally resize the minimal image to fit in a box of size
  // |max_image_size|.
  SkBitmap resized = ResizeImage(*min_image, max_image_size);
  // Drop null or empty SkBitmap.
  if (resized.drawsNothing())
    return;
  images->push_back(resized);
  original_image_sizes->push_back(
      gfx::Size(min_image->width(), min_image->height()));
}

}  // namespace

namespace blink {

// static
const char ImageDownloaderImpl::kSupplementName[] = "ImageDownloader";

// static
ImageDownloaderImpl* ImageDownloaderImpl::From(LocalFrame& frame) {
  return Supplement<LocalFrame>::From<ImageDownloaderImpl>(frame);
}

// static
void ImageDownloaderImpl::ProvideTo(LocalFrame& frame) {
  if (ImageDownloaderImpl::From(frame))
    return;
  Supplement<LocalFrame>::ProvideTo(
      frame, MakeGarbageCollected<ImageDownloaderImpl>(frame));
}

ImageDownloaderImpl::ImageDownloaderImpl(LocalFrame& frame)
    : Supplement<LocalFrame>(frame),
      ExecutionContextLifecycleObserver(frame.DomWindow()),
      receiver_(this, frame.DomWindow()) {
  frame.GetInterfaceRegistry()->AddInterface(WTF::BindRepeating(
      &ImageDownloaderImpl::CreateMojoService, WrapWeakPersistent(this)));
}

ImageDownloaderImpl::~ImageDownloaderImpl() {}

void ImageDownloaderImpl::CreateMojoService(
    mojo::PendingReceiver<mojom::blink::ImageDownloader> receiver) {
  receiver_.Bind(std::move(receiver),
                 GetSupplementable()->GetTaskRunner(TaskType::kNetworking));
  receiver_.set_disconnect_handler(
      WTF::Bind(&ImageDownloaderImpl::Dispose, WrapWeakPersistent(this)));
}

// ImageDownloader methods:
void ImageDownloaderImpl::DownloadImage(const KURL& image_url,
                                        bool is_favicon,
                                        uint32_t preferred_size,
                                        uint32_t max_bitmap_size,
                                        bool bypass_cache,
                                        DownloadImageCallback callback) {
  // Constrain the preferred size by the max bitmap size. This will prevent
  // resizing of the resulting image if the preferred size is used.
  if (max_bitmap_size)
    preferred_size = std::min(preferred_size, max_bitmap_size);

  auto download_callback =
      WTF::Bind(&ImageDownloaderImpl::DidDownloadImage, WrapPersistent(this),
                max_bitmap_size, std::move(callback));

  const WebSize preferred_dimensions(preferred_size, preferred_size);
  if (!image_url.ProtocolIsData()) {
    FetchImage(image_url, is_favicon, preferred_dimensions, bypass_cache,
               std::move(download_callback));
    // Will complete asynchronously via ImageDownloaderImpl::DidFetchImage.
    return;
  }

  WTF::Vector<SkBitmap> result_images =
      ImagesFromDataUrl(image_url, preferred_dimensions);
  std::move(download_callback).Run(0, result_images);
}

void ImageDownloaderImpl::DidDownloadImage(
    uint32_t max_image_size,
    DownloadImageCallback callback,
    int32_t http_status_code,
    const WTF::Vector<SkBitmap>& images) {
  WTF::Vector<SkBitmap> result_images;
  WTF::Vector<gfx::Size> result_original_image_sizes;
  FilterAndResizeImagesForMaximalSize(images, max_image_size, &result_images,
                                      &result_original_image_sizes);

  DCHECK_EQ(result_images.size(), result_original_image_sizes.size());

  std::move(callback).Run(http_status_code, result_images,
                          result_original_image_sizes);
}

void ImageDownloaderImpl::Dispose() {
  receiver_.reset();
}

void ImageDownloaderImpl::FetchImage(const KURL& image_url,
                                     bool is_favicon,
                                     const WebSize& preferred_size,
                                     bool bypass_cache,
                                     DownloadCallback callback) {
  // Create an image resource fetcher and assign it with a call back object.
  image_fetchers_.push_back(
      std::make_unique<MultiResolutionImageResourceFetcher>(
          image_url, GetSupplementable(), is_favicon,
          bypass_cache ? blink::mojom::FetchCacheMode::kBypassCache
                       : blink::mojom::FetchCacheMode::kDefault,
          WTF::Bind(&ImageDownloaderImpl::DidFetchImage, WrapPersistent(this),
                    std::move(callback), preferred_size)));
}

void ImageDownloaderImpl::DidFetchImage(
    DownloadCallback callback,
    const WebSize& preferred_size,
    MultiResolutionImageResourceFetcher* fetcher,
    const std::string& image_data,
    const WebString& mime_type) {
  int32_t http_status_code = fetcher->http_status_code();

  Vector<SkBitmap> images =
      DecodeImageData(image_data, mime_type.Utf8(), preferred_size);

  // Remove the image fetcher from our pending list. We're in the callback from
  // MultiResolutionImageResourceFetcher, best to delay deletion.
  for (auto* it = image_fetchers_.begin(); it != image_fetchers_.end(); ++it) {
    MultiResolutionImageResourceFetcher* image_fetcher = it->get();
    DCHECK(image_fetcher);
    if (image_fetcher == fetcher) {
      it = image_fetchers_.erase(it);
      break;
    }
  }

  // |this| may be destructed after callback is run.
  std::move(callback).Run(http_status_code, images);
}

void ImageDownloaderImpl::Trace(Visitor* visitor) const {
  visitor->Trace(receiver_);
  Supplement<LocalFrame>::Trace(visitor);
  ExecutionContextLifecycleObserver::Trace(visitor);
}

void ImageDownloaderImpl::ContextDestroyed() {
  for (const auto& fetcher : image_fetchers_) {
    // Will run callbacks with an empty image vector.
    fetcher->Dispose();
  }
  image_fetchers_.clear();
}

}  // namespace blink
