/*
 * 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.
 */

// JNI wrapper for the Annotator.

#include "annotator/annotator_jni.h"

#include <jni.h>

#include <type_traits>
#include <utility>
#include <vector>

#include "annotator/annotator.h"
#include "annotator/annotator_jni_common.h"
#include "annotator/knowledge/knowledge-engine-types.h"
#include "annotator/types.h"
#include "utils/base/integral_types.h"
#include "utils/base/status_macros.h"
#include "utils/base/statusor.h"
#include "utils/calendar/calendar.h"
#include "utils/intents/intent-generator.h"
#include "utils/intents/jni.h"
#include "utils/intents/remote-action-template.h"
#include "utils/java/jni-cache.h"
#include "utils/java/jni-helper.h"
#include "utils/memory/mmap.h"
#include "utils/strings/stringpiece.h"
#include "utils/utf8/unilib.h"

#ifdef TC3_UNILIB_JAVAICU
#ifndef TC3_CALENDAR_JAVAICU
#error Inconsistent usage of Java ICU components
#else
#define TC3_USE_JAVAICU
#endif
#endif

using libtextclassifier3::AnnotatedSpan;
using libtextclassifier3::Annotations;
using libtextclassifier3::Annotator;
using libtextclassifier3::ClassificationResult;
using libtextclassifier3::CodepointSpan;
using libtextclassifier3::JniHelper;
using libtextclassifier3::Model;
using libtextclassifier3::ScopedLocalRef;
using libtextclassifier3::StatusOr;
// When using the Java's ICU, CalendarLib and UniLib need to be instantiated
// with a JavaVM pointer from JNI. When using a standard ICU the pointer is
// not needed and the objects are instantiated implicitly.
#ifdef TC3_USE_JAVAICU
using libtextclassifier3::CalendarLib;
using libtextclassifier3::UniLib;
#endif

namespace libtextclassifier3 {

using libtextclassifier3::CodepointSpan;

namespace {
class AnnotatorJniContext {
 public:
  static AnnotatorJniContext* Create(
      const std::shared_ptr<libtextclassifier3::JniCache>& jni_cache,
      std::unique_ptr<Annotator> model) {
    if (jni_cache == nullptr || model == nullptr) {
      return nullptr;
    }
    // Intent generator will be null if the options are not specified.
    std::unique_ptr<IntentGenerator> intent_generator =
        IntentGenerator::Create(model->model()->intent_options(),
                                model->model()->resources(), jni_cache);
    TC3_ASSIGN_OR_RETURN_NULL(
        std::unique_ptr<RemoteActionTemplatesHandler> template_handler,
        libtextclassifier3::RemoteActionTemplatesHandler::Create(jni_cache));

    return new AnnotatorJniContext(jni_cache, std::move(model),
                                   std::move(intent_generator),
                                   std::move(template_handler));
  }

  std::shared_ptr<libtextclassifier3::JniCache> jni_cache() const {
    return jni_cache_;
  }

  Annotator* model() const { return model_.get(); }

  // NOTE: Intent generator will be null if the options are not specified in
  // the model.
  IntentGenerator* intent_generator() const { return intent_generator_.get(); }

  RemoteActionTemplatesHandler* template_handler() const {
    return template_handler_.get();
  }

 private:
  AnnotatorJniContext(
      const std::shared_ptr<libtextclassifier3::JniCache>& jni_cache,
      std::unique_ptr<Annotator> model,
      std::unique_ptr<IntentGenerator> intent_generator,
      std::unique_ptr<RemoteActionTemplatesHandler> template_handler)
      : jni_cache_(jni_cache),
        model_(std::move(model)),
        intent_generator_(std::move(intent_generator)),
        template_handler_(std::move(template_handler)) {}

