/* 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::ObjPtr<art::mirror::Object> obj = 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));
    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);
    info_ptr->parent = parent_group == nullptr
                           ? nullptr
                           : soa.AddLocalReference<jthreadGroup>(parent_group);
  }

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

  // Daemon.
  {
    art::ArtField* daemon_field = obj->GetClass()->FindDeclaredInstanceField("daemon", "Z");
    CHECK(daemon_field != nullptr);
    info_ptr->is_daemon = daemon_field->GetBoolean(obj) == 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 (int32_t i = 0; i < groups_array_as_array->GetLength(); ++i) {
    art::ObjPtr<art::mirror::Object> entry = groups_array_as_array->Get(i);
    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
