/*
 * Copyright (C) 2019 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 "suspend_event_helper.h"

#include <inttypes.h>

#include <cstdio>
#include <memory>
#include <string>
#include <vector>

#include "android-base/logging.h"
#include "android-base/stringprintf.h"

#include "jni.h"
#include "jvmti.h"
#include "scoped_local_ref.h"
#include "scoped_utf_chars.h"

// Test infrastructure
#include "jni_binder.h"
#include "jni_helper.h"
#include "jvmti_helper.h"
#include "test_env.h"
#include "ti_macros.h"

namespace art {
namespace common_suspend_event {

struct TestData {
  jlocation target_loc;
  jmethodID target_method;
  jclass target_klass;
  jfieldID target_field;
  jrawMonitorID notify_monitor;
  jint frame_pop_offset;
  jmethodID frame_pop_setup_method;
  std::vector<std::string> interesting_classes;
  bool hit_location;

  TestData(jvmtiEnv* jvmti,
           JNIEnv* env,
           jlocation loc,
           jobject meth,
           jclass klass,
           jobject field,
           jobject setup_meth,
           jint pop_offset,
           const std::vector<std::string>&& interesting)
      : target_loc(loc), target_method(meth != nullptr ? env->FromReflectedMethod(meth) : nullptr),
        target_klass(reinterpret_cast<jclass>(env->NewGlobalRef(klass))),
        target_field(field != nullptr ? env->FromReflectedField(field) : nullptr),
        frame_pop_offset(pop_offset),
        frame_pop_setup_method(setup_meth != nullptr ? env->FromReflectedMethod(setup_meth)
                                                     : nullptr),
        interesting_classes(interesting), hit_location(false) {
    JvmtiErrorToException(
        env, jvmti, jvmti->CreateRawMonitor("SuspendStopMonitor", &notify_monitor));
  }

  void PerformSuspend(jvmtiEnv* jvmti, JNIEnv* env) {
    // Wake up the waiting thread.
    JvmtiErrorToException(env, jvmti, jvmti->RawMonitorEnter(notify_monitor));
    hit_location = true;
    JvmtiErrorToException(env, jvmti, jvmti->RawMonitorNotifyAll(notify_monitor));
    JvmtiErrorToException(env, jvmti, jvmti->RawMonitorExit(notify_monitor));
    // Suspend ourself
    jvmti->SuspendThread(nullptr);
  }
};

void PerformSuspension(jvmtiEnv* jvmti, JNIEnv* env) {
  TestData* data;
  if (JvmtiErrorToException(
          env,
          jvmti_env,
          jvmti->GetThreadLocalStorage(/* thread */ nullptr, reinterpret_cast<void**>(&data)))) {
    return;
  }
  CHECK(data != nullptr);
  data->PerformSuspend(jvmti, env);
}

void JNICALL
cbSingleStep(jvmtiEnv* jvmti, JNIEnv* env, jthread thr, jmethodID meth, jlocation loc) {
  TestData* data;
  if (JvmtiErrorToException(
          env, jvmti, jvmti->GetThreadLocalStorage(thr, reinterpret_cast<void**>(&data)))) {
    return;
  }
  CHECK(data != nullptr);
  if (meth != data->target_method || loc != data->target_loc) {
    return;
  }
  data->PerformSuspend(jvmti, env);
}

void JNICALL cbExceptionCatch(jvmtiEnv* jvmti,
                              JNIEnv* env,
                              jthread thr,
                              jmethodID method,
                              [[maybe_unused]] jlocation location,
                              [[maybe_unused]] jobject exception) {
  TestData* data;
  if (JvmtiErrorToException(
          env, jvmti, jvmti->GetThreadLocalStorage(thr, reinterpret_cast<void**>(&data)))) {
    return;
  }
  CHECK(data != nullptr);
  if (method != data->target_method) {
    return;
  }
  data->PerformSuspend(jvmti, env);
}