  std::shared_ptr<libtextclassifier3::JniCache> jni_cache_;
  std::unique_ptr<Annotator> model_;
  std::unique_ptr<IntentGenerator> intent_generator_;
  std::unique_ptr<RemoteActionTemplatesHandler> template_handler_;
};

StatusOr<ScopedLocalRef<jobject>> ClassificationResultWithIntentsToJObject(
    JNIEnv* env, const AnnotatorJniContext* model_context, jobject app_context,
    jclass result_class, jmethodID result_class_constructor,
    jclass datetime_parse_class, jmethodID datetime_parse_class_constructor,
    const jstring device_locales, const ClassificationOptions* options,
    const std::string& context, const CodepointSpan& selection_indices,
    const ClassificationResult& classification_result, bool generate_intents) {
  TC3_ASSIGN_OR_RETURN(
      ScopedLocalRef<jstring> row_string,
      JniHelper::NewStringUTF(env, classification_result.collection.c_str()));

  ScopedLocalRef<jobject> row_datetime_parse;
  if (classification_result.datetime_parse_result.IsSet()) {
    TC3_ASSIGN_OR_RETURN(
        row_datetime_parse,
        JniHelper::NewObject(
            env, datetime_parse_class, datetime_parse_class_constructor,
            classification_result.datetime_parse_result.time_ms_utc,
            classification_result.datetime_parse_result.granularity));
  }

  ScopedLocalRef<jbyteArray> serialized_knowledge_result;
  const std::string& serialized_knowledge_result_string =
      classification_result.serialized_knowledge_result;
  if (!serialized_knowledge_result_string.empty()) {
    TC3_ASSIGN_OR_RETURN(serialized_knowledge_result,
                         JniHelper::NewByteArray(
                             env, serialized_knowledge_result_string.size()));
    TC3_RETURN_IF_ERROR(JniHelper::SetByteArrayRegion(
        env, serialized_knowledge_result.get(), 0,
        serialized_knowledge_result_string.size(),
        reinterpret_cast<const jbyte*>(
            serialized_knowledge_result_string.data())));
  }

  ScopedLocalRef<jstring> contact_name;
  if (!classification_result.contact_name.empty()) {
    TC3_ASSIGN_OR_RETURN(contact_name,
                         JniHelper::NewStringUTF(
                             env, classification_result.contact_name.c_str()));
  }

  ScopedLocalRef<jstring> contact_given_name;
  if (!classification_result.contact_given_name.empty()) {
    TC3_ASSIGN_OR_RETURN(
        contact_given_name,
        JniHelper::NewStringUTF(
            env, classification_result.contact_given_name.c_str()));
  }

  ScopedLocalRef<jstring> contact_family_name;
  if (!classification_result.contact_family_name.empty()) {
    TC3_ASSIGN_OR_RETURN(
        contact_family_name,
        JniHelper::NewStringUTF(
            env, classification_result.contact_family_name.c_str()));
  }

  ScopedLocalRef<jstring> contact_nickname;
  if (!classification_result.contact_nickname.empty()) {
    TC3_ASSIGN_OR_RETURN(
        contact_nickname,
        JniHelper::NewStringUTF(
            env, classification_result.contact_nickname.c_str()));
  }

  ScopedLocalRef<jstring> contact_email_address;
  if (!classification_result.contact_email_address.empty()) {
    TC3_ASSIGN_OR_RETURN(
        contact_email_address,
        JniHelper::NewStringUTF(
            env, classification_result.contact_email_address.c_str()));
  }

  ScopedLocalRef<jstring> contact_phone_number;
  if (!classification_result.contact_phone_number.empty()) {
    TC3_ASSIGN_OR_RETURN(
        contact_phone_number,
        JniHelper::NewStringUTF(
            env, classification_result.contact_phone_number.c_str()));
  }

  ScopedLocalRef<jstring> contact_account_type;
  if (!classification_result.contact_account_type.empty()) {
    TC3_ASSIGN_OR_RETURN(
        contact_account_type,
        JniHelper::NewStringUTF(
            env, classification_result.contact_account_type.c_str()));
  }

  ScopedLocalRef<jstring> contact_account_name;
  if (!classification_result.contact_account_name.empty()) {
    TC3_ASSIGN_OR_RETURN(
        contact_account_name,
        JniHelper::NewStringUTF(
            env, classification_result.contact_account_name.c_str()));
  }

  ScopedLocalRef<jstring> contact_id;
  if (!classification_result.contact_id.empty()) {
    TC3_ASSIGN_OR_RETURN(
        contact_id,
        JniHelper::NewStringUTF(env, classification_result.contact_id.c_str()));
  }

  ScopedLocalRef<jstring> app_name;
  if (!classification_result.app_name.empty()) {
    TC3_ASSIGN_OR_RETURN(
        app_name,
        JniHelper::NewStringUTF(env, classification_result.app_name.c_str()));
  }

  ScopedLocalRef<jstring> app_package_name;
  if (!classification_result.app_package_name.empty()) {
    TC3_ASSIGN_OR_RETURN(
        app_package_name,
        JniHelper::NewStringUTF(
            env, classification_result.app_package_name.c_str()));
  }

  ScopedLocalRef<jobjectArray> extras;
  if (model_context->model()->entity_data_schema() != nullptr &&
      !classification_result.serialized_entity_data.empty()) {
    TC3_ASSIGN_OR_RETURN(
        extras,
        model_context->template_handler()->EntityDataAsNamedVariantArray(
            model_context->model()->entity_data_schema(),
            classification_result.serialized_entity_data));
  }

  ScopedLocalRef<jbyteArray> serialized_entity_data;
  if (!classification_result.serialized_entity_data.empty()) {
    TC3_ASSIGN_OR_RETURN(
        serialized_entity_data,
        JniHelper::NewByteArray(
            env, classification_result.serialized_entity_data.size()));
    TC3_RETURN_IF_ERROR(JniHelper::SetByteArrayRegion(
        env, serialized_entity_data.get(), 0,
        classification_result.serialized_entity_data.size(),
        reinterpret_cast<const jbyte*>(
            classification_result.serialized_entity_data.data())));
  }

  ScopedLocalRef<jobjectArray> remote_action_templates_result;
  // Only generate RemoteActionTemplate for the top classification result
  // as classifyText does not need RemoteAction from other results anyway.
  if (generate_intents && model_context->intent_generator() != nullptr) {
    std::vector<RemoteActionTemplate> remote_action_templates;
    if (!model_context->intent_generator()->GenerateIntents(
            device_locales, classification_result,
            options->reference_time_ms_utc, context, selection_indices,
            app_context, model_context->model()->entity_data_schema(),
            &remote_action_templates)) {
      return {Status::UNKNOWN};
    }

    TC3_ASSIGN_OR_RETURN(
        remote_action_templates_result,
        model_context->template_handler()->RemoteActionTemplatesToJObjectArray(
            remote_action_templates));
  }

  return JniHelper::NewObject(
      env, result_class, result_class_constructor, row_string.get(),
      static_cast<jfloat>(classification_result.score),
      row_datetime_parse.get(), serialized_knowledge_result.get(),
      contact_name.get(), contact_given_name.get(), contact_family_name.get(),
      contact_nickname.get(), contact_email_address.get(),
      contact_phone_number.get(), contact_account_type.get(),
      contact_account_name.get(), contact_id.get(), app_name.get(),
      app_package_name.get(), extras.get(), serialized_entity_data.get(),
      remote_action_templates_result.get(), classification_result.duration_ms,
      classification_result.numeric_value,
      classification_result.numeric_double_value);
}

StatusOr<ScopedLocalRef<jobjectArray>>
ClassificationResultsWithIntentsToJObjectArray(
    JNIEnv* env, const AnnotatorJniContext* model_context, jobject app_context,
    const jstring device_locales, const ClassificationOptions* options,
    const std::string& context, const CodepointSpan& selection_indices,
    const std::vector<ClassificationResult>& classification_result,
    bool generate_intents) {
  TC3_ASSIGN_OR_RETURN(
      ScopedLocalRef<jclass> result_class,
      JniHelper::FindClass(env, TC3_PACKAGE_PATH TC3_ANNOTATOR_CLASS_NAME_STR
                           "$ClassificationResult"));

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

  TC3_ASSIGN_OR_RETURN(
      const jmethodID result_class_constructor,
      JniHelper::GetMethodID(
          env, result_class.get(), "<init>",
          "(Ljava/lang/String;FL" TC3_PACKAGE_PATH TC3_ANNOTATOR_CLASS_NAME_STR
          "$DatetimeResult;"
          "[B"
          "Ljava/lang/String;"
          "Ljava/lang/String;"
          "Ljava/lang/String;"
          "Ljava/lang/String;"
          "Ljava/lang/String;"
          "Ljava/lang/String;"
          "Ljava/lang/String;"
          "Ljava/lang/String;"
          "Ljava/lang/String;"
          "Ljava/lang/String;"
          "Ljava/lang/String;"
          "[L" TC3_PACKAGE_PATH "" TC3_NAMED_VARIANT_CLASS_NAME_STR ";"
          "[B"
          "[L" TC3_PACKAGE_PATH "" TC3_REMOTE_ACTION_TEMPLATE_CLASS_NAME_STR ";"
          "JJD)V"));
  TC3_ASSIGN_OR_RETURN(const jmethodID datetime_parse_class_constructor,
                       JniHelper::GetMethodID(env, datetime_parse_class.get(),
                                              "<init>", "(JI)V"));

  TC3_ASSIGN_OR_RETURN(
      ScopedLocalRef<jobjectArray> results,
      JniHelper::NewObjectArray(env, classification_result.size(),
                                result_class.get()));

  for (int i = 0; i < classification_result.size(); i++) {
    TC3_ASSIGN_OR_RETURN(
        ScopedLocalRef<jobject> result,
        ClassificationResultWithIntentsToJObject(
            env, model_context, app_context, result_class.get(),
            result_class_constructor, datetime_parse_class.get(),
            datetime_parse_class_constructor, device_locales, options, context,
            selection_indices, classification_result[i],
            generate_intents && (i == 0)));
    TC3_RETURN_IF_ERROR(
        JniHelper::SetObjectArrayElement(env, results.get(), i, result.get()));
  }
  return results;
}

StatusOr<ScopedLocalRef<jobjectArray>> ClassificationResultsToJObjectArray(
    JNIEnv* env, const AnnotatorJniContext* model_context,
    const std::vector<ClassificationResult>& classification_result) {
  return ClassificationResultsWithIntentsToJObjectArray(
      env, model_context,
      /*(unused) app_context=*/nullptr,
      /*(unused) device_locale=*/nullptr,
      /*(unusued) options=*/nullptr,
      /*(unused) selection_text=*/"",
      /*(unused) selection_indices=*/{kInvalidIndex, kInvalidIndex},
      classification_result,
      /*generate_intents=*/false);
}

std::pair<int, int> ConvertIndicesBMPUTF8(
    const std::string& utf8_str, const std::pair<int, int>& orig_indices,
    bool from_utf8) {
  const libtextclassifier3::UnicodeText unicode_str =
      libtextclassifier3::UTF8ToUnicodeText(utf8_str, /*do_copy=*/false);

  int unicode_index = 0;
  int bmp_index = 0;

  const int* source_index;
  const int* target_index;
  if (from_utf8) {
    source_index = &unicode_index;
    target_index = &bmp_index;
  } else {
    source_index = &bmp_index;
    target_index = &unicode_index;
  }

  std::pair<int, int> result = std::make_pair(-1, -1);
  std::function<void()> assign_indices_fn = [&result, &orig_indices,
                                             &source_index, &target_index]() {
    if (orig_indices.first == *source_index) {
      result.first = *target_index;
    }

    if (orig_indices.second == *source_index) {
      result.second = *target_index;
    }
  };

  for (auto it = unicode_str.begin(); it != unicode_str.end();
       ++it, ++unicode_index, ++bmp_index) {
    assign_indices_fn();

    // There is 1 extra character in the input for each UTF8 character > 0xFFFF.
    if (*it > 0xFFFF) {
      ++bmp_index;
    }
  }
  assign_indices_fn();

  return result;
}

}  // namespace

CodepointSpan ConvertIndicesBMPToUTF8(const std::string& utf8_str,
                                      const std::pair<int, int>& bmp_indices) {
  const std::pair<int, int> utf8_indices =
      ConvertIndicesBMPUTF8(utf8_str, bmp_indices, /*from_utf8=*/false);
  return CodepointSpan(utf8_indices.first, utf8_indices.second);
}

std::pair<int, int> ConvertIndicesUTF8ToBMP(const std::string& utf8_str,
                                            const CodepointSpan& utf8_indices) {
  return ConvertIndicesBMPUTF8(
      utf8_str, std::make_pair(utf8_indices.first, utf8_indices.second),
      /*from_utf8=*/true);
}

StatusOr<ScopedLocalRef<jstring>> GetLocalesFromMmap(
    JNIEnv* env, libtextclassifier3::ScopedMmap* mmap) {
  if (!mmap->handle().ok()) {
    return JniHelper::NewStringUTF(env, "");
  }
  const Model* model = libtextclassifier3::ViewModel(
      mmap->handle().start(), mmap->handle().num_bytes());
  if (!model || !model->locales()) {
    return JniHelper::NewStringUTF(env, "");
  }

  return JniHelper::NewStringUTF(env, model->locales()->c_str());
}

jint GetVersionFromMmap(JNIEnv* env, libtextclassifier3::ScopedMmap* mmap) {
  if (!mmap->handle().ok()) {
    return 0;
  }
  const Model* model = libtextclassifier3::ViewModel(
      mmap->handle().start(), mmap->handle().num_bytes());
  if (!model) {
    return 0;
  }
  return model->version();
}

StatusOr<ScopedLocalRef<jstring>> GetNameFromMmap(
    JNIEnv* env, libtextclassifier3::ScopedMmap* mmap) {
  if (!mmap->handle().ok()) {
    return JniHelper::NewStringUTF(env, "");
  }
  const Model* model = libtextclassifier3::ViewModel(
      mmap->handle().start(), mmap->handle().num_bytes());
  if (!model || !model->name()) {
    return JniHelper::NewStringUTF(env, "");
  }
  return JniHelper::NewStringUTF(env, model->name()->c_str());
}

}  // namespace libtextclassifier3

