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

#include "android-base/logging.h"
#include "android-base/macros.h"
#include "art_field-inl.h"
#include "art_field.h"
#include "art_method.h"
#include "base/casts.h"
#include "base/utils.h"
#include "class_linker.h"
#include "class_root-inl.h"
#include "common_throws.h"
#include "handle_scope-inl.h"
#include "handle_scope.h"
#include "interpreter/shadow_frame-inl.h"
#include "interpreter/shadow_frame.h"
#include "jni.h"
#include "jni/jni_internal.h"
#include "mirror/class-alloc-inl.h"
#include "mirror/class.h"
#include "mirror/object-inl.h"
#include "mirror/object.h"
#include "mirror/object_array-alloc-inl.h"
#include "mirror/object_array-inl.h"
#include "mirror/object_array.h"
#include "mirror/object_reference.h"
#include "monitor.h"
#include "native_util.h"
#include "nativehelper/jni_macros.h"
#include "nativehelper/scoped_utf_chars.h"
#include "obj_ptr.h"
#include "runtime.h"
#include "scoped_fast_native_object_access-inl.h"
#include "scoped_thread_state_change-inl.h"
#include "stack.h"
#include "stack_reference.h"
#include "thread.h"
#include "thread_list.h"
#include "verify_object.h"
#include "well_known_classes.h"