void JNICALL cbException(jvmtiEnv* jvmti,
                         JNIEnv* env,
                         jthread thr,
                         jmethodID method,
                         [[maybe_unused]] jlocation location,
                         [[maybe_unused]] jobject exception,
                         [[maybe_unused]] jmethodID catch_method,
                         [[maybe_unused]] jlocation catch_location) {
  TestData* data;
  if (JvmtiErrorToException(
          env, jvmti, jvmti->GetThreadLocalStorage(thr, reinterpret_cast<void**>(&data)))) {
    return;
  }
  CHECK(data != nullptr);
  if (method != data->target_method) {
    return;
  }
  data->PerformSuspend(jvmti, env);
}

void JNICALL cbMethodEntry(jvmtiEnv* jvmti, JNIEnv* env, jthread thr, jmethodID method) {
  TestData* data;
  if (JvmtiErrorToException(
          env, jvmti, jvmti->GetThreadLocalStorage(thr, reinterpret_cast<void**>(&data)))) {
    return;
  }
  CHECK(data != nullptr);
  if (method != data->target_method) {
    return;
  }
  data->PerformSuspend(jvmti, env);
}

void JNICALL cbMethodExit(jvmtiEnv* jvmti,
                          JNIEnv* env,
                          jthread thr,
                          jmethodID method,
                          [[maybe_unused]] jboolean was_popped_by_exception,
                          [[maybe_unused]] jvalue return_value) {
  TestData* data;
  if (JvmtiErrorToException(
          env, jvmti, jvmti->GetThreadLocalStorage(thr, reinterpret_cast<void**>(&data)))) {
    return;
  }
  CHECK(data != nullptr);
  if (method != data->target_method) {
    return;
  }
  data->PerformSuspend(jvmti, env);
}

void JNICALL cbFieldModification(jvmtiEnv* jvmti,
                                 JNIEnv* env,
                                 jthread thr,
                                 [[maybe_unused]] jmethodID method,
                                 [[maybe_unused]] jlocation location,
                                 [[maybe_unused]] jclass field_klass,
                                 [[maybe_unused]] jobject object,
                                 jfieldID field,
                                 [[maybe_unused]] char signature_type,
                                 [[maybe_unused]] jvalue new_value) {
  TestData* data;
  if (JvmtiErrorToException(
          env, jvmti, jvmti->GetThreadLocalStorage(thr, reinterpret_cast<void**>(&data)))) {
    return;
  }
  CHECK(data != nullptr);
  if (field != data->target_field) {
    // TODO What to do here.
    LOG(FATAL) << "Strange, shouldn't get here!";
  }
  data->PerformSuspend(jvmti, env);
}

void JNICALL cbFieldAccess(jvmtiEnv* jvmti,
                           JNIEnv* env,
                           jthread thr,
                           [[maybe_unused]] jmethodID method,
                           [[maybe_unused]] jlocation location,
                           jclass field_klass,
                           [[maybe_unused]] jobject object,
                           jfieldID field) {
  TestData* data;
  if (JvmtiErrorToException(
          env, jvmti, jvmti->GetThreadLocalStorage(thr, reinterpret_cast<void**>(&data)))) {
    return;
  }
  CHECK(data != nullptr);
  if (field != data->target_field || !env->IsSameObject(field_klass, data->target_klass)) {
    // TODO What to do here.
    LOG(FATAL) << "Strange, shouldn't get here!";
  }
  data->PerformSuspend(jvmti, env);
}

void JNICALL
cbBreakpointHit(jvmtiEnv* jvmti, JNIEnv* env, jthread thr, jmethodID method, jlocation loc) {
  TestData* data;
  if (JvmtiErrorToException(
          env, jvmti, jvmti->GetThreadLocalStorage(thr, reinterpret_cast<void**>(&data)))) {
    return;
  }
  CHECK(data != nullptr);
  if (data->frame_pop_setup_method == method) {
    CHECK(loc == 0) << "We should have stopped at location 0";
    if (JvmtiErrorToException(env, jvmti, jvmti->NotifyFramePop(thr, data->frame_pop_offset))) {
      return;
    }
    return;
  }
  if (method != data->target_method || loc != data->target_loc) {
    // TODO What to do here.
    LOG(FATAL) << "Strange, shouldn't get here!";
  }
  data->PerformSuspend(jvmti, env);
}