using libtextclassifier3::AnnotatorJniContext;
using libtextclassifier3::ClassificationResultsToJObjectArray;
using libtextclassifier3::ClassificationResultsWithIntentsToJObjectArray;
using libtextclassifier3::ConvertIndicesBMPToUTF8;
using libtextclassifier3::ConvertIndicesUTF8ToBMP;
using libtextclassifier3::FromJavaAnnotationOptions;
using libtextclassifier3::FromJavaClassificationOptions;
using libtextclassifier3::FromJavaInputFragment;
using libtextclassifier3::FromJavaSelectionOptions;
using libtextclassifier3::InputFragment;
using libtextclassifier3::JStringToUtf8String;

TC3_JNI_METHOD(jlong, TC3_ANNOTATOR_CLASS_NAME, nativeNewAnnotator)
(JNIEnv* env, jobject clazz, jint fd) {
  std::shared_ptr<libtextclassifier3::JniCache> jni_cache(
      libtextclassifier3::JniCache::Create(env));
#ifdef TC3_USE_JAVAICU
  return reinterpret_cast<jlong>(AnnotatorJniContext::Create(
      jni_cache,
      Annotator::FromFileDescriptor(
          fd, std::unique_ptr<UniLib>(new UniLib(jni_cache)),
          std::unique_ptr<CalendarLib>(new CalendarLib(jni_cache)))));
#else
  return reinterpret_cast<jlong>(AnnotatorJniContext::Create(
      jni_cache, Annotator::FromFileDescriptor(fd)));
#endif
}