namespace art HIDDEN {

static jobject Thread_currentThread(JNIEnv* env, jclass) {
  ScopedFastNativeObjectAccess soa(env);
  return soa.AddLocalReference<jobject>(soa.Self()->GetPeer());
}

static jboolean Thread_interrupted(JNIEnv* env, jclass) {
  return static_cast<JNIEnvExt*>(env)->GetSelf()->Interrupted() ? JNI_TRUE : JNI_FALSE;
}

static jboolean Thread_isInterrupted(JNIEnv* env, jobject java_thread) {
  ScopedFastNativeObjectAccess soa(env);
  MutexLock mu(soa.Self(), *Locks::thread_list_lock_);
  Thread* thread = Thread::FromManagedThread(soa, java_thread);
  return (thread != nullptr) ? thread->IsInterrupted() : JNI_FALSE;
}

static void Thread_nativeCreate(JNIEnv* env, jclass, jobject java_thread, jlong stack_size,
                                jboolean daemon) {
  // There are sections in the zygote that forbid thread creation.
  Runtime* runtime = Runtime::Current();
  if (runtime->IsZygote() && runtime->IsZygoteNoThreadSection()) {
    jclass internal_error = env->FindClass("java/lang/InternalError");
    CHECK(internal_error != nullptr);
    env->ThrowNew(internal_error, "Cannot create threads in zygote");
    return;
  }

  Thread::CreateNativeThread(env, java_thread, stack_size, daemon == JNI_TRUE);
}

static jint Thread_nativeGetStatus(JNIEnv* env, jobject java_thread, jboolean has_been_started) {
  // Ordinals from Java's Thread.State.
  const jint kJavaNew = 0;
  const jint kJavaRunnable = 1;
  const jint kJavaBlocked = 2;
  const jint kJavaWaiting = 3;
  const jint kJavaTimedWaiting = 4;
  const jint kJavaTerminated = 5;

  ScopedObjectAccess soa(env);
  ThreadState internal_thread_state =
      (has_been_started ? ThreadState::kTerminated : ThreadState::kStarting);
  MutexLock mu(soa.Self(), *Locks::thread_list_lock_);
  Thread* thread = Thread::FromManagedThread(soa, java_thread);
  if (thread != nullptr) {
    internal_thread_state = thread->GetState();
  }
  switch (internal_thread_state) {
    case ThreadState::kTerminated:                     return kJavaTerminated;
    case ThreadState::kRunnable:                       return kJavaRunnable;
    case ThreadState::kObsoleteRunnable:               break;  // Obsolete value.
    case ThreadState::kTimedWaiting:                   return kJavaTimedWaiting;
    case ThreadState::kSleeping:                       return kJavaTimedWaiting;
    case ThreadState::kBlocked:                        return kJavaBlocked;
    case ThreadState::kWaiting:                        return kJavaWaiting;
    case ThreadState::kStarting:                       return kJavaNew;
    case ThreadState::kNative:                         return kJavaRunnable;
    case ThreadState::kWaitingForTaskProcessor:        return kJavaWaiting;
    case ThreadState::kWaitingForLockInflation:        return kJavaWaiting;
    case ThreadState::kWaitingForGcToComplete:         return kJavaWaiting;
    case ThreadState::kWaitingPerformingGc:            return kJavaWaiting;
    case ThreadState::kWaitingForCheckPointsToRun:     return kJavaWaiting;
    case ThreadState::kWaitingForDebuggerSend:         return kJavaWaiting;
    case ThreadState::kWaitingForDebuggerToAttach:     return kJavaWaiting;
    case ThreadState::kWaitingInMainDebuggerLoop:      return kJavaWaiting;
    case ThreadState::kWaitingForDebuggerSuspension:   return kJavaWaiting;
    case ThreadState::kWaitingForDeoptimization:       return kJavaWaiting;
    case ThreadState::kWaitingForGetObjectsAllocated:  return kJavaWaiting;
    case ThreadState::kWaitingForJniOnLoad:            return kJavaWaiting;
    case ThreadState::kWaitingForSignalCatcherOutput:  return kJavaWaiting;
    case ThreadState::kWaitingInMainSignalCatcherLoop: return kJavaWaiting;
    case ThreadState::kWaitingForMethodTracingStart:   return kJavaWaiting;
    case ThreadState::kWaitingForVisitObjects:         return kJavaWaiting;
    case ThreadState::kWaitingWeakGcRootRead:          return kJavaRunnable;
    case ThreadState::kWaitingForGcThreadFlip:         return kJavaWaiting;
    case ThreadState::kNativeForAbort:                 return kJavaWaiting;
    case ThreadState::kSuspended:                      return kJavaRunnable;
    case ThreadState::kInvalidState:                   break;
    // Don't add a 'default' here so the compiler can spot incompatible enum changes.
  }
  LOG(ERROR) << "Unexpected thread state: " << internal_thread_state;
  return -1;  // Unreachable.
}

static jboolean Thread_holdsLock(JNIEnv* env, jclass, jobject java_object) {
  ScopedObjectAccess soa(env);
  ObjPtr<mirror::Object> object = soa.Decode<mirror::Object>(java_object);
  if (object == nullptr) {
    ThrowNullPointerException("object == null");
    return JNI_FALSE;
  }
  Thread* thread = soa.Self();
  return thread->HoldsLock(object);
}

static void Thread_interrupt0(JNIEnv* env, jobject java_thread) {
  ScopedFastNativeObjectAccess soa(env);
  MutexLock mu(soa.Self(), *Locks::thread_list_lock_);
  Thread* thread = Thread::FromManagedThread(soa, java_thread);
  if (thread != nullptr) {
    thread->Interrupt(soa.Self());
  }
}

static void Thread_setNativeName(JNIEnv* env, jobject peer, jstring java_name) {
  ScopedUtfChars name(env, java_name);
  {
    ScopedObjectAccess soa(env);
    if (soa.Decode<mirror::Object>(peer) == soa.Self()->GetPeer()) {
      soa.Self()->SetThreadName(name.c_str());
      return;
    }
  }
  // Suspend thread to avoid it from killing itself while we set its name. We don't just hold the
  // thread list lock to avoid this, as setting the thread name causes mutator to lock/unlock
  // in the DDMS send code.
  ThreadList* thread_list = Runtime::Current()->GetThreadList();
  // Take suspend thread lock to avoid races with threads trying to suspend this one.
  Thread* thread = thread_list->SuspendThreadByPeer(peer, SuspendReason::kInternal);
  if (thread != nullptr) {
    {
      ScopedObjectAccess soa(env);
      thread->SetThreadName(name.c_str());
    }
    bool resumed = thread_list->Resume(thread, SuspendReason::kInternal);
    DCHECK(resumed);
  }
}

/*
 * Change Linux niceness priority for the given thread, returning errno.
 */
static int Thread_setNiceness0([[maybe_unused]] JNIEnv* env, jobject java_thread, jint new_niceness)
    REQUIRES_SHARED(art::Locks::mutator_lock_) {
  Thread* self = Thread::Current();
  MutexLock mu(self, *Locks::thread_list_lock_);
  Thread* thread = Thread::FromManagedThread(self, self->DecodeJObject(java_thread));
  if (thread != nullptr) {
    return thread->SetNativeNiceness(new_niceness);
  }
  return 0;
}

/*
 * Alter the priority of the specified thread.  "new_priority" will range
 * from Thread.MIN_PRIORITY to Thread.MAX_PRIORITY (1-10), with "normal"
 * threads at Thread.NORM_PRIORITY (5). Returns corresponding niceness.
 */
static void Thread_setPriority0([[maybe_unused]] JNIEnv* env,
                                jobject java_thread,
                                jint new_priority,
                                jint new_niceness) REQUIRES_SHARED(art::Locks::mutator_lock_) {
  // We should just do the conversion and call the above. But that would bypass the
  // Android S workaround in SetNativePriority. So we have a separate code path.
  Thread* self = Thread::Current();
  MutexLock mu(self, *Locks::thread_list_lock_);
  Thread* thread = Thread::FromManagedThread(self, self->DecodeJObject(java_thread));
  if (thread != nullptr) {
    thread->SetNativePriority(new_priority, new_niceness);
  }
}

static int Thread_priorityForNiceness(int niceness) {
  return (Thread::NicenessToPriority(niceness));
}

static int Thread_nicenessForPriority(int priority) {
  return (Thread::PriorityToNiceness(priority));
}

static void Thread_sleep(JNIEnv* env, jclass, jobject java_lock, jlong ms, jint ns) {
  ScopedFastNativeObjectAccess soa(env);
  ObjPtr<mirror::Object> lock = soa.Decode<mirror::Object>(java_lock);
  Monitor::Wait(Thread::Current(), lock.Ptr(), ms, ns, true, ThreadState::kSleeping);
}

/*
 * Causes the thread to temporarily pause and allow other threads to execute.
 *
 * The exact behavior is poorly defined.  Some discussion here:
 *   http://www.cs.umd.edu/~pugh/java/memoryModel/archive/0944.html
 */
static void Thread_yield(JNIEnv*, jobject) {
  sched_yield();
}

enum PinningReason {
  kNoReason = 0,
  kNativeMethod = 1,
  kMonitor = 2,
  kUnsupportedFrame = 3,
};

struct VirtualThreadParkingVisitor final : public StackVisitor {
  explicit VirtualThreadParkingVisitor(Thread* thread) REQUIRES_SHARED(Locks::mutator_lock_)
      : StackVisitor(thread, nullptr, StackVisitor::StackWalkKind::kIncludeInlinedFrames, true),
        shadow_frame_count_(0),
        reason_(kNoReason) {}
  bool VisitFrame() override REQUIRES_SHARED(Locks::mutator_lock_) {
    ShadowFrame* shadow_frame = GetCurrentShadowFrame();

    if (shadow_frame == nullptr) {
      // Stack walking continues only if the only non-interpreted frame is
      // Thread.parkVirtualInternal until JIT and AOT frame is supported.
      ArtMethod** quick_frame = GetCurrentQuickFrame();
      ArtMethod* method = quick_frame != nullptr ? *quick_frame : nullptr;
      if (method != nullptr && method->IsNative()) {
        if (method == WellKnownClasses::java_lang_Thread_parkVirtualInternal) {
          return true;
        }

        reason_ = kNativeMethod;
        return false;
      }

      reason_ = kUnsupportedFrame;
      return false;
    }

    if (!shadow_frame->GetLockCountData().IsEmpty()) {
      reason_ = kMonitor;
      return false;
    }

    // If the verifier was able to verify the locks are balanced, the interpreter won't update the
    // lock cound data. We need to walk the stack to find the locks here. Or should we just have an
    // increment/decrement counter?
    Monitor::VisitLocks(this, LockVisitingCallback, this);
    if (reason_ == kMonitor) {
      return false;
    }
    DCHECK(reason_ == kNoReason);

    shadow_frame_count_++;
    shadow_frames_.push_back(shadow_frame);

    return true;
  }

