// Copyright 2013 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/android/favicon_helper.h"

#include <jni.h>
#include <stddef.h>

#include <memory>
#include <vector>

#include "base/android/jni_android.h"
#include "base/android/jni_array.h"
#include "base/android/jni_string.h"
#include "base/android/scoped_java_ref.h"
#include "base/functional/bind.h"
#include "base/memory/raw_ptr.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/android/compose_bitmaps_helper.h"
#include "chrome/browser/favicon/favicon_service_factory.h"
#include "chrome/browser/favicon/history_ui_favicon_request_handler_factory.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/profiles/profile_android.h"
#include "chrome/browser/ui/android/favicon/jni_headers/FaviconHelper_jni.h"
#include "components/favicon/core/favicon_service.h"
#include "components/favicon/core/favicon_util.h"
#include "components/favicon/core/history_ui_favicon_request_handler.h"
#include "components/favicon_base/favicon_util.h"
#include "content/public/browser/web_contents.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "ui/gfx/android/java_bitmap.h"
#include "ui/gfx/codec/png_codec.h"
#include "ui/gfx/color_utils.h"
#include "ui/gfx/image/image_skia.h"
#include "ui/gfx/image/image_skia_rep.h"
#include "url/android/gurl_android.h"

using base::android::AttachCurrentThread;
using base::android::ConvertJavaStringToUTF16;
using base::android::ConvertJavaStringToUTF8;
using base::android::ConvertUTF8ToJavaString;
using base::android::JavaParamRef;
using base::android::JavaRef;
using base::android::ScopedJavaGlobalRef;
using base::android::ScopedJavaLocalRef;
using JobFinishedCallback = base::OnceCallback<void(void)>;

static jlong JNI_FaviconHelper_Init(JNIEnv* env) {
  return reinterpret_cast<intptr_t>(new FaviconHelper());
}

// This is used by the FaviconHelper::GetComposedFaviconImageInternal, and it is
// used to manage multiple FaviconService::GetRawFaviconForPageURL calls. The
// number of calls is the size of the urls_. The Job is destroyed after the
// number of calls have been reached, and the result_callback_ is finished.
class FaviconHelper::Job {
 public:
  Job(FaviconHelper* favicon_helper,
      favicon::FaviconService* favicon_service,
      std::vector<GURL> urls,
      int desire_size_in_pixel,
      JobFinishedCallback job_finished_callback,
      favicon_base::FaviconResultsCallback result_callback);

  Job(const Job&) = delete;
  Job& operator=(const Job&) = delete;

  void Start();

 private:
  void OnFaviconAvailable(int favicon_index,
                          const favicon_base::FaviconRawBitmapResult& result);
  raw_ptr<FaviconHelper> favicon_helper_;
  raw_ptr<favicon::FaviconService> favicon_service_;
  std::vector<GURL> urls_;
  int desire_size_in_pixel_;
  JobFinishedCallback job_finished_callback_;
  favicon_base::FaviconResultsCallback result_callback_;
  int favicon_expected_count_;
  std::vector<favicon_base::FaviconRawBitmapResult> favicon_raw_bitmap_results_;
  int favicon_result_count_;

  base::WeakPtrFactory<Job> weak_ptr_factory_{this};
};

FaviconHelper::Job::Job(FaviconHelper* favicon_helper,
                        favicon::FaviconService* favicon_service,
                        std::vector<GURL> urls,
                        int desire_size_in_pixel,
                        JobFinishedCallback job_finished_callback,
                        favicon_base::FaviconResultsCallback result_callback)
    : favicon_helper_(favicon_helper),
      favicon_service_(favicon_service),
      urls_(urls),
      desire_size_in_pixel_(desire_size_in_pixel),
      job_finished_callback_(std::move(job_finished_callback)),
      result_callback_(std::move(result_callback)),
      favicon_raw_bitmap_results_(4),
      favicon_result_count_(0) {
  favicon_expected_count_ = urls_.size();
}

