// Copyright 2020 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "components/omnibox/browser/autocomplete_match.h"

#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/functional/bind.h"
#include "base/uuid.h"
#include "components/omnibox/browser/actions/omnibox_action.h"
#include "components/omnibox/browser/actions/omnibox_action_factory_android.h"
#include "components/omnibox/browser/clipboard_provider.h"
#include "components/omnibox/browser/search_suggestion_parser.h"
#include "components/omnibox/common/omnibox_feature_configs.h"
#include "components/saved_tab_groups/public/android/tab_group_sync_conversions_bridge.h"
#include "components/saved_tab_groups/public/android/tab_group_sync_conversions_utils.h"
#include "third_party/omnibox_proto/suggest_template_info.pb.h"
#include "url/android/gurl_android.h"

// Must come after all headers that specialize FromJniType() / ToJniType().
#include "components/omnibox/browser/jni_headers/AutocompleteMatch_jni.h"

using base::android::ConvertUTF16ToJavaString;
using base::android::ConvertUTF8ToJavaString;
using base::android::RunRunnableAndroid;
using base::android::ScopedJavaGlobalRef;
using base::android::ScopedJavaLocalRef;
using base::android::ToJavaArrayOfStrings;
using base::android::ToJavaByteArray;
using base::android::ToJavaIntArray;

// static
jclass AutocompleteMatch::GetClazz(JNIEnv* env) {
  return org_chromium_components_omnibox_AutocompleteMatch_clazz(env);
}

ScopedJavaLocalRef<jobject> AutocompleteMatch::GetOrCreateJavaObject(
    JNIEnv* env) const {
  // Short circuit if we already built the match.
  if (java_match_)
    return ScopedJavaLocalRef<jobject>(*java_match_);

  std::vector<int> contents_class_offsets;
  std::vector<int> contents_class_styles;
  for (auto contents_class_item : contents_class) {
    contents_class_offsets.push_back(contents_class_item.offset);
    contents_class_styles.push_back(contents_class_item.style);
  }

  std::vector<int> description_class_offsets;
  std::vector<int> description_class_styles;
  for (auto description_class_item : description_class) {
    description_class_offsets.push_back(description_class_item.offset);
    description_class_styles.push_back(description_class_item.style);
  }

  ScopedJavaLocalRef<jbyteArray> j_answer_template;
  if (answer_template) {
    std::string str_answer_template;
    if (answer_template->SerializeToString(&str_answer_template)) {
      j_answer_template =
          base::android::ToJavaByteArray(env, str_answer_template);
    }
  }

  ScopedJavaLocalRef<jstring> j_image_dominant_color;
  ScopedJavaLocalRef<jstring> j_post_content_type;
  ScopedJavaLocalRef<jbyteArray> j_post_content;
  std::string clipboard_image_data;

  if (!image_dominant_color.empty()) {
    j_image_dominant_color = ConvertUTF8ToJavaString(env, image_dominant_color);
  }

  if (post_content && !post_content->first.empty() &&
      !post_content->second.empty()) {
    j_post_content_type = ConvertUTF8ToJavaString(env, post_content->first);
    j_post_content = ToJavaByteArray(env, post_content->second);
  }

  if (search_terms_args.get()) {
    clipboard_image_data = search_terms_args->image_thumbnail_content;
  }

  std::vector<int> temp_subtypes(subtypes.begin(), subtypes.end());

  std::vector<jni_zero::ScopedJavaLocalRef<jobject>> actions_list;
  if (actions.empty() && takeover_action) {
    actions_list = ToJavaOmniboxActionsList(env, {takeover_action});
  } else {
    actions_list = ToJavaOmniboxActionsList(env, actions);
  }

  int icon_type = omnibox::SuggestTemplateInfo::IconType::
      SuggestTemplateInfo_IconType_ICON_TYPE_UNSPECIFIED;

  ScopedJavaLocalRef<jbyteArray> j_suggest_template;

  if (suggest_template.has_value()) {
    icon_type = suggest_template.value().type_icon();

    std::string str_suggest_template;
    if (suggest_template->SerializeToString(&str_suggest_template)) {
      j_suggest_template =
          base::android::ToJavaByteArray(env, str_suggest_template);
    }
  }

  java_match_ = std::make_unique<ScopedJavaGlobalRef<jobject>>(
      Java_AutocompleteMatch_build(
          env, reinterpret_cast<intptr_t>(this), type,
          ToJavaIntArray(env, temp_subtypes), IsSearchType(type), icon_type,
          transition, ConvertUTF16ToJavaString(env, contents),
          ToJavaIntArray(env, contents_class_offsets),
          ToJavaIntArray(env, contents_class_styles),
          ConvertUTF16ToJavaString(env, description),
          ToJavaIntArray(env, description_class_offsets),
          ToJavaIntArray(env, description_class_styles), j_answer_template,
          answer_type, ConvertUTF16ToJavaString(env, fill_into_edit),
          url::GURLAndroid::FromNativeGURL(env, destination_url),
          url::GURLAndroid::FromNativeGURL(env, image_url),
          j_image_dominant_color, SupportsDeletion(), j_post_content_type,
          j_post_content, suggestion_group_id.value_or(omnibox::GROUP_INVALID),
          ToJavaByteArray(env, clipboard_image_data),
          has_tab_match.value_or(false), actions_list,
          allowed_to_be_default_match,
          ConvertUTF16ToJavaString(env, inline_autocompletion),
          ConvertUTF16ToJavaString(env, additional_text),
          tab_groups::UuidToJavaString(
              env, matching_tab_group_uuid.value_or(base::Uuid())),
          j_suggest_template));

  return ScopedJavaLocalRef<jobject>(*java_match_);
}

