/* Copyright (C) 2017 The Android Open Source Project
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This file implements interfaces from the file jvmti.h. This implementation
 * is licensed under the same terms as the file jvmti.h.  The
 * copyright and license information for the file jvmti.h follows.
 *
 * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

#include "ti_threadgroup.h"

#include "art_field-inl.h"
#include "art_jvmti.h"
#include "base/logging.h"
#include "base/macros.h"
#include "base/mutex.h"
#include "handle_scope-inl.h"
#include "jni/jni_internal.h"
#include "mirror/class.h"
#include "mirror/object-inl.h"
#include "mirror/string.h"
#include "obj_ptr.h"
#include "object_lock.h"
#include "runtime.h"
#include "scoped_thread_state_change-inl.h"
#include "thread-current-inl.h"
#include "thread_list.h"
#include "well_known_classes.h"

namespace openjdkjvmti {


jvmtiError ThreadGroupUtil::GetTopThreadGroups(jvmtiEnv* env,
                                               jint* group_count_ptr,
                                               jthreadGroup** groups_ptr) {
  // We only have a single top group. So we can take the current thread and move upwards.
  if (group_count_ptr == nullptr || groups_ptr == nullptr) {
    return ERR(NULL_POINTER);
  }

  art::Runtime* runtime = art::Runtime::Current();
  if (runtime == nullptr) {
    // Must be starting the runtime, or dying.
    return ERR(WRONG_PHASE);
  }

  jobject sys_thread_group = runtime->GetSystemThreadGroup();
  if (sys_thread_group == nullptr) {
    // Seems we're still starting up.
    return ERR(WRONG_PHASE);
  }

  unsigned char* data;
  jvmtiError result = env->Allocate(sizeof(jthreadGroup), &data);
  if (result != ERR(NONE)) {
    return result;
  }

  jthreadGroup* groups = reinterpret_cast<jthreadGroup*>(data);
  *groups =
      reinterpret_cast<JNIEnv*>(art::Thread::Current()->GetJniEnv())->NewLocalRef(sys_thread_group);
  *groups_ptr = groups;
  *group_count_ptr = 1;

  return ERR(NONE);
}

jvmtiError ThreadGroupUtil::GetThreadGroupInfo(jvmtiEnv* env,
                                               jthreadGroup group,
                                               jvmtiThreadGroupInfo* info_ptr) {
  if (group == nullptr) {
    return ERR(INVALID_THREAD_GROUP);
  }

  art::ScopedObjectAccess soa(art::Thread::Current());
  if (soa.Env()->IsInstanceOf(group, art::WellKnownClasses::java_lang_ThreadGroup) == JNI_FALSE) {
    return ERR(INVALID_THREAD_GROUP);
  }

  art::StackHandleScope<2> hs(soa.Self());
  art::Handle<art::mirror::Class> tg_class(
      hs.NewHandle(soa.Decode<art::mirror::Class>(art::WellKnownClasses::java_lang_ThreadGroup)));
  art::Handle<art::mirror::Object> obj(hs.NewHandle(soa.Decode<art::mirror::Object>(group)));

  // Do the name first. It's the only thing that can fail.
  {
    art::ArtField* name_field =
        art::jni::DecodeArtField(art::WellKnownClasses::java_lang_ThreadGroup_name);
    CHECK(name_field != nullptr);
    art::ObjPtr<art::mirror::String> name_obj =
        art::ObjPtr<art::mirror::String>::DownCast(name_field->GetObject(obj.Get()));
    std::string tmp_str;
    const char* tmp_cstr;
    if (name_obj == nullptr) {
      tmp_cstr = "";
    } else {
      tmp_str = name_obj->ToModifiedUtf8();
      tmp_cstr = tmp_str.c_str();
    }
    jvmtiError result;
    JvmtiUniquePtr<char[]> copy = CopyString(env, tmp_cstr, &result);
    if (copy == nullptr) {
      return result;
    }
    info_ptr->name = copy.release();
  }

  // Parent.
  {
    art::ArtField* parent_field =
        art::jni::DecodeArtField(art::WellKnownClasses::java_lang_ThreadGroup_parent);
    CHECK(parent_field != nullptr);
    art::ObjPtr<art::mirror::Object> parent_group = parent_field->GetObject(obj.Get());
    info_ptr->parent = parent_group == nullptr
                           ? nullptr
                           : soa.AddLocalReference<jthreadGroup>(parent_group);
  }

  // Max priority.
  {
    art::ArtField* prio_field = tg_class->FindDeclaredInstanceField("maxPriority", "I");
    CHECK(prio_field != nullptr);
    info_ptr->max_priority = static_cast<jint>(prio_field->GetInt(obj.Get()));
  }

  // Daemon.
  {
    art::ArtField* daemon_field = tg_class->FindDeclaredInstanceField("daemon", "Z");
    CHECK(daemon_field != nullptr);
    info_ptr->is_daemon = daemon_field->GetBoolean(obj.Get()) == 0 ? JNI_FALSE : JNI_TRUE;
  }

  return ERR(NONE);
}


static bool IsInDesiredThreadGroup(art::Handle<art::mirror::Object> desired_thread_group,
                                   art::ObjPtr<art::mirror::Object> peer)
    REQUIRES_SHARED(art::Locks::mutator_lock_) {
  CHECK(desired_thread_group != nullptr);

  art::ArtField* thread_group_field =
      art::jni::DecodeArtField(art::WellKnownClasses::java_lang_Thread_group);
  DCHECK(thread_group_field != nullptr);
  art::ObjPtr<art::mirror::Object> group = thread_group_field->GetObject(peer);
  return (group == desired_thread_group.Get());
}

static void GetThreads(art::Handle<art::mirror::Object> thread_group,
                       std::vector<art::ObjPtr<art::mirror::Object>>* thread_peers)
    REQUIRES_SHARED(art::Locks::mutator_lock_) REQUIRES(!art::Locks::thread_list_lock_) {
  CHECK(thread_group != nullptr);

  art::MutexLock mu(art::Thread::Current(), *art::Locks::thread_list_lock_);
  for (art::Thread* t : art::Runtime::Current()->GetThreadList()->GetList()) {
    if (t->IsStillStarting()) {
      continue;
    }
    art::ObjPtr<art::mirror::Object> peer = t->GetPeerFromOtherThread();
    if (peer == nullptr) {
      continue;
    }
    if (IsInDesiredThreadGroup(thread_group, peer)) {
      thread_peers->push_back(peer);
    }
  }
}

static void GetChildThreadGroups(art::Handle<art::mirror::Object> thread_group,
                                 std::vector<art::ObjPtr<art::mirror::Object>>* thread_groups)
    REQUIRES_SHARED(art::Locks::mutator_lock_) {
  CHECK(thread_group != nullptr);

  // Get the ThreadGroup[] "groups" out of this thread group...
  art::ArtField* groups_field =
      art::jni::DecodeArtField(art::WellKnownClasses::java_lang_ThreadGroup_groups);
  art::ObjPtr<art::mirror::Object> groups_array = groups_field->GetObject(thread_group.Get());

  if (groups_array == nullptr) {
    return;
  }
  CHECK(groups_array->IsObjectArray());

  art::ObjPtr<art::mirror::ObjectArray<art::mirror::Object>> groups_array_as_array =
      groups_array->AsObjectArray<art::mirror::Object>();

  // Copy all non-null elements.
  for (auto entry : groups_array_as_array->Iterate()) {
    if (entry != nullptr) {
      thread_groups->push_back(entry);
    }
  }
}

jvmtiError ThreadGroupUtil::GetThreadGroupChildren(jvmtiEnv* env,
                                                   jthreadGroup group,
                                                   jint* thread_count_ptr,
                                                   jthread** threads_ptr,
                                                   jint* group_count_ptr,
                                                   jthreadGroup** groups_ptr) {
  if (group == nullptr) {
    return ERR(INVALID_THREAD_GROUP);
  }

  art::ScopedObjectAccess soa(art::Thread::Current());

  if (!soa.Env()->IsInstanceOf(group, art::WellKnownClasses::java_lang_ThreadGroup)) {
    return ERR(INVALID_THREAD_GROUP);
  }

  art::StackHandleScope<1> hs(soa.Self());
  art::Handle<art::mirror::Object> thread_group = hs.NewHandle(
      soa.Decode<art::mirror::Object>(group));

  art::ObjectLock<art::mirror::Object> thread_group_lock(soa.Self(), thread_group);

  std::vector<art::ObjPtr<art::mirror::Object>> thread_peers;
  GetThreads(thread_group, &thread_peers);

  std::vector<art::ObjPtr<art::mirror::Object>> thread_groups;
  GetChildThreadGroups(thread_group, &thread_groups);

  JvmtiUniquePtr<jthread[]> peers_uptr;
  if (!thread_peers.empty()) {
    jvmtiError res;
    peers_uptr = AllocJvmtiUniquePtr<jthread[]>(env, thread_peers.size(), &res);
    if (peers_uptr == nullptr) {
      return res;
    }
  }

  JvmtiUniquePtr<jthreadGroup[]> group_uptr;
  if (!thread_groups.empty()) {
    jvmtiError res;
    group_uptr = AllocJvmtiUniquePtr<jthreadGroup[]>(env, thread_groups.size(), &res);
    if (group_uptr == nullptr) {
      return res;
    }
  }

  // Can't fail anymore from here on.

  // Copy data into out buffers.
  for (size_t i = 0; i != thread_peers.size(); ++i) {
    peers_uptr[i] = soa.AddLocalReference<jthread>(thread_peers[i]);
  }
  for (size_t i = 0; i != thread_groups.size(); ++i) {
    group_uptr[i] = soa.AddLocalReference<jthreadGroup>(thread_groups[i]);
  }

  *thread_count_ptr = static_cast<jint>(thread_peers.size());
  *threads_ptr = peers_uptr.release();
  *group_count_ptr = static_cast<jint>(thread_groups.size());
  *groups_ptr = group_uptr.release();

  return ERR(NONE);
}

}  // namespace openjdkjvmti