TC3_JNI_METHOD(jlong, TC3_ANNOTATOR_CLASS_NAME, nativeNewAnnotatorFromPath)
(JNIEnv* env, jobject clazz, jstring path) {
  TC3_ASSIGN_OR_RETURN_0(const std::string path_str,
                         JStringToUtf8String(env, path));
  std::shared_ptr<libtextclassifier3::JniCache> jni_cache(
      libtextclassifier3::JniCache::Create(env));
#ifdef TC3_USE_JAVAICU
  return reinterpret_cast<jlong>(AnnotatorJniContext::Create(
      jni_cache,
      Annotator::FromPath(
          path_str, std::unique_ptr<UniLib>(new UniLib(jni_cache)),
          std::unique_ptr<CalendarLib>(new CalendarLib(jni_cache)))));
#else
  return reinterpret_cast<jlong>(
      AnnotatorJniContext::Create(jni_cache, Annotator::FromPath(path_str)));
#endif
}

TC3_JNI_METHOD(jlong, TC3_ANNOTATOR_CLASS_NAME, nativeNewAnnotatorWithOffset)
(JNIEnv* env, jobject clazz, jint fd, jlong offset, jlong size) {
  std::shared_ptr<libtextclassifier3::JniCache> jni_cache(
      libtextclassifier3::JniCache::Create(env));
#ifdef TC3_USE_JAVAICU
  return reinterpret_cast<jlong>(AnnotatorJniContext::Create(
      jni_cache,
      Annotator::FromFileDescriptor(
          fd, offset, size, std::unique_ptr<UniLib>(new UniLib(jni_cache)),
          std::unique_ptr<CalendarLib>(new CalendarLib(jni_cache)))));
#else
  return reinterpret_cast<jlong>(AnnotatorJniContext::Create(
      jni_cache, Annotator::FromFileDescriptor(fd, offset, size)));
#endif
}