void FaviconHelper::Job::Start() {
  size_t urls_size = urls_.size();
  DCHECK(urls_size > 1 && urls_size <= 4);
  if (urls_size <= 1 || urls_size > 4) {
    return;
  }

  for (size_t i = 0; i < urls_size; i++) {
    favicon_base::FaviconRawBitmapCallback callback =
        base::BindOnce(&FaviconHelper::Job::OnFaviconAvailable,
                       weak_ptr_factory_.GetWeakPtr(), i);

    favicon_helper_->GetLocalFaviconImageForURLInternal(
        favicon_service_, urls_.at(i), desire_size_in_pixel_,
        std::move(callback));
  }
}

void FaviconHelper::Job::OnFaviconAvailable(
    int favicon_index,
    const favicon_base::FaviconRawBitmapResult& result) {
  DCHECK(favicon_index >= 0 && favicon_index < 4);

  if (result.is_valid()) {
    favicon_raw_bitmap_results_.at(favicon_index) = result;
    favicon_result_count_++;
  } else {
    favicon_expected_count_--;
  }

  if (favicon_result_count_ == favicon_expected_count_) {
    size_t i = 0;
    while (i < favicon_raw_bitmap_results_.size()) {
      if (!favicon_raw_bitmap_results_[i].is_valid()) {
        favicon_raw_bitmap_results_.erase(favicon_raw_bitmap_results_.begin() +
                                          i);
        continue;
      }
      i++;
    }
    std::move(result_callback_).Run(favicon_raw_bitmap_results_);
    std::move(job_finished_callback_).Run();
  }
}

FaviconHelper::FaviconHelper() : last_used_job_id_(0) {
  cancelable_task_tracker_ = std::make_unique<base::CancelableTaskTracker>();
}

void FaviconHelper::Destroy(JNIEnv* env) {
  delete this;
}

jboolean FaviconHelper::GetComposedFaviconImage(
    JNIEnv* env,
    const base::android::JavaParamRef<jobject>& j_profile,
    const base::android::JavaParamRef<jobjectArray>& j_urls,
    jint j_desired_size_in_pixel,
    const base::android::JavaParamRef<jobject>&
        j_composed_favicon_image_callback) {
  Profile* profile = ProfileAndroid::FromProfileAndroid(j_profile);
  DCHECK(profile);
  if (!profile) {
    return false;
  }

  favicon::FaviconService* favicon_service =
      FaviconServiceFactory::GetForProfile(profile,
                                           ServiceAccessType::EXPLICIT_ACCESS);

  DCHECK(favicon_service);
  if (!favicon_service) {
    return false;
  }

  int desired_size_in_pixel = static_cast<int>(j_desired_size_in_pixel);

  favicon_base::FaviconResultsCallback callback_runner = base::BindOnce(
      &FaviconHelper::OnComposedFaviconBitmapResultsAvailable,
      weak_ptr_factory_.GetWeakPtr(),
      ScopedJavaGlobalRef<jobject>(j_composed_favicon_image_callback),
      desired_size_in_pixel);

  std::vector<GURL> urls;
  url::GURLAndroid::JavaGURLArrayToGURLVector(env, j_urls, &urls);

  GetComposedFaviconImageInternal(favicon_service, urls,
                                  static_cast<int>(j_desired_size_in_pixel),
                                  std::move(callback_runner));

  return true;
}

void FaviconHelper::GetComposedFaviconImageInternal(
    favicon::FaviconService* favicon_service,
    std::vector<GURL> urls,
    int desired_size_in_pixel,
    favicon_base::FaviconResultsCallback callback_runner) {
  DCHECK(favicon_service);

  JobFinishedCallback job_finished_callback =
      base::BindOnce(&FaviconHelper::OnJobFinished,
                     weak_ptr_factory_.GetWeakPtr(), ++last_used_job_id_);

  auto job = std::make_unique<Job>(
      this, favicon_service, urls, desired_size_in_pixel,
      std::move(job_finished_callback), std::move(callback_runner));

  id_to_job_[last_used_job_id_] = std::move(job);
  id_to_job_[last_used_job_id_]->Start();
}