void JNICALL cbFramePop(jvmtiEnv* jvmti,
                        JNIEnv* env,
                        jthread thr,
                        [[maybe_unused]] jmethodID method,
                        [[maybe_unused]] jboolean was_popped_by_exception) {
  TestData* data;
  if (JvmtiErrorToException(
          env, jvmti, jvmti->GetThreadLocalStorage(thr, reinterpret_cast<void**>(&data)))) {
    return;
  }
  CHECK(data != nullptr);
  data->PerformSuspend(jvmti, env);
}

void JNICALL cbClassLoadOrPrepare(jvmtiEnv* jvmti, JNIEnv* env, jthread thr, jclass klass) {
  TestData* data;
  if (JvmtiErrorToException(
          env, jvmti, jvmti->GetThreadLocalStorage(thr, reinterpret_cast<void**>(&data)))) {
    return;
  }
  CHECK(data != nullptr);
  char* name;
  if (JvmtiErrorToException(env, jvmti, jvmti->GetClassSignature(klass, &name, nullptr))) {
    return;
  }
  std::string name_str(name);
  if (JvmtiErrorToException(
          env, jvmti, jvmti->Deallocate(reinterpret_cast<unsigned char*>(name)))) {
    return;
  }
  if (std::find(data->interesting_classes.cbegin(), data->interesting_classes.cend(), name_str) !=
      data->interesting_classes.cend()) {
    data->PerformSuspend(jvmti, env);
  }
}

extern "C" JNIEXPORT void JNICALL Java_art_SuspendEvents_setupTest(JNIEnv* env,
                                                                   [[maybe_unused]] jclass klass) {
  jvmtiCapabilities caps;
  memset(&caps, 0, sizeof(caps));
  // Most of these will already be there but might as well be complete.
  caps.can_pop_frame = 1;
  caps.can_force_early_return = 1;
  caps.can_generate_single_step_events = 1;
  caps.can_generate_breakpoint_events = 1;
  caps.can_suspend = 1;
  caps.can_generate_method_entry_events = 1;
  caps.can_generate_method_exit_events = 1;
  caps.can_generate_monitor_events = 1;
  caps.can_generate_exception_events = 1;
  caps.can_generate_frame_pop_events = 1;
  caps.can_generate_field_access_events = 1;
  caps.can_generate_field_modification_events = 1;
  caps.can_redefine_classes = 1;
  if (JvmtiErrorToException(env, jvmti_env, jvmti_env->AddCapabilities(&caps))) {
    return;
  }
  jvmtiEventCallbacks cb;
  memset(&cb, 0, sizeof(cb));
  // TODO Add the rest of these.
  cb.Breakpoint = cbBreakpointHit;
  cb.SingleStep = cbSingleStep;
  cb.FieldAccess = cbFieldAccess;
  cb.FieldModification = cbFieldModification;
  cb.MethodEntry = cbMethodEntry;
  cb.MethodExit = cbMethodExit;
  cb.Exception = cbException;
  cb.ExceptionCatch = cbExceptionCatch;
  cb.FramePop = cbFramePop;
  cb.ClassLoad = cbClassLoadOrPrepare;
  cb.ClassPrepare = cbClassLoadOrPrepare;
  JvmtiErrorToException(env, jvmti_env, jvmti_env->SetEventCallbacks(&cb, sizeof(cb)));
}

static bool DeleteTestData(JNIEnv* env, jthread thr, TestData* data) {
  env->DeleteGlobalRef(data->target_klass);
  if (JvmtiErrorToException(env, jvmti_env, jvmti_env->SetThreadLocalStorage(thr, nullptr))) {
    return false;
  }
  return JvmtiErrorToException(
      env, jvmti_env, jvmti_env->Deallocate(reinterpret_cast<uint8_t*>(data)));
}