TC3_JNI_METHOD(jboolean, TC3_ANNOTATOR_CLASS_NAME,
               nativeInitializeKnowledgeEngine)
(JNIEnv* env, jobject thiz, jlong ptr, jbyteArray serialized_config) {
  if (!ptr) {
    return false;
  }

  Annotator* model = reinterpret_cast<AnnotatorJniContext*>(ptr)->model();

  TC3_ASSIGN_OR_RETURN_FALSE(
      const std::string serialized_config_string,
      libtextclassifier3::JByteArrayToString(env, serialized_config));

  return model->InitializeKnowledgeEngine(serialized_config_string);
}

TC3_JNI_METHOD(jboolean, TC3_ANNOTATOR_CLASS_NAME,
               nativeInitializeContactEngine)
(JNIEnv* env, jobject thiz, jlong ptr, jbyteArray serialized_config) {
  if (!ptr) {
    return false;
  }

  Annotator* model = reinterpret_cast<AnnotatorJniContext*>(ptr)->model();

  TC3_ASSIGN_OR_RETURN_FALSE(
      const std::string serialized_config_string,
      libtextclassifier3::JByteArrayToString(env, serialized_config));

  return model->InitializeContactEngine(serialized_config_string);
}

TC3_JNI_METHOD(jboolean, TC3_ANNOTATOR_CLASS_NAME,
               nativeInitializeInstalledAppEngine)
(JNIEnv* env, jobject thiz, jlong ptr, jbyteArray serialized_config) {
  if (!ptr) {
    return false;
  }

  Annotator* model = reinterpret_cast<AnnotatorJniContext*>(ptr)->model();

  TC3_ASSIGN_OR_RETURN_FALSE(
      const std::string serialized_config_string,
      libtextclassifier3::JByteArrayToString(env, serialized_config));

  return model->InitializeInstalledAppEngine(serialized_config_string);
}

TC3_JNI_METHOD(jboolean, TC3_ANNOTATOR_CLASS_NAME,
               nativeInitializePersonNameEngine)
(JNIEnv* env, jobject thiz, jlong ptr, jint fd, jlong offset, jlong size) {
  if (!ptr) {
    return false;
  }

  Annotator* model = reinterpret_cast<AnnotatorJniContext*>(ptr)->model();

  return model->InitializePersonNameEngineFromFileDescriptor(fd, offset, size);
}

TC3_JNI_METHOD(void, TC3_ANNOTATOR_CLASS_NAME, nativeSetLangId)
(JNIEnv* env, jobject thiz, jlong annotator_ptr, jlong lang_id_ptr) {
  if (!annotator_ptr) {
    return;
  }
  Annotator* model =
      reinterpret_cast<AnnotatorJniContext*>(annotator_ptr)->model();
  libtextclassifier3::mobile::lang_id::LangId* lang_id_model =
      reinterpret_cast<libtextclassifier3::mobile::lang_id::LangId*>(lang_id_ptr);
  model->SetLangId(lang_id_model);
}

TC3_JNI_METHOD(jlong, TC3_ANNOTATOR_CLASS_NAME, nativeGetNativeModelPtr)
(JNIEnv* env, jobject thiz, jlong ptr) {
  if (!ptr) {
    return 0L;
  }
  return reinterpret_cast<jlong>(
      reinterpret_cast<AnnotatorJniContext*>(ptr)->model());
}

TC3_JNI_METHOD(jintArray, TC3_ANNOTATOR_CLASS_NAME, nativeSuggestSelection)
(JNIEnv* env, jobject thiz, jlong ptr, jstring context, jint selection_begin,
 jint selection_end, jobject options) {
  if (!ptr) {
    return nullptr;
  }
  const Annotator* model = reinterpret_cast<AnnotatorJniContext*>(ptr)->model();
  TC3_ASSIGN_OR_RETURN_NULL(const std::string context_utf8,
                            JStringToUtf8String(env, context));
  const CodepointSpan input_indices =
      ConvertIndicesBMPToUTF8(context_utf8, {selection_begin, selection_end});
  TC3_ASSIGN_OR_RETURN_NULL(
      libtextclassifier3::SelectionOptions selection_options,
      FromJavaSelectionOptions(env, options));
  CodepointSpan selection =
      model->SuggestSelection(context_utf8, input_indices, selection_options);
  const std::pair<int, int> selection_bmp =
      ConvertIndicesUTF8ToBMP(context_utf8, selection);

  TC3_ASSIGN_OR_RETURN_NULL(ScopedLocalRef<jintArray> result,
                            JniHelper::NewIntArray(env, 2));
  TC3_RETURN_NULL_IF_ERROR(JniHelper::SetIntArrayRegion(
      env, result.get(), 0, 1, &(selection_bmp.first)));
  TC3_RETURN_NULL_IF_ERROR(JniHelper::SetIntArrayRegion(
      env, result.get(), 1, 1, &(selection_bmp.second)));
  return result.release();
}

