/*
 * Copyright (C) 2018 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "annotator/annotator_jni_common.h"

#include "annotator/knowledge/knowledge-engine-types.h"
#include "utils/java/jni-base.h"
#include "utils/java/jni-helper.h"

namespace libtextclassifier3 {
namespace {

StatusOr<std::unordered_set<std::string>> EntityTypesFromJObject(
    JNIEnv* env, const jobject& jobject) {
  std::unordered_set<std::string> entity_types;
  jobjectArray jentity_types = reinterpret_cast<jobjectArray>(jobject);
  TC3_ASSIGN_OR_RETURN(const int size,
                       JniHelper::GetArrayLength(env, jentity_types));
  for (int i = 0; i < size; ++i) {
    TC3_ASSIGN_OR_RETURN(
        ScopedLocalRef<jstring> jentity_type,
        JniHelper::GetObjectArrayElement<jstring>(env, jentity_types, i));
    TC3_ASSIGN_OR_RETURN(std::string entity_type,
                         JStringToUtf8String(env, jentity_type.get()));
    entity_types.insert(entity_type);
  }
  return entity_types;
}

template <typename T>
StatusOr<T> FromJavaOptionsInternal(JNIEnv* env, jobject joptions,
                                    const std::string& class_name) {
  if (!joptions) {
    return {Status::UNKNOWN};
  }

  TC3_ASSIGN_OR_RETURN(ScopedLocalRef<jclass> options_class,
                       JniHelper::FindClass(env, class_name.c_str()));

  // .getLocale()
  TC3_ASSIGN_OR_RETURN(
      jmethodID get_locale,
      JniHelper::GetMethodID(env, options_class.get(), "getLocale",
                             "()Ljava/lang/String;"));
  TC3_ASSIGN_OR_RETURN(
      ScopedLocalRef<jstring> locales,
      JniHelper::CallObjectMethod<jstring>(env, joptions, get_locale));

  // .getReferenceTimeMsUtc()
  TC3_ASSIGN_OR_RETURN(jmethodID get_reference_time_method,
                       JniHelper::GetMethodID(env, options_class.get(),
                                              "getReferenceTimeMsUtc", "()J"));
  TC3_ASSIGN_OR_RETURN(
      int64 reference_time,
      JniHelper::CallLongMethod(env, joptions, get_reference_time_method));

  // .getReferenceTimezone()
  TC3_ASSIGN_OR_RETURN(
      jmethodID get_reference_timezone_method,
      JniHelper::GetMethodID(env, options_class.get(), "getReferenceTimezone",
                             "()Ljava/lang/String;"));
  TC3_ASSIGN_OR_RETURN(ScopedLocalRef<jstring> reference_timezone,
                       JniHelper::CallObjectMethod<jstring>(
                           env, joptions, get_reference_timezone_method));

  // .getDetectedTextLanguageTags()
  TC3_ASSIGN_OR_RETURN(jmethodID get_detected_text_language_tags_method,
                       JniHelper::GetMethodID(env, options_class.get(),
                                              "getDetectedTextLanguageTags",
                                              "()Ljava/lang/String;"));
  TC3_ASSIGN_OR_RETURN(
      ScopedLocalRef<jstring> detected_text_language_tags,
      JniHelper::CallObjectMethod<jstring>(
          env, joptions, get_detected_text_language_tags_method));

  // .getAnnotationUsecase()
  TC3_ASSIGN_OR_RETURN(jmethodID get_annotation_usecase,
                       JniHelper::GetMethodID(env, options_class.get(),
                                              "getAnnotationUsecase", "()I"));
  TC3_ASSIGN_OR_RETURN(
      int32 annotation_usecase,
      JniHelper::CallIntMethod(env, joptions, get_annotation_usecase));

  // .getUserLocationLat()
  TC3_ASSIGN_OR_RETURN(jmethodID get_user_location_lat,
                       JniHelper::GetMethodID(env, options_class.get(),
                                              "getUserLocationLat", "()D"));
  TC3_ASSIGN_OR_RETURN(
      double user_location_lat,
      JniHelper::CallDoubleMethod(env, joptions, get_user_location_lat));

  // .getUserLocationLng()
  TC3_ASSIGN_OR_RETURN(jmethodID get_user_location_lng,
                       JniHelper::GetMethodID(env, options_class.get(),
                                              "getUserLocationLng", "()D"));
  TC3_ASSIGN_OR_RETURN(
      double user_location_lng,
      JniHelper::CallDoubleMethod(env, joptions, get_user_location_lng));

  // .getUserLocationAccuracyMeters()
  TC3_ASSIGN_OR_RETURN(
      jmethodID get_user_location_accuracy_meters,
      JniHelper::GetMethodID(env, options_class.get(),
                             "getUserLocationAccuracyMeters", "()F"));
  TC3_ASSIGN_OR_RETURN(float user_location_accuracy_meters,
                       JniHelper::CallFloatMethod(
                           env, joptions, get_user_location_accuracy_meters));

  // .getUsePodNer()
  TC3_ASSIGN_OR_RETURN(
      jmethodID get_use_pod_ner,
      JniHelper::GetMethodID(env, options_class.get(), "getUsePodNer", "()Z"));
  TC3_ASSIGN_OR_RETURN(bool use_pod_ner, JniHelper::CallBooleanMethod(
                                             env, joptions, get_use_pod_ner));

  // .getUseVocabAnnotator()
  TC3_ASSIGN_OR_RETURN(jmethodID get_use_vocab_annotator,
                       JniHelper::GetMethodID(env, options_class.get(),
                                              "getUseVocabAnnotator", "()Z"));
  TC3_ASSIGN_OR_RETURN(
      bool use_vocab_annotator,
      JniHelper::CallBooleanMethod(env, joptions, get_use_vocab_annotator));
  T options;
  TC3_ASSIGN_OR_RETURN(options.locales,
                       JStringToUtf8String(env, locales.get()));
  TC3_ASSIGN_OR_RETURN(options.reference_timezone,
                       JStringToUtf8String(env, reference_timezone.get()));
  options.reference_time_ms_utc = reference_time;
  TC3_ASSIGN_OR_RETURN(
      options.detected_text_language_tags,
      JStringToUtf8String(env, detected_text_language_tags.get()));
  options.annotation_usecase =
      static_cast<AnnotationUsecase>(annotation_usecase);
  options.location_context = {user_location_lat, user_location_lng,
                              user_location_accuracy_meters};
  options.use_pod_ner = use_pod_ner;
  options.use_vocab_annotator = use_vocab_annotator;
  return options;
}
}  // namespace

StatusOr<SelectionOptions> FromJavaSelectionOptions(JNIEnv* env,
                                                    jobject joptions) {
  if (!joptions) {
    // Falling back to default options in case joptions is null
    SelectionOptions default_selection_options;
    return default_selection_options;
  }

  TC3_ASSIGN_OR_RETURN(
      ScopedLocalRef<jclass> options_class,
      JniHelper::FindClass(env, TC3_PACKAGE_PATH TC3_ANNOTATOR_CLASS_NAME_STR
                           "$SelectionOptions"));

  // .getLocale()
  TC3_ASSIGN_OR_RETURN(
      jmethodID get_locales,
      JniHelper::GetMethodID(env, options_class.get(), "getLocales",
                             "()Ljava/lang/String;"));
  TC3_ASSIGN_OR_RETURN(
      ScopedLocalRef<jstring> locales,
      JniHelper::CallObjectMethod<jstring>(env, joptions, get_locales));

  // .getDetectedTextLanguageTags()
  TC3_ASSIGN_OR_RETURN(jmethodID get_detected_text_language_tags_method,
                       JniHelper::GetMethodID(env, options_class.get(),
                                              "getDetectedTextLanguageTags",
                                              "()Ljava/lang/String;"));
  TC3_ASSIGN_OR_RETURN(
      ScopedLocalRef<jstring> detected_text_language_tags,
      JniHelper::CallObjectMethod<jstring>(
          env, joptions, get_detected_text_language_tags_method));

  // .getAnnotationUsecase()
  TC3_ASSIGN_OR_RETURN(jmethodID get_annotation_usecase,
                       JniHelper::GetMethodID(env, options_class.get(),
                                              "getAnnotationUsecase", "()I"));
  TC3_ASSIGN_OR_RETURN(
      int32 annotation_usecase,
      JniHelper::CallIntMethod(env, joptions, get_annotation_usecase));

  // .getUserLocationLat()
  TC3_ASSIGN_OR_RETURN(jmethodID get_user_location_lat,
                       JniHelper::GetMethodID(env, options_class.get(),
                                              "getUserLocationLat", "()D"));
  TC3_ASSIGN_OR_RETURN(
      double user_location_lat,
      JniHelper::CallDoubleMethod(env, joptions, get_user_location_lat));

  // .getUserLocationLng()
  TC3_ASSIGN_OR_RETURN(jmethodID get_user_location_lng,
                       JniHelper::GetMethodID(env, options_class.get(),
                                              "getUserLocationLng", "()D"));
  TC3_ASSIGN_OR_RETURN(
      double user_location_lng,
      JniHelper::CallDoubleMethod(env, joptions, get_user_location_lng));

  // .getUserLocationAccuracyMeters()
  TC3_ASSIGN_OR_RETURN(
      jmethodID get_user_location_accuracy_meters,
      JniHelper::GetMethodID(env, options_class.get(),
                             "getUserLocationAccuracyMeters", "()F"));
  TC3_ASSIGN_OR_RETURN(float user_location_accuracy_meters,
                       JniHelper::CallFloatMethod(
                           env, joptions, get_user_location_accuracy_meters));

  // .getUsePodNer()
  TC3_ASSIGN_OR_RETURN(
      jmethodID get_use_pod_ner,
      JniHelper::GetMethodID(env, options_class.get(), "getUsePodNer", "()Z"));
  TC3_ASSIGN_OR_RETURN(bool use_pod_ner, JniHelper::CallBooleanMethod(
                                             env, joptions, get_use_pod_ner));

  SelectionOptions options;
  TC3_ASSIGN_OR_RETURN(options.locales,
                       JStringToUtf8String(env, locales.get()));
  options.annotation_usecase =
      static_cast<AnnotationUsecase>(annotation_usecase);
  TC3_ASSIGN_OR_RETURN(
      options.detected_text_language_tags,
      JStringToUtf8String(env, detected_text_language_tags.get()));
  options.location_context = {user_location_lat, user_location_lng,
                              user_location_accuracy_meters};
  options.use_pod_ner = use_pod_ner;
  return options;
}

StatusOr<ClassificationOptions> FromJavaClassificationOptions(
    JNIEnv* env, jobject joptions) {
  if (!joptions) {
    // Falling back to default options in case joptions is null
    ClassificationOptions default_classification_options;
    return default_classification_options;
  }

  TC3_ASSIGN_OR_RETURN(ClassificationOptions classifier_options,
                       FromJavaOptionsInternal<ClassificationOptions>(
                           env, joptions,
                           TC3_PACKAGE_PATH TC3_ANNOTATOR_CLASS_NAME_STR
                           "$ClassificationOptions"));

  TC3_ASSIGN_OR_RETURN(
      ScopedLocalRef<jclass> options_class,
      JniHelper::FindClass(env, TC3_PACKAGE_PATH TC3_ANNOTATOR_CLASS_NAME_STR
                           "$ClassificationOptions"));
  // .getUserFamiliarLanguageTags()
  TC3_ASSIGN_OR_RETURN(jmethodID get_user_familiar_language_tags,
                       JniHelper::GetMethodID(env, options_class.get(),
                                              "getUserFamiliarLanguageTags",
                                              "()Ljava/lang/String;"));
  TC3_ASSIGN_OR_RETURN(ScopedLocalRef<jstring> user_familiar_language_tags,
                       JniHelper::CallObjectMethod<jstring>(
                           env, joptions, get_user_familiar_language_tags));

  TC3_ASSIGN_OR_RETURN(
      classifier_options.user_familiar_language_tags,
      JStringToUtf8String(env, user_familiar_language_tags.get()));

  // .getTriggerDictionaryOnBeginnerWords()
  TC3_ASSIGN_OR_RETURN(
      jmethodID get_trigger_dictionary_on_beginner_words,
      JniHelper::GetMethodID(env, options_class.get(),
                             "getTriggerDictionaryOnBeginnerWords", "()Z"));
  TC3_ASSIGN_OR_RETURN(
      classifier_options.trigger_dictionary_on_beginner_words,
      JniHelper::CallBooleanMethod(env, joptions,
                                   get_trigger_dictionary_on_beginner_words));

  return classifier_options;
}

StatusOr<AnnotationOptions> FromJavaAnnotationOptions(JNIEnv* env,
                                                      jobject joptions) {
  if (!joptions) {
    // Falling back to default options in case joptions is null
    AnnotationOptions default_annotation_options;
    return default_annotation_options;
  }

  TC3_ASSIGN_OR_RETURN(
      ScopedLocalRef<jclass> options_class,
      JniHelper::FindClass(env, TC3_PACKAGE_PATH TC3_ANNOTATOR_CLASS_NAME_STR
                           "$AnnotationOptions"));

  // .getEntityTypes()
  TC3_ASSIGN_OR_RETURN(
      jmethodID get_entity_types,
      JniHelper::GetMethodID(env, options_class.get(), "getEntityTypes",
                             "()[Ljava/lang/String;"));
  TC3_ASSIGN_OR_RETURN(
      ScopedLocalRef<jobject> entity_types,
      JniHelper::CallObjectMethod<jobject>(env, joptions, get_entity_types));

  // .isSerializedEntityDataEnabled()
  TC3_ASSIGN_OR_RETURN(
      jmethodID is_serialized_entity_data_enabled_method,
      JniHelper::GetMethodID(env, options_class.get(),
                             "isSerializedEntityDataEnabled", "()Z"));
  TC3_ASSIGN_OR_RETURN(
      bool is_serialized_entity_data_enabled,
      JniHelper::CallBooleanMethod(env, joptions,
                                   is_serialized_entity_data_enabled_method));

  // .hasLocationPermission()
  TC3_ASSIGN_OR_RETURN(jmethodID has_location_permission_method,
                       JniHelper::GetMethodID(env, options_class.get(),
                                              "hasLocationPermission", "()Z"));
  TC3_ASSIGN_OR_RETURN(bool has_location_permission,
                       JniHelper::CallBooleanMethod(
                           env, joptions, has_location_permission_method));

  // .hasPersonalizationPermission()
  TC3_ASSIGN_OR_RETURN(
      jmethodID has_personalization_permission_method,
      JniHelper::GetMethodID(env, options_class.get(),
                             "hasPersonalizationPermission", "()Z"));
  TC3_ASSIGN_OR_RETURN(
      bool has_personalization_permission,
      JniHelper::CallBooleanMethod(env, joptions,
                                   has_personalization_permission_method));
  // .getAnnotateMode()
  TC3_ASSIGN_OR_RETURN(jmethodID get_annotate_mode,
                       JniHelper::GetMethodID(env, options_class.get(),
                                              "getAnnotateMode", "()I"));
  TC3_ASSIGN_OR_RETURN(
      int32 annotate_mode,
      JniHelper::CallIntMethod(env, joptions, get_annotate_mode));

  TC3_ASSIGN_OR_RETURN(
      AnnotationOptions annotation_options,
      FromJavaOptionsInternal<AnnotationOptions>(
          env, joptions,
          TC3_PACKAGE_PATH TC3_ANNOTATOR_CLASS_NAME_STR "$AnnotationOptions"));
  TC3_ASSIGN_OR_RETURN(annotation_options.entity_types,
                       EntityTypesFromJObject(env, entity_types.get()));
  annotation_options.is_serialized_entity_data_enabled =
      is_serialized_entity_data_enabled;
  annotation_options.permissions.has_location_permission =
      has_location_permission;
  annotation_options.permissions.has_personalization_permission =
      has_personalization_permission;
  annotation_options.annotate_mode = static_cast<AnnotateMode>(annotate_mode);

  // .getTriggerDictionaryOnBeginnerWords()
  TC3_ASSIGN_OR_RETURN(
      jmethodID get_trigger_dictionary_on_beginner_words,
      JniHelper::GetMethodID(env, options_class.get(),
                             "getTriggerDictionaryOnBeginnerWords", "()Z"));
  TC3_ASSIGN_OR_RETURN(
      annotation_options.trigger_dictionary_on_beginner_words,
      JniHelper::CallBooleanMethod(env, joptions,
                                   get_trigger_dictionary_on_beginner_words));
  return annotation_options;
}

StatusOr<InputFragment> FromJavaInputFragment(JNIEnv* env, jobject jfragment) {
  if (!jfragment) {
    return Status(StatusCode::INTERNAL, "Called with null input fragment.");
  }
  InputFragment fragment;

  TC3_ASSIGN_OR_RETURN(
      ScopedLocalRef<jclass> fragment_class,
      JniHelper::FindClass(
          env, TC3_PACKAGE_PATH TC3_ANNOTATOR_CLASS_NAME_STR "$InputFragment"));

  // .getText()
  TC3_ASSIGN_OR_RETURN(
      jmethodID get_text,
      JniHelper::GetMethodID(env, fragment_class.get(), "getText",
                             "()Ljava/lang/String;"));

  TC3_ASSIGN_OR_RETURN(
      ScopedLocalRef<jstring> text,
      JniHelper::CallObjectMethod<jstring>(env, jfragment, get_text));

  TC3_ASSIGN_OR_RETURN(fragment.text, JStringToUtf8String(env, text.get()));

  // .hasDatetimeOptions()
  TC3_ASSIGN_OR_RETURN(jmethodID has_date_time_options_method,
                       JniHelper::GetMethodID(env, fragment_class.get(),
                                              "hasDatetimeOptions", "()Z"));

  TC3_ASSIGN_OR_RETURN(bool has_date_time_options,
                       JniHelper::CallBooleanMethod(
                           env, jfragment, has_date_time_options_method));

  if (has_date_time_options) {
    // .getReferenceTimeMsUtc()
    TC3_ASSIGN_OR_RETURN(
        jmethodID get_reference_time_method,
        JniHelper::GetMethodID(env, fragment_class.get(),
                               "getReferenceTimeMsUtc", "()J"));

    TC3_ASSIGN_OR_RETURN(
        int64 reference_time,
        JniHelper::CallLongMethod(env, jfragment, get_reference_time_method));

    // .getReferenceTimezone()
    TC3_ASSIGN_OR_RETURN(
        jmethodID get_reference_timezone_method,
        JniHelper::GetMethodID(env, fragment_class.get(),
                               "getReferenceTimezone", "()Ljava/lang/String;"));

    TC3_ASSIGN_OR_RETURN(ScopedLocalRef<jstring> jreference_timezone,
                         JniHelper::CallObjectMethod<jstring>(
                             env, jfragment, get_reference_timezone_method));

    TC3_ASSIGN_OR_RETURN(std::string reference_timezone,
                         JStringToUtf8String(env, jreference_timezone.get()));

    fragment.datetime_options =
        DatetimeOptions{.reference_time_ms_utc = reference_time,
                        .reference_timezone = reference_timezone};
  }

  // .getBoundingBoxHeight()
  TC3_ASSIGN_OR_RETURN(jmethodID get_bounding_box_height,
                       JniHelper::GetMethodID(env, fragment_class.get(),
                                              "getBoundingBoxHeight", "()F"));
  TC3_ASSIGN_OR_RETURN(
      float bounding_box_height,
      JniHelper::CallFloatMethod(env, jfragment, get_bounding_box_height));

  fragment.bounding_box_height = bounding_box_height;

  // .getBoundingBoxTop()
  TC3_ASSIGN_OR_RETURN(jmethodID get_bounding_box_top,
                       JniHelper::GetMethodID(env, fragment_class.get(),
                                              "getBoundingBoxTop", "()F"));
  TC3_ASSIGN_OR_RETURN(
      float bounding_box_top,
      JniHelper::CallFloatMethod(env, jfragment, get_bounding_box_top));
  fragment.bounding_box_top = bounding_box_top;
  return fragment;
}
}  // namespace libtextclassifier3