static TestData* SetupTestData(JNIEnv* env,
                               jobject meth,
                               jlocation loc,
                               jclass target_klass,
                               jobject field,
                               jobject setup_meth,
                               jint pop_offset,
                               const std::vector<std::string>&& interesting_names) {
  void* data_ptr;
  TestData* data;
  if (JvmtiErrorToException(
          env,
          jvmti_env,
          jvmti_env->Allocate(sizeof(TestData), reinterpret_cast<uint8_t**>(&data_ptr)))) {
    return nullptr;
  }
  data = new (data_ptr) TestData(jvmti_env,
                                 env,
                                 loc,
                                 meth,
                                 target_klass,
                                 field,
                                 setup_meth,
                                 pop_offset,
                                 std::move(interesting_names));
  if (env->ExceptionCheck()) {
    env->DeleteGlobalRef(data->target_klass);
    jvmti_env->Deallocate(reinterpret_cast<uint8_t*>(data));
    return nullptr;
  }
  return data;
}

static TestData* SetupTestData(JNIEnv* env,
                               jobject meth,
                               jlocation loc,
                               jclass target_klass,
                               jobject field,
                               jobject setup_meth,
                               jint pop_offset) {
  std::vector<std::string> empty;
  return SetupTestData(
      env, meth, loc, target_klass, field, setup_meth, pop_offset, std::move(empty));
}

extern "C" JNIEXPORT void JNICALL
Java_art_SuspendEvents_setupSuspendClassEvent(JNIEnv* env,
                                              [[maybe_unused]] jclass klass,
                                              jint event_num,
                                              jobjectArray interesting_names,
                                              jthread thr) {
  CHECK(event_num == JVMTI_EVENT_CLASS_LOAD || event_num == JVMTI_EVENT_CLASS_PREPARE);
  std::vector<std::string> names;
  jint cnt = env->GetArrayLength(interesting_names);
  for (jint i = 0; i < cnt; i++) {
    env->PushLocalFrame(1);
    jstring name_obj = reinterpret_cast<jstring>(env->GetObjectArrayElement(interesting_names, i));
    const char* name_chr = env->GetStringUTFChars(name_obj, nullptr);
    names.push_back(std::string(name_chr));
    env->ReleaseStringUTFChars(name_obj, name_chr);
    env->PopLocalFrame(nullptr);
  }
  TestData* data;
  if (JvmtiErrorToException(
          env, jvmti_env, jvmti_env->GetThreadLocalStorage(thr, reinterpret_cast<void**>(&data)))) {
    return;
  }
  CHECK(data == nullptr) << "Data was not cleared!";
  data = SetupTestData(env, nullptr, 0, nullptr, nullptr, nullptr, 0, std::move(names));
  if (data == nullptr) {
    return;
  }
  if (JvmtiErrorToException(env, jvmti_env, jvmti_env->SetThreadLocalStorage(thr, data))) {
    return;
  }
  JvmtiErrorToException(
      env,
      jvmti_env,
      jvmti_env->SetEventNotificationMode(JVMTI_ENABLE, static_cast<jvmtiEvent>(event_num), thr));
}

extern "C" JNIEXPORT void JNICALL Java_art_SuspendEvents_clearSuspendClassEvent(
    JNIEnv* env, [[maybe_unused]] jclass klass, jthread thr) {
  TestData* data;
  if (JvmtiErrorToException(
          env, jvmti_env, jvmti_env->GetThreadLocalStorage(thr, reinterpret_cast<void**>(&data)))) {
    return;
  }
  CHECK(data != nullptr);
  if (JvmtiErrorToException(
          env,
          jvmti_env,
          jvmti_env->SetEventNotificationMode(JVMTI_DISABLE, JVMTI_EVENT_CLASS_LOAD, thr))) {
    return;
  }
  if (JvmtiErrorToException(
          env,
          jvmti_env,
          jvmti_env->SetEventNotificationMode(JVMTI_DISABLE, JVMTI_EVENT_CLASS_PREPARE, thr))) {
    return;
  }
  DeleteTestData(env, thr, data);
}