TC3_JNI_METHOD(jobjectArray, TC3_ANNOTATOR_CLASS_NAME, nativeClassifyText)
(JNIEnv* env, jobject thiz, jlong ptr, jstring context, jint selection_begin,
 jint selection_end, jobject options, jobject app_context,
 jstring device_locales) {
  if (!ptr) {
    return nullptr;
  }
  const AnnotatorJniContext* model_context =
      reinterpret_cast<AnnotatorJniContext*>(ptr);

  TC3_ASSIGN_OR_RETURN_NULL(const std::string context_utf8,
                            JStringToUtf8String(env, context));
  const CodepointSpan input_indices =
      ConvertIndicesBMPToUTF8(context_utf8, {selection_begin, selection_end});
  TC3_ASSIGN_OR_RETURN_NULL(
      const libtextclassifier3::ClassificationOptions classification_options,
      FromJavaClassificationOptions(env, options));
  const std::vector<ClassificationResult> classification_result =
      model_context->model()->ClassifyText(context_utf8, input_indices,
                                           classification_options);

  ScopedLocalRef<jobjectArray> result;
  if (app_context != nullptr) {
    TC3_ASSIGN_OR_RETURN_NULL(
        result, ClassificationResultsWithIntentsToJObjectArray(
                    env, model_context, app_context, device_locales,
                    &classification_options, context_utf8, input_indices,
                    classification_result,
                    /*generate_intents=*/true));

  } else {
    TC3_ASSIGN_OR_RETURN_NULL(
        result, ClassificationResultsToJObjectArray(env, model_context,
                                                    classification_result));
  }

  return result.release();
}

TC3_JNI_METHOD(jobjectArray, TC3_ANNOTATOR_CLASS_NAME, nativeAnnotate)
(JNIEnv* env, jobject thiz, jlong ptr, jstring context, jobject options) {
  if (!ptr) {
    return nullptr;
  }
  const AnnotatorJniContext* model_context =
      reinterpret_cast<AnnotatorJniContext*>(ptr);
  TC3_ASSIGN_OR_RETURN_NULL(const std::string context_utf8,
                            JStringToUtf8String(env, context));
  TC3_ASSIGN_OR_RETURN_NULL(
      libtextclassifier3::AnnotationOptions annotation_options,
      FromJavaAnnotationOptions(env, options));
  const std::vector<AnnotatedSpan> annotations =
      model_context->model()->Annotate(context_utf8, annotation_options);

  TC3_ASSIGN_OR_RETURN_NULL(
      ScopedLocalRef<jclass> result_class,
      JniHelper::FindClass(
          env, TC3_PACKAGE_PATH TC3_ANNOTATOR_CLASS_NAME_STR "$AnnotatedSpan"));

  TC3_ASSIGN_OR_RETURN_NULL(
      jmethodID result_class_constructor,
      JniHelper::GetMethodID(
          env, result_class.get(), "<init>",
          "(II[L" TC3_PACKAGE_PATH TC3_ANNOTATOR_CLASS_NAME_STR
          "$ClassificationResult;)V"));

  TC3_ASSIGN_OR_RETURN_NULL(
      ScopedLocalRef<jobjectArray> results,
      JniHelper::NewObjectArray(env, annotations.size(), result_class.get()));

  for (int i = 0; i < annotations.size(); ++i) {
    const std::pair<int, int> span_bmp =
        ConvertIndicesUTF8ToBMP(context_utf8, annotations[i].span);

    TC3_ASSIGN_OR_RETURN_NULL(
        ScopedLocalRef<jobjectArray> classification_results,
        ClassificationResultsToJObjectArray(env, model_context,
                                            annotations[i].classification));

    TC3_ASSIGN_OR_RETURN_NULL(
        ScopedLocalRef<jobject> result,
        JniHelper::NewObject(env, result_class.get(), result_class_constructor,
                             static_cast<jint>(span_bmp.first),
                             static_cast<jint>(span_bmp.second),
                             classification_results.get()));
    if (!JniHelper::SetObjectArrayElement(env, results.get(), i, result.get())
             .ok()) {
      return nullptr;
    }
  }
  return results.release();
}

