// 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 "chrome/browser/offline_pages/android/offline_page_bridge.h"

#include <memory>
#include <set>
#include <string>
#include <utility>
#include <vector>

#include "base/android/callback_android.h"
#include "base/android/jni_android.h"
#include "base/android/jni_array.h"
#include "base/android/jni_string.h"
#include "base/bind.h"
#include "base/logging.h"
#include "base/memory/ptr_util.h"
#include "base/metrics/histogram_functions.h"
#include "base/metrics/histogram_macros.h"
#include "base/strings/string16.h"
#include "base/strings/string_number_conversions.h"
#include "base/task_scheduler/post_task.h"
#include "base/time/time.h"
#include "chrome/browser/android/tab_android.h"
#include "chrome/browser/offline_pages/offline_page_mhtml_archiver.h"
#include "chrome/browser/offline_pages/offline_page_model_factory.h"
#include "chrome/browser/offline_pages/offline_page_tab_helper.h"
#include "chrome/browser/offline_pages/offline_page_utils.h"
#include "chrome/browser/offline_pages/prefetch/prefetched_pages_notifier.h"
#include "chrome/browser/offline_pages/recent_tab_helper.h"
#include "chrome/browser/offline_pages/request_coordinator_factory.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/profiles/profile_android.h"
#include "components/offline_pages/core/archive_validator.h"
#include "components/offline_pages/core/background/request_coordinator.h"
#include "components/offline_pages/core/background/request_queue_results.h"
#include "components/offline_pages/core/background/save_page_request.h"
#include "components/offline_pages/core/client_policy_controller.h"
#include "components/offline_pages/core/offline_page_client_policy.h"
#include "components/offline_pages/core/offline_page_feature.h"
#include "components/offline_pages/core/offline_page_item.h"
#include "components/offline_pages/core/offline_page_model.h"
#include "components/offline_pages/core/offline_page_types.h"
#include "components/offline_pages/core/request_header/offline_page_header.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/web_contents.h"
#include "jni/OfflinePageBridge_jni.h"
#include "jni/SavePageRequest_jni.h"
#include "net/base/filename_util.h"

using base::android::ConvertJavaStringToUTF8;
using base::android::ConvertUTF16ToJavaString;
using base::android::ConvertUTF8ToJavaString;
using base::android::JavaParamRef;
using base::android::JavaRef;
using base::android::ScopedJavaGlobalRef;
using base::android::ScopedJavaLocalRef;