extern "C" JNIEXPORT void JNICALL Java_art_SuspendEvents_setupSuspendSingleStepAt(
    JNIEnv* env, [[maybe_unused]] jclass klass, jobject meth, jlocation loc, jthread thr) {
  TestData* data;
  if (JvmtiErrorToException(
          env, jvmti_env, jvmti_env->GetThreadLocalStorage(thr, reinterpret_cast<void**>(&data)))) {
    return;
  }
  CHECK(data == nullptr) << "Data was not cleared!";
  data = SetupTestData(env, meth, loc, nullptr, nullptr, nullptr, 0);
  if (data == nullptr) {
    return;
  }
  if (JvmtiErrorToException(env, jvmti_env, jvmti_env->SetThreadLocalStorage(thr, data))) {
    return;
  }
  JvmtiErrorToException(
      env,
      jvmti_env,
      jvmti_env->SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_SINGLE_STEP, thr));
}

extern "C" JNIEXPORT void JNICALL Java_art_SuspendEvents_clearSuspendSingleStepFor(
    JNIEnv* env, [[maybe_unused]] jclass klass, jthread thr) {
  TestData* data;
  if (JvmtiErrorToException(
          env, jvmti_env, jvmti_env->GetThreadLocalStorage(thr, reinterpret_cast<void**>(&data)))) {
    return;
  }
  CHECK(data != nullptr);
  if (JvmtiErrorToException(
          env,
          jvmti_env,
          jvmti_env->SetEventNotificationMode(JVMTI_DISABLE, JVMTI_EVENT_SINGLE_STEP, thr))) {
    return;
  }
  DeleteTestData(env, thr, data);
}

extern "C" JNIEXPORT void JNICALL Java_art_SuspendEvents_setupSuspendPopFrameEvent(
    JNIEnv* env, [[maybe_unused]] jclass klass, jint offset, jobject breakpoint_func, jthread thr) {
  TestData* data;
  if (JvmtiErrorToException(
          env, jvmti_env, jvmti_env->GetThreadLocalStorage(thr, reinterpret_cast<void**>(&data)))) {
    return;
  }
  CHECK(data == nullptr) << "Data was not cleared!";
  data = SetupTestData(env, nullptr, 0, nullptr, nullptr, breakpoint_func, offset);
  CHECK(data != nullptr);
  if (JvmtiErrorToException(env, jvmti_env, jvmti_env->SetThreadLocalStorage(thr, data))) {
    return;
  }
  if (JvmtiErrorToException(
          env,
          jvmti_env,
          jvmti_env->SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_FRAME_POP, thr))) {
    return;
  }
  if (JvmtiErrorToException(
          env,
          jvmti_env,
          jvmti_env->SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_BREAKPOINT, thr))) {
    return;
  }
  if (JvmtiErrorToException(
          env, jvmti_env, jvmti_env->SetBreakpoint(data->frame_pop_setup_method, 0))) {
    return;
  }
}

extern "C" JNIEXPORT void JNICALL Java_art_SuspendEvents_clearSuspendPopFrameEvent(
    JNIEnv* env, [[maybe_unused]] jclass klass , jthread thr) {
  TestData* data;
  if (JvmtiErrorToException(
          env, jvmti_env, jvmti_env->GetThreadLocalStorage(thr, reinterpret_cast<void**>(&data)))) {
    return;
  }
  CHECK(data != nullptr);
  if (JvmtiErrorToException(
          env,
          jvmti_env,
          jvmti_env->SetEventNotificationMode(JVMTI_DISABLE, JVMTI_EVENT_FRAME_POP, thr))) {
    return;
  }
  if (JvmtiErrorToException(
          env,
          jvmti_env,
          jvmti_env->SetEventNotificationMode(JVMTI_DISABLE, JVMTI_EVENT_BREAKPOINT, thr))) {
    return;
  }
  if (JvmtiErrorToException(
          env, jvmti_env, jvmti_env->ClearBreakpoint(data->frame_pop_setup_method, 0))) {
    return;
  }
  DeleteTestData(env, thr, data);
}