TC3_JNI_METHOD(jobject, TC3_ANNOTATOR_CLASS_NAME, nativeAnnotateStructuredInput)
(JNIEnv* env, jobject thiz, jlong ptr, jobjectArray jinput_fragments,
 jobject options) {
  if (!ptr) {
    return nullptr;
  }
  const AnnotatorJniContext* model_context =
      reinterpret_cast<AnnotatorJniContext*>(ptr);

  std::vector<InputFragment> string_fragments;
  TC3_ASSIGN_OR_RETURN_NULL(jsize input_size,
                            JniHelper::GetArrayLength(env, jinput_fragments));
  for (int i = 0; i < input_size; ++i) {
    TC3_ASSIGN_OR_RETURN_NULL(
        ScopedLocalRef<jobject> jfragment,
        JniHelper::GetObjectArrayElement<jobject>(env, jinput_fragments, i));
    TC3_ASSIGN_OR_RETURN_NULL(InputFragment fragment,
                              FromJavaInputFragment(env, jfragment.get()));
    string_fragments.push_back(std::move(fragment));
  }

  TC3_ASSIGN_OR_RETURN_NULL(
      libtextclassifier3::AnnotationOptions annotation_options,
      FromJavaAnnotationOptions(env, options));
  const StatusOr<Annotations> annotations_or =
      model_context->model()->AnnotateStructuredInput(string_fragments,
                                                      annotation_options);
  if (!annotations_or.ok()) {
    TC3_LOG(ERROR) << "Annotation of structured input failed with error: "
                   << annotations_or.status().error_message();
    return nullptr;
  }

  Annotations annotations = std::move(annotations_or.ValueOrDie());
  TC3_ASSIGN_OR_RETURN_NULL(
      ScopedLocalRef<jclass> annotations_class,
      JniHelper::FindClass(
          env, TC3_PACKAGE_PATH TC3_ANNOTATOR_CLASS_NAME_STR "$Annotations"));

  TC3_ASSIGN_OR_RETURN_NULL(
      jmethodID annotations_class_constructor,
      JniHelper::GetMethodID(
          env, annotations_class.get(), "<init>",
          "([[L" TC3_PACKAGE_PATH TC3_ANNOTATOR_CLASS_NAME_STR
          "$AnnotatedSpan;[L" TC3_PACKAGE_PATH TC3_ANNOTATOR_CLASS_NAME_STR
          "$ClassificationResult;)V"));

  TC3_ASSIGN_OR_RETURN_NULL(
      ScopedLocalRef<jclass> span_class,
      JniHelper::FindClass(
          env, TC3_PACKAGE_PATH TC3_ANNOTATOR_CLASS_NAME_STR "$AnnotatedSpan"));

  TC3_ASSIGN_OR_RETURN_NULL(
      jmethodID span_class_constructor,
      JniHelper::GetMethodID(
          env, span_class.get(), "<init>",
          "(II[L" TC3_PACKAGE_PATH TC3_ANNOTATOR_CLASS_NAME_STR
          "$ClassificationResult;)V"));

  TC3_ASSIGN_OR_RETURN_NULL(
      ScopedLocalRef<jclass> span_class_array,
      JniHelper::FindClass(env,
                           "[L" TC3_PACKAGE_PATH TC3_ANNOTATOR_CLASS_NAME_STR
                           "$AnnotatedSpan;"));

  TC3_ASSIGN_OR_RETURN_NULL(
      ScopedLocalRef<jobjectArray> annotated_spans,
      JniHelper::NewObjectArray(env, input_size, span_class_array.get()));

  for (int fragment_index = 0;
       fragment_index < annotations.annotated_spans.size(); ++fragment_index) {
    TC3_ASSIGN_OR_RETURN_NULL(
        ScopedLocalRef<jobjectArray> jfragmentAnnotations,
        JniHelper::NewObjectArray(
            env, annotations.annotated_spans[fragment_index].size(),
            span_class.get()));
    for (int annotation_index = 0;
         annotation_index < annotations.annotated_spans[fragment_index].size();
         ++annotation_index) {
      const std::pair<int, int> span_bmp = ConvertIndicesUTF8ToBMP(
          string_fragments[fragment_index].text,
          annotations.annotated_spans[fragment_index][annotation_index].span);
      TC3_ASSIGN_OR_RETURN_NULL(
          ScopedLocalRef<jobjectArray> classification_results,
          ClassificationResultsToJObjectArray(
              env, model_context,
              annotations.annotated_spans[fragment_index][annotation_index]
                  .classification));
      TC3_ASSIGN_OR_RETURN_NULL(
          ScopedLocalRef<jobject> single_annotation,
          JniHelper::NewObject(env, span_class.get(), span_class_constructor,
                               static_cast<jint>(span_bmp.first),
                               static_cast<jint>(span_bmp.second),
                               classification_results.get()));

      if (!JniHelper::SetObjectArrayElement(env, jfragmentAnnotations.get(),
                                            annotation_index,
                                            single_annotation.get())
               .ok()) {
        return nullptr;
      }
    }

    if (!JniHelper::SetObjectArrayElement(env, annotated_spans.get(),
                                          fragment_index,
                                          jfragmentAnnotations.get())
             .ok()) {
      return nullptr;
    }
  }

  TC3_ASSIGN_OR_RETURN_NULL(
      ScopedLocalRef<jobjectArray> topicality_results,
      ClassificationResultsToJObjectArray(env, model_context,
                                          annotations.topicality_results));

  TC3_ASSIGN_OR_RETURN_NULL(
      ScopedLocalRef<jobject> annotations_result,
      JniHelper::NewObject(env, annotations_class.get(),
                           annotations_class_constructor, annotated_spans.get(),
                           topicality_results.get()));

  return annotations_result.release();
}