void AutocompleteMatch::UpdateJavaObjectNativeRef() {
  if (!java_match_)
    return;

  JNIEnv* env = base::android::AttachCurrentThread();
  Java_AutocompleteMatch_updateNativeObjectRef(
      env, *java_match_, reinterpret_cast<intptr_t>(this));
}

void AutocompleteMatch::DestroyJavaObject() {
  if (!java_match_)
    return;

  JNIEnv* env = base::android::AttachCurrentThread();
  Java_AutocompleteMatch_destroy(env, *java_match_);
  java_match_.reset();
}

void AutocompleteMatch::UpdateWithClipboardContent(
    JNIEnv* env,
    const base::android::JavaRef<jobject>& j_callback) {
  DCHECK(provider) << "No provider available";
  DCHECK(provider->type() == AutocompleteProvider::TYPE_CLIPBOARD)
      << "Invalid provider type: " << provider->type();

  ClipboardProvider* clipboard_provider =
      static_cast<ClipboardProvider*>(provider);
  clipboard_provider->UpdateClipboardMatchWithContent(
      this,
      base::BindOnce(&AutocompleteMatch::OnClipboardSuggestionContentUpdated,
                     weak_ptr_factory_.GetWeakPtr(),
                     base::android::ScopedJavaGlobalRef<jobject>(j_callback)));
}

void AutocompleteMatch::OnClipboardSuggestionContentUpdated(
    const base::android::JavaRef<jobject>& j_callback) {
  JNIEnv* env = base::android::AttachCurrentThread();
  UpdateClipboardContent(env);
  RunRunnableAndroid(j_callback);
}

void AutocompleteMatch::UpdateClipboardContent(JNIEnv* env) {
  if (!java_match_)
    return;

  std::string clipboard_image_data;
  if (search_terms_args.get()) {
    clipboard_image_data = search_terms_args->image_thumbnail_content;
  }

  ScopedJavaLocalRef<jstring> j_post_content_type;
  ScopedJavaLocalRef<jbyteArray> j_post_content;
  if (post_content && !post_content->first.empty() &&
      !post_content->second.empty()) {
    j_post_content_type = ConvertUTF8ToJavaString(env, post_content->first);
    j_post_content = ToJavaByteArray(env, post_content->second);
  }

  Java_AutocompleteMatch_updateClipboardContent(
      env, *java_match_, ConvertUTF16ToJavaString(env, contents),
      url::GURLAndroid::FromNativeGURL(env, destination_url),
      j_post_content_type, j_post_content,
      ToJavaByteArray(env, clipboard_image_data));
}

void AutocompleteMatch::UpdateJavaNavigationDetails() {
  if (java_match_) {
    JNIEnv* env = base::android::AttachCurrentThread();

    std::vector<std::string> header_keys;
    std::vector<std::string> header_vals;
    for (const auto& [key, val] : extra_headers) {
      header_keys.emplace_back(key);
      header_vals.emplace_back(val);
    }

    Java_AutocompleteMatch_updateNavigationDetails(
        env, *java_match_,
        url::GURLAndroid::FromNativeGURL(env, destination_url),
        ToJavaArrayOfStrings(env, header_keys),
        ToJavaArrayOfStrings(env, header_vals));
  }
}

void AutocompleteMatch::UpdateJavaAnswer() {
  if (java_match_) {
    JNIEnv* env = base::android::AttachCurrentThread();
    if (answer_template) {
      ScopedJavaLocalRef<jbyteArray> j_answer_template;
      std::string str_answer_template;
      if (answer_template->SerializeToString(&str_answer_template)) {
        j_answer_template =
            base::android::ToJavaByteArray(env, str_answer_template);
      }
      Java_AutocompleteMatch_setAnswerTemplate(
          env, *java_match_, answer_template ? j_answer_template : nullptr);
    }
    Java_AutocompleteMatch_setAnswerType(env, *java_match_, answer_type);
  }
}

void AutocompleteMatch::UpdateJavaDescription() {
  if (java_match_) {
    std::vector<int> description_class_offsets;
    std::vector<int> description_class_styles;
    for (auto description_class_item : description_class) {
      description_class_offsets.push_back(description_class_item.offset);
      description_class_styles.push_back(description_class_item.style);
    }
    JNIEnv* env = base::android::AttachCurrentThread();
    Java_AutocompleteMatch_setDescription(
        env, *java_match_, ConvertUTF16ToJavaString(env, description),
        ToJavaIntArray(env, description_class_offsets),
        ToJavaIntArray(env, description_class_styles));
  }
}

DEFINE_JNI(AutocompleteMatch)