extern "C" JNIEXPORT void JNICALL Java_art_SuspendEvents_setupSuspendBreakpointFor(
    JNIEnv* env, [[maybe_unused]] jclass klass , jobject meth, jlocation loc, jthread thr) {
  TestData* data;
  if (JvmtiErrorToException(
          env, jvmti_env, jvmti_env->GetThreadLocalStorage(thr, reinterpret_cast<void**>(&data)))) {
    return;
  }
  CHECK(data == nullptr) << "Data was not cleared!";
  data = SetupTestData(env, meth, loc, nullptr, nullptr, nullptr, 0);
  if (data == nullptr) {
    return;
  }
  if (JvmtiErrorToException(env, jvmti_env, jvmti_env->SetThreadLocalStorage(thr, data))) {
    return;
  }
  if (JvmtiErrorToException(
          env,
          jvmti_env,
          jvmti_env->SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_BREAKPOINT, thr))) {
    return;
  }
  JvmtiErrorToException(
      env, jvmti_env, jvmti_env->SetBreakpoint(data->target_method, data->target_loc));
}

extern "C" JNIEXPORT void JNICALL Java_art_SuspendEvents_clearSuspendBreakpointFor(
    JNIEnv* env, [[maybe_unused]] jclass klass , jthread thr) {
  TestData* data;
  if (JvmtiErrorToException(
          env, jvmti_env, jvmti_env->GetThreadLocalStorage(thr, reinterpret_cast<void**>(&data)))) {
    return;
  }
  CHECK(data != nullptr);
  if (JvmtiErrorToException(
          env,
          jvmti_env,
          jvmti_env->SetEventNotificationMode(JVMTI_DISABLE, JVMTI_EVENT_BREAKPOINT, thr))) {
    return;
  }
  if (JvmtiErrorToException(
          env, jvmti_env, jvmti_env->ClearBreakpoint(data->target_method, data->target_loc))) {
    return;
  }
  if (JvmtiErrorToException(env, jvmti_env, jvmti_env->SetThreadLocalStorage(thr, nullptr))) {
    return;
  }
  DeleteTestData(env, thr, data);
}

extern "C" JNIEXPORT void JNICALL Java_art_SuspendEvents_setupSuspendExceptionEvent(
    JNIEnv* env, [[maybe_unused]] jclass klass , jobject method, jboolean is_catch, jthread thr) {
  TestData* data;
  if (JvmtiErrorToException(
          env, jvmti_env, jvmti_env->GetThreadLocalStorage(thr, reinterpret_cast<void**>(&data)))) {
    return;
  }
  CHECK(data == nullptr) << "Data was not cleared!";
  data = SetupTestData(env, method, 0, nullptr, nullptr, nullptr, 0);
  if (data == nullptr) {
    return;
  }
  if (JvmtiErrorToException(env, jvmti_env, jvmti_env->SetThreadLocalStorage(thr, data))) {
    return;
  }
  JvmtiErrorToException(
      env,
      jvmti_env,
      jvmti_env->SetEventNotificationMode(
          JVMTI_ENABLE, is_catch ? JVMTI_EVENT_EXCEPTION_CATCH : JVMTI_EVENT_EXCEPTION, thr));
}

extern "C" JNIEXPORT void JNICALL Java_art_SuspendEvents_clearSuspendExceptionEvent(
    JNIEnv* env, [[maybe_unused]] jclass klass , jthread thr) {
  TestData* data;
  if (JvmtiErrorToException(
          env, jvmti_env, jvmti_env->GetThreadLocalStorage(thr, reinterpret_cast<void**>(&data)))) {
    return;
  }
  CHECK(data != nullptr);
  if (JvmtiErrorToException(
          env,
          jvmti_env,
          jvmti_env->SetEventNotificationMode(JVMTI_DISABLE, JVMTI_EVENT_EXCEPTION_CATCH, thr))) {
    return;
  }
  if (JvmtiErrorToException(
          env,
          jvmti_env,
          jvmti_env->SetEventNotificationMode(JVMTI_DISABLE, JVMTI_EVENT_EXCEPTION, thr))) {
    return;
  }
  DeleteTestData(env, thr, data);
}