TC3_JNI_METHOD(jbyteArray, TC3_ANNOTATOR_CLASS_NAME,
               nativeLookUpKnowledgeEntity)
(JNIEnv* env, jobject thiz, jlong ptr, jstring id) {
  if (!ptr) {
    return nullptr;
  }
  const Annotator* model = reinterpret_cast<AnnotatorJniContext*>(ptr)->model();
  TC3_ASSIGN_OR_RETURN_NULL(const std::string id_utf8,
                            JStringToUtf8String(env, id));
  auto serialized_knowledge_result_so = model->LookUpKnowledgeEntity(id_utf8);
  if (!serialized_knowledge_result_so.ok()) {
    return nullptr;
  }
  std::string serialized_knowledge_result =
      serialized_knowledge_result_so.ValueOrDie();

  TC3_ASSIGN_OR_RETURN_NULL(
      ScopedLocalRef<jbyteArray> result,
      JniHelper::NewByteArray(env, serialized_knowledge_result.size()));
  TC3_RETURN_NULL_IF_ERROR(JniHelper::SetByteArrayRegion(
      env, result.get(), 0, serialized_knowledge_result.size(),
      reinterpret_cast<const jbyte*>(serialized_knowledge_result.data())));
  return result.release();
}

TC3_JNI_METHOD(void, TC3_ANNOTATOR_CLASS_NAME, nativeCloseAnnotator)
(JNIEnv* env, jobject thiz, jlong ptr) {
  const AnnotatorJniContext* context =
      reinterpret_cast<AnnotatorJniContext*>(ptr);
  delete context;
}

TC3_JNI_METHOD(jstring, TC3_ANNOTATOR_CLASS_NAME, nativeGetLanguage)
(JNIEnv* env, jobject clazz, jint fd) {
  TC3_LOG(WARNING) << "Using deprecated getLanguage().";
  return TC3_JNI_METHOD_NAME(TC3_ANNOTATOR_CLASS_NAME, nativeGetLocales)(
      env, clazz, fd);
}

TC3_JNI_METHOD(jstring, TC3_ANNOTATOR_CLASS_NAME, nativeGetLocales)
(JNIEnv* env, jobject clazz, jint fd) {
  const std::unique_ptr<libtextclassifier3::ScopedMmap> mmap(
      new libtextclassifier3::ScopedMmap(fd));
  TC3_ASSIGN_OR_RETURN_NULL(ScopedLocalRef<jstring> value,
                            GetLocalesFromMmap(env, mmap.get()));
  return value.release();
}

TC3_JNI_METHOD(jstring, TC3_ANNOTATOR_CLASS_NAME, nativeGetLocalesWithOffset)
(JNIEnv* env, jobject clazz, jint fd, jlong offset, jlong size) {
  const std::unique_ptr<libtextclassifier3::ScopedMmap> mmap(
      new libtextclassifier3::ScopedMmap(fd, offset, size));
  TC3_ASSIGN_OR_RETURN_NULL(ScopedLocalRef<jstring> value,
                            GetLocalesFromMmap(env, mmap.get()));
  return value.release();
}

TC3_JNI_METHOD(jint, TC3_ANNOTATOR_CLASS_NAME, nativeGetVersion)
(JNIEnv* env, jobject clazz, jint fd) {
  const std::unique_ptr<libtextclassifier3::ScopedMmap> mmap(
      new libtextclassifier3::ScopedMmap(fd));
  return GetVersionFromMmap(env, mmap.get());
}

TC3_JNI_METHOD(jint, TC3_ANNOTATOR_CLASS_NAME, nativeGetVersionWithOffset)
(JNIEnv* env, jobject clazz, jint fd, jlong offset, jlong size) {
  const std::unique_ptr<libtextclassifier3::ScopedMmap> mmap(
      new libtextclassifier3::ScopedMmap(fd, offset, size));
  return GetVersionFromMmap(env, mmap.get());
}

TC3_JNI_METHOD(jstring, TC3_ANNOTATOR_CLASS_NAME, nativeGetName)
(JNIEnv* env, jobject clazz, jint fd) {
  const std::unique_ptr<libtextclassifier3::ScopedMmap> mmap(
      new libtextclassifier3::ScopedMmap(fd));
  TC3_ASSIGN_OR_RETURN_NULL(ScopedLocalRef<jstring> value,
                            GetNameFromMmap(env, mmap.get()));
  return value.release();
}

TC3_JNI_METHOD(jstring, TC3_ANNOTATOR_CLASS_NAME, nativeGetNameWithOffset)
(JNIEnv* env, jobject clazz, jint fd, jlong offset, jlong size) {
  const std::unique_ptr<libtextclassifier3::ScopedMmap> mmap(
      new libtextclassifier3::ScopedMmap(fd, offset, size));
  TC3_ASSIGN_OR_RETURN_NULL(ScopedLocalRef<jstring> value,
                            GetNameFromMmap(env, mmap.get()));
  return value.release();
}