void ::FaviconHelper::OnJobFinished(int job_id) {
  DCHECK(id_to_job_.count(job_id));

  id_to_job_.erase(job_id);
}

jboolean FaviconHelper::GetLocalFaviconImageForURL(
    JNIEnv* env,
    const JavaParamRef<jobject>& j_profile,
    const JavaParamRef<jobject>& j_page_url,
    jint j_desired_size_in_pixel,
    const JavaParamRef<jobject>& j_favicon_image_callback) {
  Profile* profile = ProfileAndroid::FromProfileAndroid(j_profile);
  DCHECK(profile);
  if (!profile) {
    return false;
  }

  favicon::FaviconService* favicon_service =
      FaviconServiceFactory::GetForProfile(profile,
                                           ServiceAccessType::EXPLICIT_ACCESS);
  DCHECK(favicon_service);
  if (!favicon_service) {
    return false;
  }

  favicon_base::FaviconRawBitmapCallback callback_runner =
      base::BindOnce(&FaviconHelper::OnFaviconBitmapResultAvailable,
                     weak_ptr_factory_.GetWeakPtr(),
                     ScopedJavaGlobalRef<jobject>(j_favicon_image_callback));

  auto page_url = url::GURLAndroid::ToNativeGURL(env, j_page_url);
  GetLocalFaviconImageForURLInternal(favicon_service, *page_url,
                                     static_cast<int>(j_desired_size_in_pixel),
                                     std::move(callback_runner));

  return true;
}

void FaviconHelper::GetLocalFaviconImageForURLInternal(
    favicon::FaviconService* favicon_service,
    GURL url,
    int desired_size_in_pixel,
    favicon_base::FaviconRawBitmapCallback callback_runner) {
  DCHECK(favicon_service);
  if (!favicon_service) {
    return;
  }

  // |j_page_url| is an origin, and it may not have had a favicon associated
  // with it. A trickier case is when |j_page_url| only has domain-scoped
  // cookies, but visitors are redirected to HTTPS on visiting. Then
  // |j_page_url| defaults to a HTTP scheme, but the favicon will be associated
  // with the HTTPS URL and hence won't be found if we include the scheme in the
  // lookup. Set |fallback_to_host|=true so the favicon database will fall back
  // to matching only the hostname to have the best chance of finding a favicon.
  const bool fallback_to_host = true;
  favicon_service->GetRawFaviconForPageURL(
      url,
      {favicon_base::IconType::kFavicon, favicon_base::IconType::kTouchIcon,
       favicon_base::IconType::kTouchPrecomposedIcon,
       favicon_base::IconType::kWebManifestIcon},
      desired_size_in_pixel, fallback_to_host, std::move(callback_runner),
      cancelable_task_tracker_.get());
}

jboolean FaviconHelper::GetForeignFaviconImageForURL(
    JNIEnv* env,
    const JavaParamRef<jobject>& jprofile,
    const JavaParamRef<jobject>& j_page_url,
    jint j_desired_size_in_pixel,
    const base::android::JavaParamRef<jobject>& j_favicon_image_callback) {
  Profile* profile = ProfileAndroid::FromProfileAndroid(jprofile);
  if (!profile) {
    return false;
  }

  std::unique_ptr<GURL> page_url =
      url::GURLAndroid::ToNativeGURL(env, j_page_url);

  favicon::HistoryUiFaviconRequestHandler* history_ui_favicon_request_handler =
      HistoryUiFaviconRequestHandlerFactory::GetForBrowserContext(profile);
  // Can be null in tests.
  if (!history_ui_favicon_request_handler) {
    return false;
  }
  history_ui_favicon_request_handler->GetRawFaviconForPageURL(
      *page_url, static_cast<int>(j_desired_size_in_pixel),
      base::BindOnce(&FaviconHelper::OnFaviconBitmapResultAvailable,
                     weak_ptr_factory_.GetWeakPtr(),
                     ScopedJavaGlobalRef<jobject>(j_favicon_image_callback)),
      favicon::HistoryUiFaviconRequestOrigin::kRecentTabs);
  return true;
}

FaviconHelper::~FaviconHelper() {}