  static void LockVisitingCallback(ObjPtr<mirror::Object> obj, void* visitor) {
    DCHECK(!obj.IsNull());
    reinterpret_cast<VirtualThreadParkingVisitor*>(visitor)->reason_ = kMonitor;
  }

  std::vector<ShadowFrame*> shadow_frames_;
  size_t shadow_frame_count_;
  PinningReason reason_;
};

static void Thread_parkVirtualInternal(
    JNIEnv* env, jobject, jobject v_context, jobject parked_states, jobject vm_error) {
  Thread* self = Thread::Current();
  ScopedObjectAccess soa(env);
  StackHandleScope<4> hs(soa.Self());
  ClassLinker* cl = Runtime::Current()->GetClassLinker();

  auto v_context_h = hs.NewHandle(soa.Decode<mirror::Object>(v_context));
  auto parked_states_h = hs.NewHandle(soa.Decode<mirror::Object>(parked_states));
  auto opeer_h = hs.NewHandle(self->GetPeer());

  VirtualThreadParkingVisitor dump_visitor(self);
  dump_visitor.WalkStack();

  DCHECK_NE(dump_visitor.reason_, kUnsupportedFrame) << "JIT / AOT frame isn't supported.";
  if (dump_visitor.reason_ != kNoReason) {
    WellKnownClasses::dalvik_system_VirtualThreadContext_pinnedCarrierThread->SetObject<false>(
        v_context_h.Get(), opeer_h.Get());
    // Return to the java code to park the carrier thread
    return;
  }

  size_t num_frames = dump_visitor.shadow_frames_.size();

  DCHECK(!Runtime::Current()->IsActiveTransaction());

  Runtime* runtime = Runtime::Current();
  auto frames_h = hs.NewHandle(mirror::ObjectArray<mirror::Object>::Alloc(
      self,
      soa.Decode<mirror::Class>(WellKnownClasses::dalvik_system_VirtualThreadFrame__array),
      num_frames));
  for (size_t i = 0; i < num_frames; i++) {
    const ShadowFrame* sf = dump_visitor.shadow_frames_[i];
    DCHECK(sf != nullptr);
    sf->CheckConsistentVRegs();

    size_t num_vergs = sf->NumberOfVRegs();
    int32_t non_vref_size = ShadowFrame::ComputeSizeWithoutReferences(num_vergs);

    StackHandleScope<4> hs2(soa.Self());
    auto vtf = hs2.NewHandle(WellKnownClasses::dalvik_system_VirtualThreadFrame.Get()->Alloc(
        self, Runtime::Current()->GetHeap()->GetCurrentAllocator()));
    auto frame_bytes = hs2.NewHandle(mirror::ByteArray::Alloc(self, non_vref_size));
    auto declaring_class = hs2.NewHandle(sf->GetMethod()->GetDeclaringClass());
    auto refs = hs2.NewHandle(mirror::ObjectArray<mirror::Object>::Alloc(
        self, GetClassRoot<mirror::ObjectArray<mirror::Object>>(), num_vergs));
    DCHECK(!vtf.IsNull());
    DCHECK(!frame_bytes.IsNull());
    DCHECK(!refs.IsNull());

    bool areRefsAllNull = true;
    for (uint32_t j = 0; j < sf->NumberOfVRegs(); j++) {
      ObjPtr<mirror::Object> obj = sf->GetVRegReference(j);
      if (obj != nullptr) {
        refs->Set(j, obj);
        areRefsAllNull = false;
      }
    }

    if (!areRefsAllNull) {
      WellKnownClasses::dalvik_system_VirtualThreadFrame_refs->SetObject<false>(vtf.Get(),
                                                                                refs.Get());
    }
    frame_bytes->Memcpy(0, reinterpret_cast<const int8_t*>(sf), 0, non_vref_size);
    WellKnownClasses::dalvik_system_VirtualThreadFrame_frame->SetObject<false>(vtf.Get(),
                                                                               frame_bytes.Get());
    WellKnownClasses::dalvik_system_VirtualThreadFrame_declaringClass->SetObject<false>(
        vtf.Get(), declaring_class.Get());
    frames_h->Set(i, vtf.Get());
  }

  if (self->IsExceptionPending()) {
    // It's likely a OOME. Let's throw it at the java level.
    // Consider handling it in another way, e.g. pinning virtual thread, in the future.
    return;
  }

  WellKnownClasses::dalvik_system_VirtualThreadParkedStates_frames->SetObject<false>(
      parked_states_h.Get(), frames_h.Get());
  WellKnownClasses::dalvik_system_VirtualThreadContext_parkedStates->SetObject<false>(
      v_context_h.Get(), parked_states_h.Get());
  self->SetVirtualThreadFlags(VirtualThreadFlag::kParking, true);

  // Throw a VirtualThreadParkingError to unwind the stack and park the virtual thread.
  env->Throw(reinterpret_cast<jthrowable>(vm_error));
}

static JNINativeMethod gMethods[] = {
    FAST_NATIVE_METHOD(Thread, currentThread, "()Ljava/lang/Thread;"),
    FAST_NATIVE_METHOD(Thread, interrupted, "()Z"),
    FAST_NATIVE_METHOD(Thread, isInterrupted, "()Z"),
    NATIVE_METHOD(Thread, nativeCreate, "(Ljava/lang/Thread;JZ)V"),
    NATIVE_METHOD(Thread, nativeGetStatus, "(Z)I"),
    CRITICAL_NATIVE_METHOD(Thread, nicenessForPriority, "(I)I"),
    NATIVE_METHOD(Thread, holdsLock, "(Ljava/lang/Object;)Z"),
    FAST_NATIVE_METHOD(Thread, interrupt0, "()V"),
    CRITICAL_NATIVE_METHOD(Thread, priorityForNiceness, "(I)I"),
    NATIVE_METHOD(Thread, setNativeName, "(Ljava/lang/String;)V"),
    NATIVE_METHOD(Thread, setNiceness0, "(I)I"),
    NATIVE_METHOD(Thread, setPriority0, "(II)V"),
    FAST_NATIVE_METHOD(Thread, sleep, "(Ljava/lang/Object;JI)V"),
    NATIVE_METHOD(Thread, yield, "()V"),
    NATIVE_METHOD(Thread,
                  parkVirtualInternal,
                  "(Ldalvik/system/VirtualThreadContext;Ldalvik/system/"
                  "VirtualThreadParkedStates;Ldalvik/system/VirtualThreadParkingError;)V"),
};

void register_java_lang_Thread(JNIEnv* env) {
  REGISTER_NATIVE_METHODS("java/lang/Thread");
}

}  // namespace art