extern "C" JNIEXPORT void JNICALL Java_art_SuspendEvents_setupSuspendMethodEvent(
    JNIEnv* env, [[maybe_unused]] jclass klass , jobject method, jboolean enter, jthread thr) {
  TestData* data;
  if (JvmtiErrorToException(
          env, jvmti_env, jvmti_env->GetThreadLocalStorage(thr, reinterpret_cast<void**>(&data)))) {
    return;
  }
  CHECK(data == nullptr) << "Data was not cleared!";
  data = SetupTestData(env, method, 0, nullptr, nullptr, nullptr, 0);
  if (data == nullptr) {
    return;
  }
  if (JvmtiErrorToException(env, jvmti_env, jvmti_env->SetThreadLocalStorage(thr, data))) {
    return;
  }
  JvmtiErrorToException(
      env,
      jvmti_env,
      jvmti_env->SetEventNotificationMode(
          JVMTI_ENABLE, enter ? JVMTI_EVENT_METHOD_ENTRY : JVMTI_EVENT_METHOD_EXIT, thr));
}

extern "C" JNIEXPORT void JNICALL Java_art_SuspendEvents_clearSuspendMethodEvent(
    JNIEnv* env, [[maybe_unused]] jclass klass , jthread thr) {
  TestData* data;
  if (JvmtiErrorToException(
          env, jvmti_env, jvmti_env->GetThreadLocalStorage(thr, reinterpret_cast<void**>(&data)))) {
    return;
  }
  CHECK(data != nullptr);
  if (JvmtiErrorToException(
          env,
          jvmti_env,
          jvmti_env->SetEventNotificationMode(JVMTI_DISABLE, JVMTI_EVENT_METHOD_EXIT, thr))) {
    return;
  }
  if (JvmtiErrorToException(
          env,
          jvmti_env,
          jvmti_env->SetEventNotificationMode(JVMTI_DISABLE, JVMTI_EVENT_METHOD_ENTRY, thr))) {
    return;
  }
  DeleteTestData(env, thr, data);
}

extern "C" JNIEXPORT void JNICALL
Java_art_SuspendEvents_setupFieldSuspendFor(JNIEnv* env,
                                            [[maybe_unused]] jclass klass,
                                            jclass target_klass,
                                            jobject field,
                                            jboolean access,
                                            jthread thr) {
  TestData* data;
  if (JvmtiErrorToException(
          env, jvmti_env, jvmti_env->GetThreadLocalStorage(thr, reinterpret_cast<void**>(&data)))) {
    return;
  }
  CHECK(data == nullptr) << "Data was not cleared!";
  data = SetupTestData(env, nullptr, 0, target_klass, field, nullptr, 0);
  if (data == nullptr) {
    return;
  }
  if (JvmtiErrorToException(env, jvmti_env, jvmti_env->SetThreadLocalStorage(thr, data))) {
    return;
  }
  if (JvmtiErrorToException(env,
                            jvmti_env,
                            jvmti_env->SetEventNotificationMode(
                                JVMTI_ENABLE,
                                access ? JVMTI_EVENT_FIELD_ACCESS : JVMTI_EVENT_FIELD_MODIFICATION,
                                thr))) {
    return;
  }
  if (access) {
    JvmtiErrorToException(
        env, jvmti_env, jvmti_env->SetFieldAccessWatch(data->target_klass, data->target_field));
  } else {
    JvmtiErrorToException(
        env,
        jvmti_env,
        jvmti_env->SetFieldModificationWatch(data->target_klass, data->target_field));
  }
}

