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

#include "android-base/macros.h"

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

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

namespace art {
namespace Test1962MultiThreadEvents {

struct BreakpointData {
  jobject events;
  jmethodID target;
};
void cbMethodEntry(jvmtiEnv* jvmti,
                   JNIEnv* env,
                   jthread thread,
                   jmethodID method,
                   [[maybe_unused]] jboolean was_exception,
                   [[maybe_unused]] jvalue val) {
  BreakpointData* data = nullptr;
  if (JvmtiErrorToException(
          env, jvmti, jvmti->GetThreadLocalStorage(thread, reinterpret_cast<void**>(&data)))) {
    return;
  }
  if (data->target != method) {
    return;
  }
  jclass klass = env->FindClass("art/Test1962");
  jmethodID handler =
      env->GetStaticMethodID(klass, "HandleEvent", "(Ljava/lang/Thread;Ljava/util/List;)V");
  CHECK(data != nullptr);
  env->CallStaticVoidMethod(klass, handler, thread, data->events);
}

extern "C" JNIEXPORT void JNICALL Java_art_Test1962_setupTest(JNIEnv* env,
                                                              [[maybe_unused]] jclass klass) {
  jvmtiCapabilities caps{
    .can_generate_method_exit_events = 1,
  };
  if (JvmtiErrorToException(env, jvmti_env, jvmti_env->AddCapabilities(&caps))) {
    return;
  }
  jvmtiEventCallbacks cb{
    .MethodExit = cbMethodEntry,
  };
  JvmtiErrorToException(env, jvmti_env, jvmti_env->SetEventCallbacks(&cb, sizeof(cb)));
}

extern "C" JNIEXPORT void JNICALL Java_art_Test1962_setupThread(
    JNIEnv* env, [[maybe_unused]] jclass klass, jthread thr, jobject events, jobject target) {
  BreakpointData* data = nullptr;
  if (JvmtiErrorToException(
          env, jvmti_env, jvmti_env->Allocate(sizeof(*data), reinterpret_cast<uint8_t**>(&data)))) {
    return;
  }
  data->events = env->NewGlobalRef(events);
  data->target = env->FromReflectedMethod(target);
  if (JvmtiErrorToException(env, jvmti_env, jvmti_env->SetThreadLocalStorage(thr, data))) {
    return;
  }
  JvmtiErrorToException(
      env,
      jvmti_env,
      jvmti_env->SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_METHOD_EXIT, thr));
}

}  // namespace Test1962MultiThreadEvents
}  // namespace art