namespace offline_pages {
namespace android {

namespace {

const char kOfflinePageBridgeKey[] = "offline-page-bridge";

void JNI_SavePageRequest_ToJavaOfflinePageList(
    JNIEnv* env,
    const JavaRef<jobject>& j_result_obj,
    const std::vector<OfflinePageItem>& offline_pages) {
  for (const OfflinePageItem& offline_page : offline_pages) {
    Java_OfflinePageBridge_createOfflinePageAndAddToList(
        env, j_result_obj,
        ConvertUTF8ToJavaString(env, offline_page.url.spec()),
        offline_page.offline_id,
        ConvertUTF8ToJavaString(env, offline_page.client_id.name_space),
        ConvertUTF8ToJavaString(env, offline_page.client_id.id),
        ConvertUTF16ToJavaString(env, offline_page.title),
        ConvertUTF8ToJavaString(env, offline_page.file_path.value()),
        offline_page.file_size, offline_page.creation_time.ToJavaTime(),
        offline_page.access_count, offline_page.last_access_time.ToJavaTime(),
        ConvertUTF8ToJavaString(env, offline_page.request_origin));
  }
}

ScopedJavaLocalRef<jobject> JNI_SavePageRequest_ToJavaOfflinePageItem(
    JNIEnv* env,
    const OfflinePageItem& offline_page) {
  return Java_OfflinePageBridge_createOfflinePageItem(
      env, ConvertUTF8ToJavaString(env, offline_page.url.spec()),
      offline_page.offline_id,
      ConvertUTF8ToJavaString(env, offline_page.client_id.name_space),
      ConvertUTF8ToJavaString(env, offline_page.client_id.id),
      ConvertUTF16ToJavaString(env, offline_page.title),
      ConvertUTF8ToJavaString(env, offline_page.file_path.value()),
      offline_page.file_size, offline_page.creation_time.ToJavaTime(),
      offline_page.access_count, offline_page.last_access_time.ToJavaTime(),
      ConvertUTF8ToJavaString(env, offline_page.request_origin));
}

ScopedJavaLocalRef<jobject> JNI_SavePageRequest_ToJavaDeletedPageInfo(
    JNIEnv* env,
    const OfflinePageModel::DeletedPageInfo& deleted_page) {
  return Java_OfflinePageBridge_createDeletedPageInfo(
      env, deleted_page.offline_id,
      ConvertUTF8ToJavaString(env, deleted_page.client_id.name_space),
      ConvertUTF8ToJavaString(env, deleted_page.client_id.id),
      ConvertUTF8ToJavaString(env, deleted_page.request_origin));
}

void MultipleOfflinePageItemCallback(
    const ScopedJavaGlobalRef<jobject>& j_result_obj,
    const ScopedJavaGlobalRef<jobject>& j_callback_obj,
    const OfflinePageModel::MultipleOfflinePageItemResult& result) {
  JNIEnv* env = base::android::AttachCurrentThread();
  JNI_SavePageRequest_ToJavaOfflinePageList(env, j_result_obj, result);
  base::android::RunCallbackAndroid(j_callback_obj, j_result_obj);
}

void SavePageCallback(const ScopedJavaGlobalRef<jobject>& j_callback_obj,
                      const GURL& url,
                      OfflinePageModel::SavePageResult result,
                      int64_t offline_id) {
  JNIEnv* env = base::android::AttachCurrentThread();

  Java_SavePageCallback_onSavePageDone(
      env, j_callback_obj, static_cast<int>(result),
      ConvertUTF8ToJavaString(env, url.spec()), offline_id);
}

void DeletePageCallback(const ScopedJavaGlobalRef<jobject>& j_callback_obj,
                        OfflinePageModel::DeletePageResult result) {
  base::android::RunCallbackAndroid(j_callback_obj, static_cast<int>(result));
}

void SelectPageCallback(const ScopedJavaGlobalRef<jobject>& j_callback_obj,
                        const std::vector<OfflinePageItem>& result) {
  JNIEnv* env = base::android::AttachCurrentThread();
  ScopedJavaLocalRef<jobject> j_result;

  if (!result.empty())
    j_result = JNI_SavePageRequest_ToJavaOfflinePageItem(env, result.front());
  base::android::RunCallbackAndroid(j_callback_obj, j_result);
}

void SingleOfflinePageItemCallback(
    const ScopedJavaGlobalRef<jobject>& j_callback_obj,
    const OfflinePageItem* result) {
  JNIEnv* env = base::android::AttachCurrentThread();
  ScopedJavaLocalRef<jobject> j_result;

  if (result)
    j_result = JNI_SavePageRequest_ToJavaOfflinePageItem(env, *result);
  base::android::RunCallbackAndroid(j_callback_obj, j_result);
}

void CheckForNewOfflineContentCallback(
    const base::Time& pages_created_after,
    const ScopedJavaGlobalRef<jobject>& j_callback_obj,
    const OfflinePageModel::MultipleOfflinePageItemResult& result) {
  JNIEnv* env = base::android::AttachCurrentThread();
  base::string16 relevant_host =
      ExtractRelevantHostFromOfflinePageItemList(pages_created_after, result);
  ScopedJavaLocalRef<jstring> j_result =
      base::android::ConvertUTF16ToJavaString(env, relevant_host);

  base::android::RunCallbackAndroid(j_callback_obj, j_result);
}

void GetLaunchUrlByOfflineIdCallback(
    const ScopedJavaGlobalRef<jobject>& j_callback_obj,
    const std::string& result) {
  JNIEnv* env = base::android::AttachCurrentThread();
  base::android::RunCallbackAndroid(j_callback_obj,
                                    ConvertUTF8ToJavaString(env, result));
}

void GetLaunchUrlBySizeAndDigestCallback(
    const ScopedJavaGlobalRef<jobject>& j_callback_obj,
    const GURL& url,
    const std::string& extra_headers) {
  JNIEnv* env = base::android::AttachCurrentThread();
  ScopedJavaLocalRef<jobject> loadUrlParams =
      Java_OfflinePageBridge_createLoadUrlParams(
          env, ConvertUTF8ToJavaString(env, url.spec()),
          ConvertUTF8ToJavaString(env, extra_headers));
  base::android::RunCallbackAndroid(j_callback_obj, loadUrlParams);
}

void ValidateFileCallback(const ScopedJavaGlobalRef<jobject>& j_callback_obj,
                          const GURL& url,
                          const base::FilePath& file_path,
                          bool is_trusted) {
  // If trusted, the launch url will be the http/https url of the offline
  // page. Otherwise, the launch url will be the file URL pointing to the
  // archive file of the offline page.
  GURL launch_url;
  if (is_trusted)
    launch_url = url;
  else
    launch_url = net::FilePathToFileURL(file_path);
  GetLaunchUrlByOfflineIdCallback(j_callback_obj, launch_url.spec());
}

void AcquireFileAccessPermissionCallback(
    const ScopedJavaGlobalRef<jobject>& j_callback_obj,
    bool granted) {
  base::android::RunCallbackAndroid(j_callback_obj, granted);
}

ScopedJavaLocalRef<jobjectArray> JNI_SavePageRequest_CreateJavaSavePageRequests(
    JNIEnv* env,
    std::vector<std::unique_ptr<SavePageRequest>> requests) {
  ScopedJavaLocalRef<jclass> save_page_request_clazz = base::android::GetClass(
      env, "org/chromium/chrome/browser/offlinepages/SavePageRequest");
  jobjectArray joa = env->NewObjectArray(
      requests.size(), save_page_request_clazz.obj(), nullptr);
  base::android::CheckException(env);

  for (size_t i = 0; i < requests.size(); ++i) {
    SavePageRequest request = *(requests[i]);
    ScopedJavaLocalRef<jstring> name_space =
        ConvertUTF8ToJavaString(env, request.client_id().name_space);
    ScopedJavaLocalRef<jstring> id =
        ConvertUTF8ToJavaString(env, request.client_id().id);
    ScopedJavaLocalRef<jstring> url =
        ConvertUTF8ToJavaString(env, request.url().spec());
    ScopedJavaLocalRef<jstring> origin =
        ConvertUTF8ToJavaString(env, request.request_origin());

    ScopedJavaLocalRef<jobject> j_save_page_request =
        Java_SavePageRequest_create(
            env, static_cast<int>(request.request_state()),
            request.request_id(), url, name_space, id, origin);
    env->SetObjectArrayElement(joa, i, j_save_page_request.obj());
  }

  return ScopedJavaLocalRef<jobjectArray>(env, joa);
}

void OnGetAllRequestsDone(
    const ScopedJavaGlobalRef<jobject>& j_callback_obj,
    std::vector<std::unique_ptr<SavePageRequest>> all_requests) {
  JNIEnv* env = base::android::AttachCurrentThread();

  ScopedJavaLocalRef<jobjectArray> j_result_obj =
      JNI_SavePageRequest_CreateJavaSavePageRequests(env,
                                                     std::move(all_requests));
  base::android::RunCallbackAndroid(j_callback_obj, j_result_obj);
}

UpdateRequestResult ToUpdateRequestResult(ItemActionStatus status) {
  switch (status) {
    case ItemActionStatus::SUCCESS:
      return UpdateRequestResult::SUCCESS;
    case ItemActionStatus::NOT_FOUND:
      return UpdateRequestResult::REQUEST_DOES_NOT_EXIST;
    case ItemActionStatus::STORE_ERROR:
      return UpdateRequestResult::STORE_FAILURE;
    case ItemActionStatus::ALREADY_EXISTS:
    default:
      NOTREACHED();
  }
  return UpdateRequestResult::STORE_FAILURE;
}

void OnRemoveRequestsDone(const ScopedJavaGlobalRef<jobject>& j_callback_obj,
                          const MultipleItemStatuses& removed_request_results) {
  JNIEnv* env = base::android::AttachCurrentThread();

  std::vector<int> update_request_results;
  std::vector<int64_t> update_request_ids;

  for (std::pair<int64_t, ItemActionStatus> remove_result :
       removed_request_results) {
    update_request_ids.emplace_back(std::get<0>(remove_result));
    update_request_results.emplace_back(
        static_cast<int>(ToUpdateRequestResult(std::get<1>(remove_result))));
  }

  ScopedJavaLocalRef<jlongArray> j_result_ids =
      base::android::ToJavaLongArray(env, update_request_ids);
  ScopedJavaLocalRef<jintArray> j_result_codes =
      base::android::ToJavaIntArray(env, update_request_results);

  Java_RequestsRemovedCallback_onResult(env, j_callback_obj, j_result_ids,
                                        j_result_codes);
}

void SavePageLaterCallback(const ScopedJavaGlobalRef<jobject>& j_callback_obj,
                           AddRequestResult value) {
  base::android::RunCallbackAndroid(j_callback_obj, static_cast<int>(value));
}

void PublishPageDone(
    const ScopedJavaGlobalRef<jobject>& j_published_callback_obj,
    const base::FilePath& file_path,
    SavePageResult result) {
  JNIEnv* env = base::android::AttachCurrentThread();

  base::FilePath file_path_or_empty;
  if (result != SavePageResult::SUCCESS)
    file_path_or_empty = file_path;

  UMA_HISTOGRAM_ENUMERATION("OfflinePages.Sharing.PublishInternalPageResult",
                            result, SavePageResult::RESULT_COUNT);

  base::android::RunCallbackAndroid(
      j_published_callback_obj,
      ConvertUTF8ToJavaString(env, file_path.value()));
}

}  // namespace

static jboolean JNI_OfflinePageBridge_IsOfflineBookmarksEnabled(
    JNIEnv* env,
    const JavaParamRef<jclass>& clazz) {
  return offline_pages::IsOfflineBookmarksEnabled();
}

static jboolean JNI_OfflinePageBridge_IsPageSharingEnabled(
    JNIEnv* env,
    const JavaParamRef<jclass>& clazz) {
  return offline_pages::IsOfflinePagesSharingEnabled();
}

static jboolean JNI_OfflinePageBridge_CanSavePage(
    JNIEnv* env,
    const JavaParamRef<jclass>& clazz,
    const JavaParamRef<jstring>& j_url) {
  GURL url(ConvertJavaStringToUTF8(env, j_url));
  return OfflinePageModel::CanSaveURL(url);
}

static ScopedJavaLocalRef<jobject>
JNI_OfflinePageBridge_GetOfflinePageBridgeForProfile(
    JNIEnv* env,
    const JavaParamRef<jclass>& jcaller,
    const JavaParamRef<jobject>& j_profile) {
  Profile* profile = ProfileAndroid::FromProfileAndroid(j_profile);

  // Return null if there is no reasonable context for the provided Java
  // profile.
  if (profile == nullptr)
    return ScopedJavaLocalRef<jobject>();

  OfflinePageModel* offline_page_model =
      OfflinePageModelFactory::GetForBrowserContext(profile);

  // Return null if we cannot get an offline page model for provided profile.
  if (offline_page_model == nullptr)
    return ScopedJavaLocalRef<jobject>();

  OfflinePageBridge* bridge = static_cast<OfflinePageBridge*>(
      offline_page_model->GetUserData(kOfflinePageBridgeKey));
  if (!bridge) {
    bridge = new OfflinePageBridge(env, profile, offline_page_model);
    offline_page_model->SetUserData(kOfflinePageBridgeKey,
                                    base::WrapUnique(bridge));
  }

  return ScopedJavaLocalRef<jobject>(bridge->java_ref());
}

// static
ScopedJavaLocalRef<jobject> OfflinePageBridge::ConvertToJavaOfflinePage(
    JNIEnv* env,
    const OfflinePageItem& offline_page) {
  return JNI_SavePageRequest_ToJavaOfflinePageItem(env, offline_page);
}

// static
std::string OfflinePageBridge::GetEncodedOriginApp(
    const content::WebContents* web_contents) {
  TabAndroid* tab = TabAndroid::FromWebContents(web_contents);
  if (!tab)
    return "";
  JNIEnv* env = base::android::AttachCurrentThread();
  return ConvertJavaStringToUTF8(
      env,
      Java_OfflinePageBridge_getEncodedOriginApp(env, tab->GetJavaObject()));
}

OfflinePageBridge::OfflinePageBridge(JNIEnv* env,
                                     content::BrowserContext* browser_context,
                                     OfflinePageModel* offline_page_model)
    : browser_context_(browser_context),
      offline_page_model_(offline_page_model),
      weak_ptr_factory_(this) {
  ScopedJavaLocalRef<jobject> j_offline_page_bridge =
      Java_OfflinePageBridge_create(env, reinterpret_cast<jlong>(this));
  java_ref_.Reset(j_offline_page_bridge);

  NotifyIfDoneLoading();
  offline_page_model_->AddObserver(this);
}

OfflinePageBridge::~OfflinePageBridge() {
  JNIEnv* env = base::android::AttachCurrentThread();

  // Native shutdown causes the destruction of |this|.
  Java_OfflinePageBridge_offlinePageBridgeDestroyed(env, java_ref_);
}

void OfflinePageBridge::OfflinePageModelLoaded(OfflinePageModel* model) {
  DCHECK_EQ(offline_page_model_, model);
  NotifyIfDoneLoading();
}

void OfflinePageBridge::OfflinePageAdded(OfflinePageModel* model,
                                         const OfflinePageItem& added_page) {
  DCHECK_EQ(offline_page_model_, model);
  JNIEnv* env = base::android::AttachCurrentThread();

  Java_OfflinePageBridge_offlinePageAdded(
      env, java_ref_,
      JNI_SavePageRequest_ToJavaOfflinePageItem(env, added_page));
}

void OfflinePageBridge::OfflinePageDeleted(
    const OfflinePageModel::DeletedPageInfo& page_info) {
  JNIEnv* env = base::android::AttachCurrentThread();
  Java_OfflinePageBridge_offlinePageDeleted(
      env, java_ref_,
      JNI_SavePageRequest_ToJavaDeletedPageInfo(env, page_info));
}

void OfflinePageBridge::GetAllPages(
    JNIEnv* env,
    const JavaParamRef<jobject>& obj,
    const JavaParamRef<jobject>& j_result_obj,
    const JavaParamRef<jobject>& j_callback_obj) {
  DCHECK(j_result_obj);
  DCHECK(j_callback_obj);

  ScopedJavaGlobalRef<jobject> j_result_ref;
  j_result_ref.Reset(env, j_result_obj);

  ScopedJavaGlobalRef<jobject> j_callback_ref;
  j_callback_ref.Reset(env, j_callback_obj);

  offline_page_model_->GetAllPages(base::BindOnce(
      &MultipleOfflinePageItemCallback, j_result_ref, j_callback_ref));
}

void OfflinePageBridge::GetPageByOfflineId(
    JNIEnv* env,
    const JavaParamRef<jobject>& obj,
    jlong offline_id,
    const JavaParamRef<jobject>& j_callback_obj) {
  ScopedJavaGlobalRef<jobject> j_callback_ref;
  j_callback_ref.Reset(env, j_callback_obj);
  offline_page_model_->GetPageByOfflineId(
      offline_id,
      base::BindOnce(&SingleOfflinePageItemCallback, j_callback_ref));
}

std::vector<ClientId> getClientIdsFromObjectArrays(
    JNIEnv* env,
    const JavaParamRef<jobjectArray>& j_namespaces_array,
    const JavaParamRef<jobjectArray>& j_ids_array) {
  std::vector<std::string> name_spaces;
  std::vector<std::string> ids;
  base::android::AppendJavaStringArrayToStringVector(
      env, j_namespaces_array.obj(), &name_spaces);
  base::android::AppendJavaStringArrayToStringVector(env, j_ids_array.obj(),
                                                     &ids);
  DCHECK_EQ(name_spaces.size(), ids.size());
  std::vector<ClientId> client_ids;

  for (size_t i = 0; i < name_spaces.size(); i++) {
    offline_pages::ClientId client_id;
    client_id.name_space = name_spaces[i];
    client_id.id = ids[i];
    client_ids.emplace_back(client_id);
  }

  return client_ids;
}

void OfflinePageBridge::DeletePagesByClientId(
    JNIEnv* env,
    const JavaParamRef<jobject>& obj,
    const JavaParamRef<jobjectArray>& j_namespaces_array,
    const JavaParamRef<jobjectArray>& j_ids_array,
    const JavaParamRef<jobject>& j_callback_obj) {
  ScopedJavaGlobalRef<jobject> j_callback_ref;
  j_callback_ref.Reset(env, j_callback_obj);
  std::vector<ClientId> client_ids =
      getClientIdsFromObjectArrays(env, j_namespaces_array, j_ids_array);
  offline_page_model_->DeletePagesByClientIds(
      client_ids, base::Bind(&DeletePageCallback, j_callback_ref));
}

void OfflinePageBridge::DeletePagesByClientIdAndOrigin(
    JNIEnv* env,
    const base::android::JavaParamRef<jobject>& obj,
    const base::android::JavaParamRef<jobjectArray>& j_namespaces_array,
    const base::android::JavaParamRef<jobjectArray>& j_ids_array,
    const base::android::JavaParamRef<jstring>& j_origin,
    const base::android::JavaParamRef<jobject>& j_callback_obj) {
  ScopedJavaGlobalRef<jobject> j_callback_ref;
  j_callback_ref.Reset(env, j_callback_obj);
  std::vector<ClientId> client_ids =
      getClientIdsFromObjectArrays(env, j_namespaces_array, j_ids_array);
  offline_page_model_->DeletePagesByClientIdsAndOrigin(
      client_ids, ConvertJavaStringToUTF8(j_origin),
      base::Bind(&DeletePageCallback, j_callback_ref));
}

void OfflinePageBridge::DeletePagesByOfflineId(
    JNIEnv* env,
    const JavaParamRef<jobject>& obj,
    const JavaParamRef<jlongArray>& j_offline_ids_array,
    const JavaParamRef<jobject>& j_callback_obj) {
  ScopedJavaGlobalRef<jobject> j_callback_ref;
  j_callback_ref.Reset(env, j_callback_obj);
  std::vector<int64_t> offline_ids;
  base::android::JavaLongArrayToInt64Vector(env, j_offline_ids_array,
                                            &offline_ids);
  offline_page_model_->DeletePagesByOfflineId(
      offline_ids, base::Bind(&DeletePageCallback, j_callback_ref));
}

void OfflinePageBridge::GetPagesByClientId(
    JNIEnv* env,
    const JavaParamRef<jobject>& obj,
    const JavaParamRef<jobject>& j_result_obj,
    const JavaParamRef<jobjectArray>& j_namespaces_array,
    const JavaParamRef<jobjectArray>& j_ids_array,
    const JavaParamRef<jobject>& j_callback_obj) {
  ScopedJavaGlobalRef<jobject> j_result_ref;
  j_result_ref.Reset(env, j_result_obj);

  ScopedJavaGlobalRef<jobject> j_callback_ref;
  j_callback_ref.Reset(env, j_callback_obj);
  std::vector<ClientId> client_ids =
      getClientIdsFromObjectArrays(env, j_namespaces_array, j_ids_array);
  offline_page_model_->GetPagesByClientIds(
      client_ids, base::BindOnce(&MultipleOfflinePageItemCallback, j_result_ref,
                                 j_callback_ref));
}

void OfflinePageBridge::GetPagesByRequestOrigin(
    JNIEnv* env,
    const JavaParamRef<jobject>& obj,
    const JavaParamRef<jobject>& j_result_obj,
    const JavaParamRef<jstring>& j_request_origin,
    const JavaParamRef<jobject>& j_callback_obj) {
  ScopedJavaGlobalRef<jobject> j_result_ref;
  j_result_ref.Reset(env, j_result_obj);

  ScopedJavaGlobalRef<jobject> j_callback_ref;
  j_callback_ref.Reset(env, j_callback_obj);

  std::string request_origin = ConvertJavaStringToUTF8(env, j_request_origin);

  offline_page_model_->GetPagesByRequestOrigin(
      request_origin, base::BindOnce(&MultipleOfflinePageItemCallback,
                                     j_result_ref, j_callback_ref));
}

void OfflinePageBridge::GetPagesByNamespace(
    JNIEnv* env,
    const JavaParamRef<jobject>& obj,
    const JavaParamRef<jobject>& j_result_obj,
    const JavaParamRef<jstring>& j_namespace,
    const JavaParamRef<jobject>& j_callback_obj) {
  ScopedJavaGlobalRef<jobject> j_result_ref(env, j_result_obj);

  ScopedJavaGlobalRef<jobject> j_callback_ref;
  j_callback_ref.Reset(env, j_callback_obj);

  std::string name_space = ConvertJavaStringToUTF8(env, j_namespace);

  offline_page_model_->GetPagesByNamespace(
      name_space, base::BindOnce(&MultipleOfflinePageItemCallback, j_result_ref,
                                 j_callback_ref));
}

void OfflinePageBridge::SelectPageForOnlineUrl(
    JNIEnv* env,
    const JavaParamRef<jobject>& obj,
    const JavaParamRef<jstring>& j_online_url,
    int tab_id,
    const JavaParamRef<jobject>& j_callback_obj) {
  DCHECK(j_callback_obj);

  ScopedJavaGlobalRef<jobject> j_callback_ref;
  j_callback_ref.Reset(env, j_callback_obj);

  OfflinePageUtils::SelectPagesForURL(
      browser_context_, GURL(ConvertJavaStringToUTF8(env, j_online_url)),
      URLSearchMode::SEARCH_BY_ALL_URLS, tab_id,
      base::Bind(&SelectPageCallback, j_callback_ref));
}

void OfflinePageBridge::SavePage(JNIEnv* env,
                                 const JavaParamRef<jobject>& obj,
                                 const JavaParamRef<jobject>& j_callback_obj,
                                 const JavaParamRef<jobject>& j_web_contents,
                                 const JavaParamRef<jstring>& j_namespace,
                                 const JavaParamRef<jstring>& j_client_id,
                                 const JavaParamRef<jstring>& j_origin) {
  DCHECK(j_callback_obj);
  DCHECK(j_web_contents);

  ScopedJavaGlobalRef<jobject> j_callback_ref;
  j_callback_ref.Reset(env, j_callback_obj);

  OfflinePageModel::SavePageParams save_page_params;
  std::unique_ptr<OfflinePageArchiver> archiver;

  content::WebContents* web_contents =
      content::WebContents::FromJavaWebContents(j_web_contents);
  if (web_contents) {
    save_page_params.url = web_contents->GetLastCommittedURL();
    archiver.reset(new OfflinePageMHTMLArchiver());
  }

  save_page_params.client_id.name_space =
      ConvertJavaStringToUTF8(env, j_namespace);
  save_page_params.client_id.id = ConvertJavaStringToUTF8(env, j_client_id);
  save_page_params.is_background = false;
  save_page_params.request_origin = ConvertJavaStringToUTF8(env, j_origin);

  offline_page_model_->SavePage(
      save_page_params, std::move(archiver), web_contents,
      base::Bind(&SavePageCallback, j_callback_ref, save_page_params.url));
}

void OfflinePageBridge::SavePageLater(
    JNIEnv* env,
    const JavaParamRef<jobject>& obj,
    const JavaParamRef<jobject>& j_callback_obj,
    const JavaParamRef<jstring>& j_url,
    const JavaParamRef<jstring>& j_namespace,
    const JavaParamRef<jstring>& j_client_id,
    const JavaParamRef<jstring>& j_origin,
    jboolean user_requested) {
  DCHECK(j_callback_obj);
  ScopedJavaGlobalRef<jobject> j_callback_ref;
  j_callback_ref.Reset(env, j_callback_obj);

  offline_pages::ClientId client_id;
  client_id.name_space = ConvertJavaStringToUTF8(env, j_namespace);
  client_id.id = ConvertJavaStringToUTF8(env, j_client_id);

  RequestCoordinator* coordinator =
      offline_pages::RequestCoordinatorFactory::GetInstance()->
          GetForBrowserContext(browser_context_);

  RequestCoordinator::SavePageLaterParams params;
  params.url = GURL(ConvertJavaStringToUTF8(env, j_url));
  params.client_id = client_id;
  params.user_requested = static_cast<bool>(user_requested);
  params.availability =
      RequestCoordinator::RequestAvailability::ENABLED_FOR_OFFLINER;
  params.request_origin = ConvertJavaStringToUTF8(env, j_origin);

  coordinator->SavePageLater(
      params, base::BindOnce(&SavePageLaterCallback, j_callback_ref));
}

void OfflinePageBridge::PublishInternalPageByOfflineId(
    JNIEnv* env,
    const base::android::JavaParamRef<jobject>& obj,
    const jlong j_offline_id,
    const base::android::JavaParamRef<jobject>& j_published_callback) {
  ScopedJavaGlobalRef<jobject> j_published_callback_ref;
  j_published_callback_ref.Reset(env, j_published_callback);

  OfflinePageModel* offline_page_model =
      OfflinePageModelFactory::GetForBrowserContext(browser_context_);
  DCHECK(offline_page_model);

  offline_page_model->GetPageByOfflineId(
      j_offline_id,
      base::Bind(&OfflinePageBridge::PublishInternalArchive,
                 weak_ptr_factory_.GetWeakPtr(), j_published_callback_ref,
                 PublishSource::kPublishByOfflineId));
}

void OfflinePageBridge::PublishInternalPageByGuid(
    JNIEnv* env,
    const base::android::JavaParamRef<jobject>& obj,
    const base::android::JavaParamRef<jstring>& j_guid,
    const base::android::JavaParamRef<jobject>& j_published_callback) {
  ScopedJavaGlobalRef<jobject> j_published_callback_ref;
  j_published_callback_ref.Reset(env, j_published_callback);

  OfflinePageModel* offline_page_model =
      OfflinePageModelFactory::GetForBrowserContext(browser_context_);
  DCHECK(offline_page_model);

  offline_page_model->GetPageByGuid(
      ConvertJavaStringToUTF8(env, j_guid),
      base::BindOnce(&OfflinePageBridge::PublishInternalArchive,
                     weak_ptr_factory_.GetWeakPtr(), j_published_callback_ref,
                     PublishSource::kPublishByGuid));
}

void OfflinePageBridge::PublishInternalArchive(
    const ScopedJavaGlobalRef<jobject>& j_callback_obj,
    const PublishSource publish_source,
    const OfflinePageItem* offline_page) {
  if (!offline_page) {
    PublishPageDone(j_callback_obj, base::FilePath(),
                    SavePageResult::CANCELLED);
    base::UmaHistogramEnumeration("OfflinePages.PublishArchive.PublishSource",
                                  publish_source);
    return;
  }

  OfflinePageModel* offline_page_model =
      OfflinePageModelFactory::GetForBrowserContext(browser_context_);
  DCHECK(offline_page_model);

  // If it has already been published, bail out.
  if (!offline_page_model->IsArchiveInInternalDir(offline_page->file_path)) {
    PublishPageDone(j_callback_obj, offline_page->file_path,
                    SavePageResult::ALREADY_EXISTS);
    return;
  }

  std::unique_ptr<OfflinePageArchiver> archiver(new OfflinePageMHTMLArchiver());
  offline_page_model->PublishInternalArchive(
      *offline_page, std::move(archiver),
      base::BindOnce(&PublishPageDone, std::move(j_callback_obj)));
}

ScopedJavaLocalRef<jstring> OfflinePageBridge::GetOfflinePageHeaderForReload(
    JNIEnv* env,
    const base::android::JavaParamRef<jobject>& obj,
    const JavaParamRef<jobject>& j_web_contents) {
  content::WebContents* web_contents =
      content::WebContents::FromJavaWebContents(j_web_contents);
  if (!web_contents)
    return ScopedJavaLocalRef<jstring>();

  const offline_pages::OfflinePageHeader* offline_header =
      offline_pages::OfflinePageUtils::GetOfflineHeaderFromWebContents(
          web_contents);
  if (!offline_header)
    return ScopedJavaLocalRef<jstring>();

  // Only replaces the reason field with "reload" value that is used to trigger
  // the network conditon check again in deciding whether to load the offline
  // page. All other fields in the offline header should still carry to the
  // reload request in order to keep the consistent behavior if we do decide to
  // load the offline page. For example, "id" field should be kept in order to
  // load the same offline version again if desired.
  offline_pages::OfflinePageHeader offline_header_for_reload = *offline_header;
  offline_header_for_reload.reason =
      offline_pages::OfflinePageHeader::Reason::RELOAD;
  return ScopedJavaLocalRef<jstring>(ConvertUTF8ToJavaString(
      env, offline_header_for_reload.GetCompleteHeaderString()));
}

jboolean OfflinePageBridge::IsShowingOfflinePreview(
    JNIEnv* env,
    const base::android::JavaParamRef<jobject>& obj,
    const JavaParamRef<jobject>& j_web_contents) {
  content::WebContents* web_contents =
      content::WebContents::FromJavaWebContents(j_web_contents);
  if (!web_contents)
    return false;
  return offline_pages::OfflinePageUtils::IsShowingOfflinePreview(web_contents);
}

jboolean OfflinePageBridge::IsShowingDownloadButtonInErrorPage(
    JNIEnv* env,
    const base::android::JavaParamRef<jobject>& obj,
    const JavaParamRef<jobject>& j_web_contents) {
  content::WebContents* web_contents =
      content::WebContents::FromJavaWebContents(j_web_contents);
  if (!web_contents)
    return false;
  return offline_pages::OfflinePageUtils::IsShowingDownloadButtonInErrorPage(
      web_contents);
}

void OfflinePageBridge::GetRequestsInQueue(
    JNIEnv* env,
    const JavaParamRef<jobject>& obj,
    const JavaParamRef<jobject>& j_callback_obj) {
  ScopedJavaGlobalRef<jobject> j_callback_ref(j_callback_obj);

  RequestCoordinator* coordinator =
      offline_pages::RequestCoordinatorFactory::GetInstance()
          ->GetForBrowserContext(browser_context_);

  if (!coordinator) {
    // Callback with null to signal that results are unavailable.
    const JavaParamRef<jobject> empty_result(nullptr);
    base::android::RunCallbackAndroid(j_callback_obj, empty_result);
    return;
  }

  coordinator->GetAllRequests(
      base::BindOnce(&OnGetAllRequestsDone, j_callback_ref));
}

void OfflinePageBridge::RemoveRequestsFromQueue(
    JNIEnv* env,
    const JavaParamRef<jobject>& obj,
    const JavaParamRef<jlongArray>& j_request_ids_array,
    const JavaParamRef<jobject>& j_callback_obj) {
  std::vector<int64_t> request_ids;
  base::android::JavaLongArrayToInt64Vector(env, j_request_ids_array,
                                            &request_ids);
  ScopedJavaGlobalRef<jobject> j_callback_ref(j_callback_obj);

  RequestCoordinator* coordinator =
      offline_pages::RequestCoordinatorFactory::GetInstance()
          ->GetForBrowserContext(browser_context_);

  if (!coordinator) {
    // Callback with null to signal that results are unavailable.
    const JavaParamRef<jobject> empty_result(nullptr);
    base::android::RunCallbackAndroid(j_callback_obj, empty_result);
    return;
  }

  coordinator->RemoveRequests(
      request_ids, base::BindOnce(&OnRemoveRequestsDone, j_callback_ref));
}

void OfflinePageBridge::WillCloseTab(
    JNIEnv* env,
    const JavaParamRef<jobject>& obj,
    const JavaParamRef<jobject>& j_web_contents) {
  DCHECK(j_web_contents);
  content::WebContents* web_contents =
      content::WebContents::FromJavaWebContents(j_web_contents);
  DCHECK(web_contents);
  if (!web_contents)
    return;

  RecentTabHelper* tab_helper = RecentTabHelper::FromWebContents(web_contents);
  if (tab_helper)
    tab_helper->WillCloseTab();
}

void OfflinePageBridge::ScheduleDownload(
    JNIEnv* env,
    const JavaParamRef<jobject>& obj,
    const base::android::JavaParamRef<jobject>& j_web_contents,
    const JavaParamRef<jstring>& j_namespace,
    const JavaParamRef<jstring>& j_url,
    int ui_action,
    const JavaParamRef<jstring>& j_origin) {
  content::WebContents* web_contents =
      content::WebContents::FromJavaWebContents(j_web_contents);
  OfflinePageUtils::ScheduleDownload(
      web_contents, ConvertJavaStringToUTF8(env, j_namespace),
      GURL(ConvertJavaStringToUTF8(env, j_url)),
      static_cast<OfflinePageUtils::DownloadUIActionFlags>(ui_action),
      ConvertJavaStringToUTF8(env, j_origin));
}

jboolean OfflinePageBridge::IsOfflinePage(
    JNIEnv* env,
    const JavaParamRef<jobject>& obj,
    const base::android::JavaParamRef<jobject>& j_web_contents) {
  content::WebContents* web_contents =
      content::WebContents::FromJavaWebContents(j_web_contents);
  return offline_pages::OfflinePageUtils::GetOfflinePageFromWebContents(
             web_contents) != nullptr;
}

jboolean OfflinePageBridge::IsInPrivateDirectory(
    JNIEnv* env,
    const base::android::JavaParamRef<jobject>& obj,
    const base::android::JavaParamRef<jstring>& j_file_path) {
  base::FilePath file_path(ConvertJavaStringToUTF8(env, j_file_path));
  return offline_page_model_->IsArchiveInInternalDir(file_path);
}

jboolean OfflinePageBridge::IsUserRequestedDownloadNamespace(
    JNIEnv* env,
    const base::android::JavaParamRef<jobject>& obj,
    const base::android::JavaParamRef<jstring>& j_name_space) {
  std::string name_space(ConvertJavaStringToUTF8(env, j_name_space));
  return (offline_page_model_->GetPolicyController()->IsUserRequestedDownload(
      name_space));
}

ScopedJavaLocalRef<jobject> OfflinePageBridge::GetOfflinePage(
    JNIEnv* env,
    const JavaParamRef<jobject>& obj,
    const base::android::JavaParamRef<jobject>& j_web_contents) {
  const offline_pages::OfflinePageItem* offline_page =
      offline_pages::OfflinePageUtils::GetOfflinePageFromWebContents(
          content::WebContents::FromJavaWebContents(j_web_contents));
  if (!offline_page)
    return ScopedJavaLocalRef<jobject>();

  return offline_pages::android::OfflinePageBridge::ConvertToJavaOfflinePage(
      env, *offline_page);
}

void OfflinePageBridge::CheckForNewOfflineContent(
    JNIEnv* env,
    const JavaParamRef<jobject>& obj,
    const jlong j_timestamp_millis,
    const JavaParamRef<jobject>& j_callback_obj) {
  base::Time pages_created_after = base::Time::FromJavaTime(j_timestamp_millis);
  ScopedJavaGlobalRef<jobject> j_callback_ref(j_callback_obj);

  offline_page_model_->GetPagesSupportedByDownloads(base::Bind(
      &CheckForNewOfflineContentCallback, pages_created_after, j_callback_ref));
}

void OfflinePageBridge::GetLaunchUrlByOfflineId(
    JNIEnv* env,
    const base::android::JavaParamRef<jobject>& obj,
    jlong j_offline_id,
    const base::android::JavaParamRef<jobject>& j_callback_obj) {
  ScopedJavaGlobalRef<jobject> j_callback_ref(j_callback_obj);

  offline_page_model_->GetPageByOfflineId(
      j_offline_id, base::Bind(&OfflinePageBridge::GetPageByOfflineIdDone,
                               weak_ptr_factory_.GetWeakPtr(), j_callback_ref));
}

void OfflinePageBridge::GetLoadUrlParamsForOpeningMhtmlFileOrContent(
    JNIEnv* env,
    const base::android::JavaParamRef<jobject>& obj,
    const base::android::JavaParamRef<jstring>& j_url,
    const base::android::JavaParamRef<jobject>& j_callback_obj) {
  GURL url(ConvertJavaStringToUTF8(env, j_url));
  base::FilePath file_path;
  if (url.SchemeIsFile()) {
    net::FileURLToFilePath(url, &file_path);
  } else {
    DCHECK(url.SchemeIs("content"));
    // Content URI can be embeded in the file path and FileStream knows how to
    // read it.
    file_path = base::FilePath(url.spec());
  }

  ScopedJavaGlobalRef<jobject> j_callback_ref(j_callback_obj);
  base::PostTaskWithTraitsAndReplyWithResult(
      FROM_HERE, {base::MayBlock(), base::TaskPriority::BACKGROUND},
      base::Bind(&ArchiveValidator::GetSizeAndComputeDigest, file_path),
      base::Bind(&OfflinePageBridge::GetSizeAndComputeDigestDone,
                 weak_ptr_factory_.GetWeakPtr(), j_callback_ref, url));
}

jboolean OfflinePageBridge::IsShowingTrustedOfflinePage(
    JNIEnv* env,
    const base::android::JavaParamRef<jobject>& obj,
    const base::android::JavaParamRef<jobject>& j_web_contents) {
  content::WebContents* web_contents =
      content::WebContents::FromJavaWebContents(j_web_contents);
  if (!web_contents)
    return false;
  return offline_pages::OfflinePageUtils::IsShowingTrustedOfflinePage(
      web_contents);
}

void OfflinePageBridge::GetPageByOfflineIdDone(
    const ScopedJavaGlobalRef<jobject>& j_callback_obj,
    const OfflinePageItem* offline_page) {
  if (!offline_page) {
    GetLaunchUrlByOfflineIdCallback(j_callback_obj, std::string());
    return;
  }

  if (offline_page_model_->IsArchiveInInternalDir(offline_page->file_path)) {
    GetLaunchUrlByOfflineIdCallback(j_callback_obj, offline_page->url.spec());
    return;
  }

  base::PostTaskWithTraitsAndReplyWithResult(
      FROM_HERE, {base::MayBlock(), base::TaskPriority::BACKGROUND},
      base::Bind(&ArchiveValidator::ValidateFile, offline_page->file_path,
                 offline_page->file_size, offline_page->digest),
      base::Bind(&ValidateFileCallback, j_callback_obj, offline_page->url,
                 offline_page->file_path));
}

void OfflinePageBridge::GetSizeAndComputeDigestDone(
    const ScopedJavaGlobalRef<jobject>& j_callback_obj,
    const GURL& intent_url,
    std::pair<int64_t, std::string> size_and_digest) {
  // If size or digest can't be obtained, launch the intent URL.
  if (!size_and_digest.first || size_and_digest.second.empty()) {
    GetLaunchUrlBySizeAndDigestCallback(j_callback_obj, intent_url,
                                        std::string());
    return;
  }

  offline_page_model_->GetPageBySizeAndDigest(
      size_and_digest.first, size_and_digest.second,
      base::BindOnce(&OfflinePageBridge::GetPageBySizeAndDigestDone,
                     weak_ptr_factory_.GetWeakPtr(), j_callback_obj,
                     intent_url));
}

void OfflinePageBridge::GetPageBySizeAndDigestDone(
    const ScopedJavaGlobalRef<jobject>& j_callback_obj,
    const GURL& intent_url,
    const OfflinePageItem* offline_page) {
  GURL launch_url;
  std::string extra_headers;
  if (offline_page) {
    launch_url = offline_page->url;
    offline_pages::OfflinePageHeader offline_header;
    offline_header.reason =
        intent_url.SchemeIsFile()
            ? offline_pages::OfflinePageHeader::Reason::FILE_URL_INTENT
            : offline_pages::OfflinePageHeader::Reason::CONTENT_URL_INTENT;
    offline_header.need_to_persist = true;
    offline_header.id = base::Int64ToString(offline_page->offline_id);
    offline_header.intent_url = intent_url;
    extra_headers = offline_header.GetCompleteHeaderString();
  } else {
    // If the offline page can't be found, launch the intent URL.
    launch_url = intent_url;
  }
  GetLaunchUrlBySizeAndDigestCallback(j_callback_obj, launch_url,
                                      extra_headers);
}

void OfflinePageBridge::AcquireFileAccessPermission(
    JNIEnv* env,
    const base::android::JavaParamRef<jobject>& obj,
    const base::android::JavaParamRef<jobject>& j_web_contents,
    const base::android::JavaParamRef<jobject>& j_callback_obj) {
  ScopedJavaGlobalRef<jobject> j_callback_ref(j_callback_obj);
  content::WebContents* web_contents =
      content::WebContents::FromJavaWebContents(j_web_contents);
  if (!web_contents) {
    AcquireFileAccessPermissionCallback(j_callback_ref, false);
    return;
  }
  OfflinePageUtils::AcquireFileAccessPermission(
      web_contents,
      base::BindOnce(&AcquireFileAccessPermissionCallback, j_callback_ref));
}

void OfflinePageBridge::NotifyIfDoneLoading() const {
  JNIEnv* env = base::android::AttachCurrentThread();
  Java_OfflinePageBridge_offlinePageModelLoaded(env, java_ref_);
}


ScopedJavaLocalRef<jobject> OfflinePageBridge::CreateClientId(
    JNIEnv* env,
    const ClientId& client_id) const {
  return Java_OfflinePageBridge_createClientId(
      env, ConvertUTF8ToJavaString(env, client_id.name_space),
      ConvertUTF8ToJavaString(env, client_id.id));
}

}  // namespace android
}  // namespace offline_pages