extern "C" JNIEXPORT void JNICALL Java_art_SuspendEvents_clearFieldSuspendFor(
    JNIEnv* env, [[maybe_unused]] jclass klass , jthread thr) {
  TestData* data;
  if (JvmtiErrorToException(
          env, jvmti_env, jvmti_env->GetThreadLocalStorage(thr, reinterpret_cast<void**>(&data)))) {
    return;
  }
  CHECK(data != nullptr);
  if (JvmtiErrorToException(
          env,
          jvmti_env,
          jvmti_env->SetEventNotificationMode(JVMTI_DISABLE, JVMTI_EVENT_FIELD_ACCESS, thr))) {
    return;
  }
  if (JvmtiErrorToException(env,
                            jvmti_env,
                            jvmti_env->SetEventNotificationMode(
                                JVMTI_DISABLE, JVMTI_EVENT_FIELD_MODIFICATION, thr))) {
    return;
  }
  if (JvmtiErrorToException(
          env,
          jvmti_env,
          jvmti_env->ClearFieldModificationWatch(data->target_klass, data->target_field)) &&
      JvmtiErrorToException(
          env,
          jvmti_env,
          jvmti_env->ClearFieldAccessWatch(data->target_klass, data->target_field))) {
    return;
  } else {
    env->ExceptionClear();
  }
  if (JvmtiErrorToException(env, jvmti_env, jvmti_env->SetThreadLocalStorage(thr, nullptr))) {
    return;
  }
  DeleteTestData(env, thr, data);
}

extern "C" JNIEXPORT void JNICALL Java_art_SuspendEvents_setupWaitForNativeCall(
    JNIEnv* env, [[maybe_unused]] jclass klass , jthread thr) {
  TestData* data;
  if (JvmtiErrorToException(
          env, jvmti_env, jvmti_env->GetThreadLocalStorage(thr, reinterpret_cast<void**>(&data)))) {
    return;
  }
  CHECK(data == nullptr) << "Data was not cleared!";
  data = SetupTestData(env, nullptr, 0, nullptr, nullptr, nullptr, 0);
  if (data == nullptr) {
    return;
  }
  if (JvmtiErrorToException(env, jvmti_env, jvmti_env->SetThreadLocalStorage(thr, data))) {
    return;
  }
}

extern "C" JNIEXPORT void JNICALL Java_art_SuspendEvents_clearWaitForNativeCall(
    JNIEnv* env, [[maybe_unused]] jclass klass , jthread thr) {
  TestData* data;
  if (JvmtiErrorToException(
          env, jvmti_env, jvmti_env->GetThreadLocalStorage(thr, reinterpret_cast<void**>(&data)))) {
    return;
  }
  CHECK(data != nullptr);
  if (JvmtiErrorToException(env, jvmti_env, jvmti_env->SetThreadLocalStorage(thr, nullptr))) {
    return;
  }
  DeleteTestData(env, thr, data);
}

extern "C" JNIEXPORT void JNICALL
Java_art_SuspendEvents_waitForSuspendHit(JNIEnv* env, [[maybe_unused]] jclass klass, jthread thr) {
  TestData* data;
  if (JvmtiErrorToException(
          env, jvmti_env, jvmti_env->GetThreadLocalStorage(thr, reinterpret_cast<void**>(&data)))) {
    return;
  }
  CHECK(data != nullptr);
  if (JvmtiErrorToException(env, jvmti_env, jvmti_env->RawMonitorEnter(data->notify_monitor))) {
    return;
  }
  while (!data->hit_location) {
    if (JvmtiErrorToException(
            env, jvmti_env, jvmti_env->RawMonitorWait(data->notify_monitor, -1))) {
      return;
    }
  }
  if (JvmtiErrorToException(env, jvmti_env, jvmti_env->RawMonitorExit(data->notify_monitor))) {
    return;
  }
  jint state = 0;
  while (!JvmtiErrorToException(env, jvmti_env, jvmti_env->GetThreadState(thr, &state)) &&
         (state & JVMTI_THREAD_STATE_SUSPENDED) == 0) {
  }
}
}  // namespace common_suspend_event
}  // namespace art