// Return the index of |sizes| whose area is largest but not exceeds int type
// range. If all |sizes|'s area exceed int type range, return the first one.
size_t FaviconHelper::GetLargestSizeIndex(const std::vector<gfx::Size>& sizes) {
  DCHECK(!sizes.empty());
  size_t ret = 0;
  // Find the first element whose area doesn't exceed max value, then use it
  // to compare with rest elements to find largest size index.
  for (size_t i = 0; i < sizes.size(); ++i) {
    base::CheckedNumeric<int> checked_area = sizes[i].GetCheckedArea();
    if (checked_area.IsValid()) {
      ret = i;
      int largest_area = checked_area.ValueOrDie();
      for (i = ret + 1; i < sizes.size(); ++i) {
        int area = sizes[i].GetCheckedArea().ValueOrDefault(-1);
        if (largest_area < area) {
          ret = i;
          largest_area = area;
        }
      }
    }
  }
  return ret;
}

void FaviconHelper::OnFaviconBitmapResultAvailable(
    const JavaRef<jobject>& j_favicon_image_callback,
    const favicon_base::FaviconRawBitmapResult& result) {
  JNIEnv* env = AttachCurrentThread();

  // Convert favicon_image_result to java objects.
  ScopedJavaLocalRef<jobject> j_icon_url =
      url::GURLAndroid::FromNativeGURL(env, result.icon_url);
  ScopedJavaLocalRef<jobject> j_favicon_bitmap;
  if (result.is_valid()) {
    SkBitmap favicon_bitmap;
    gfx::PNGCodec::Decode(result.bitmap_data->front(),
                          result.bitmap_data->size(), &favicon_bitmap);
    if (!favicon_bitmap.isNull()) {
      j_favicon_bitmap = gfx::ConvertToJavaBitmap(favicon_bitmap);
    }
  }

  // Call java side OnFaviconBitmapResultAvailable method.
  Java_FaviconImageCallback_onFaviconAvailable(env, j_favicon_image_callback,
                                               j_favicon_bitmap, j_icon_url);
}

void FaviconHelper::OnComposedFaviconBitmapResultsAvailable(
    const JavaRef<jobject>& j_favicon_image_callback,
    const int desired_size_in_pixel,
    const std::vector<favicon_base::FaviconRawBitmapResult>& results) {
  JNIEnv* env = AttachCurrentThread();
  std::vector<SkBitmap> result_bitmaps;
  std::vector<ScopedJavaLocalRef<jobject>> j_icon_url_vector;
  for (size_t i = 0; i < results.size(); i++) {
    favicon_base::FaviconRawBitmapResult result = results[i];
    if (!result.is_valid()) {
      continue;
    }
    SkBitmap favicon_bitmap;
    const ScopedJavaLocalRef<jobject>& j_icon_url =
        url::GURLAndroid::FromNativeGURL(env, result.icon_url);
    j_icon_url_vector.push_back(j_icon_url);
    gfx::PNGCodec::Decode(result.bitmap_data->front(),
                          result.bitmap_data->size(), &favicon_bitmap);
    result_bitmaps.push_back(std::move(favicon_bitmap));
  }
  ScopedJavaLocalRef<jobjectArray> j_icon_urls(
      url::GURLAndroid::ToJavaArrayOfGURLs(env, j_icon_url_vector));

  ScopedJavaLocalRef<jobject> j_favicon_bitmap;
  if (!result_bitmaps.empty()) {
    std::unique_ptr<SkBitmap> composed_bitmap =
        compose_bitmaps_helper::ComposeBitmaps(std::move(result_bitmaps),
                                               desired_size_in_pixel);
    if (composed_bitmap && !composed_bitmap->isNull()) {
      j_favicon_bitmap = gfx::ConvertToJavaBitmap(*composed_bitmap);
    }
  }

  // Call java side OnComposedFaviconBitmapResultsAvailable method.
  Java_ComposedFaviconImageCallback_onComposedFaviconAvailable(
      env, j_favicon_image_callback, j_favicon_bitmap, j_icon_urls);
}
