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

#include <signal.h>
#include <sys/types.h>
#include <unistd.h>

#include <initializer_list>
#include <memory>
#include <mutex>
#include <string>

#include "jni.h"

#include "art_method-inl.h"
#include "base/mem_map.h"
#include "base/mutex.h"
#include "class_linker.h"
#include "common_runtime_test.h"
#include "dex/class_reference.h"
#include "handle.h"
#include "handle_scope-inl.h"
#include "mirror/class-inl.h"
#include "mirror/class_loader.h"
#include "monitor-inl.h"
#include "nativehelper/scoped_local_ref.h"
#include "obj_ptr-inl.h"
#include "runtime.h"
#include "scoped_thread_state_change-inl.h"
#include "thread-inl.h"
#include "thread_list.h"
#include "well_known_classes.h"

namespace art {

class RuntimeCallbacksTest : public CommonRuntimeTest {
 protected:
  void SetUp() override {
    CommonRuntimeTest::SetUp();

    Thread* self = Thread::Current();
    ScopedObjectAccess soa(self);
    ScopedThreadSuspension sts(self, kWaitingForDebuggerToAttach);
    ScopedSuspendAll ssa("RuntimeCallbacksTest SetUp");
    AddListener();
  }

  void TearDown() override {
    {
      Thread* self = Thread::Current();
      ScopedObjectAccess soa(self);
      ScopedThreadSuspension sts(self, kWaitingForDebuggerToAttach);
      ScopedSuspendAll ssa("RuntimeCallbacksTest TearDown");
      RemoveListener();
    }

    CommonRuntimeTest::TearDown();
  }

  virtual void AddListener() REQUIRES(Locks::mutator_lock_) = 0;
  virtual void RemoveListener() REQUIRES(Locks::mutator_lock_) = 0;

  void MakeExecutable(ObjPtr<mirror::Class> klass) REQUIRES_SHARED(Locks::mutator_lock_) {
    CHECK(klass != nullptr);
    PointerSize pointer_size = class_linker_->GetImagePointerSize();
    for (auto& m : klass->GetMethods(pointer_size)) {
      if (!m.IsAbstract()) {
        class_linker_->SetEntryPointsToInterpreter(&m);
      }
    }
  }
};

class ThreadLifecycleCallbackRuntimeCallbacksTest : public RuntimeCallbacksTest {
 public:
  static void* PthreadsCallback(void* arg ATTRIBUTE_UNUSED) {
    // Attach.
    Runtime* runtime = Runtime::Current();
    CHECK(runtime->AttachCurrentThread("ThreadLifecycle test thread", true, nullptr, false));

    // Detach.
    runtime->DetachCurrentThread();

    // Die...
    return nullptr;
  }

 protected:
  void AddListener() override REQUIRES(Locks::mutator_lock_) {
    Runtime::Current()->GetRuntimeCallbacks()->AddThreadLifecycleCallback(&cb_);
  }
  void RemoveListener() override REQUIRES(Locks::mutator_lock_) {
    Runtime::Current()->GetRuntimeCallbacks()->RemoveThreadLifecycleCallback(&cb_);
  }

  enum CallbackState {
    kBase,
    kStarted,
    kDied,
    kWrongStart,
    kWrongDeath,
  };

  struct Callback : public ThreadLifecycleCallback {
    void ThreadStart(Thread* self) override {
      if (state == CallbackState::kBase) {
        state = CallbackState::kStarted;
        stored_self = self;
      } else {
        state = CallbackState::kWrongStart;
      }
    }

    void ThreadDeath(Thread* self) override {
      if (state == CallbackState::kStarted && self == stored_self) {
        state = CallbackState::kDied;
      } else {
        state = CallbackState::kWrongDeath;
      }
    }

    Thread* stored_self;
    CallbackState state = CallbackState::kBase;
  };

  Callback cb_;
};

TEST_F(ThreadLifecycleCallbackRuntimeCallbacksTest, ThreadLifecycleCallbackJava) {
  Thread* self = Thread::Current();

  self->TransitionFromSuspendedToRunnable();
  bool started = runtime_->Start();
  ASSERT_TRUE(started);
  // Make sure the workers are done starting so we don't get callbacks for them.
  runtime_->WaitForThreadPoolWorkersToStart();

  cb_.state = CallbackState::kBase;  // Ignore main thread attach.

  {
    ScopedObjectAccess soa(self);
    MakeExecutable(soa.Decode<mirror::Class>(WellKnownClasses::java_lang_Thread));
  }

  JNIEnv* env = self->GetJniEnv();

  ScopedLocalRef<jobject> thread_name(env,
                                      env->NewStringUTF("ThreadLifecycleCallback test thread"));
  ASSERT_TRUE(thread_name.get() != nullptr);

  ScopedLocalRef<jobject> thread(env, env->AllocObject(WellKnownClasses::java_lang_Thread));
  ASSERT_TRUE(thread.get() != nullptr);

  env->CallNonvirtualVoidMethod(thread.get(),
                                WellKnownClasses::java_lang_Thread,
                                WellKnownClasses::java_lang_Thread_init,
                                runtime_->GetMainThreadGroup(),
                                thread_name.get(),
                                kMinThreadPriority,
                                JNI_FALSE);
  ASSERT_FALSE(env->ExceptionCheck());

  jmethodID start_id = env->GetMethodID(WellKnownClasses::java_lang_Thread, "start", "()V");
  ASSERT_TRUE(start_id != nullptr);

  env->CallVoidMethod(thread.get(), start_id);
  ASSERT_FALSE(env->ExceptionCheck());

  jmethodID join_id = env->GetMethodID(WellKnownClasses::java_lang_Thread, "join", "()V");
  ASSERT_TRUE(join_id != nullptr);

  env->CallVoidMethod(thread.get(), join_id);
  ASSERT_FALSE(env->ExceptionCheck());

  EXPECT_TRUE(cb_.state == CallbackState::kDied) << static_cast<int>(cb_.state);
}

TEST_F(ThreadLifecycleCallbackRuntimeCallbacksTest, ThreadLifecycleCallbackAttach) {
  std::string error_msg;
  MemMap stack = MemMap::MapAnonymous("ThreadLifecycleCallback Thread",
                                      128 * kPageSize,  // Just some small stack.
                                      PROT_READ | PROT_WRITE,
                                      /*low_4gb=*/ false,
                                      &error_msg);
  ASSERT_TRUE(stack.IsValid()) << error_msg;

  const char* reason = "ThreadLifecycleCallback test thread";
  pthread_attr_t attr;
  CHECK_PTHREAD_CALL(pthread_attr_init, (&attr), reason);
  CHECK_PTHREAD_CALL(pthread_attr_setstack, (&attr, stack.Begin(), stack.Size()), reason);
  pthread_t pthread;
  CHECK_PTHREAD_CALL(pthread_create,
                     (&pthread,
                         &attr,
                         &ThreadLifecycleCallbackRuntimeCallbacksTest::PthreadsCallback,
                         this),
                         reason);
  CHECK_PTHREAD_CALL(pthread_attr_destroy, (&attr), reason);

  CHECK_PTHREAD_CALL(pthread_join, (pthread, nullptr), "ThreadLifecycleCallback test shutdown");

  // Detach is not a ThreadDeath event, so we expect to be in state Started.
  EXPECT_TRUE(cb_.state == CallbackState::kStarted) << static_cast<int>(cb_.state);
}

class ClassLoadCallbackRuntimeCallbacksTest : public RuntimeCallbacksTest {
 protected:
  void AddListener() override REQUIRES(Locks::mutator_lock_) {
    Runtime::Current()->GetRuntimeCallbacks()->AddClassLoadCallback(&cb_);
  }
  void RemoveListener() override REQUIRES(Locks::mutator_lock_) {
    Runtime::Current()->GetRuntimeCallbacks()->RemoveClassLoadCallback(&cb_);
  }

  bool Expect(std::initializer_list<const char*> list) {
    if (cb_.data.size() != list.size()) {
      PrintError(list);
      return false;
    }

    if (!std::equal(cb_.data.begin(), cb_.data.end(), list.begin())) {
      PrintError(list);
      return false;
    }

    return true;
  }

  void PrintError(std::initializer_list<const char*> list) {
    LOG(ERROR) << "Expected:";
    for (const char* expected : list) {
      LOG(ERROR) << "  " << expected;
    }
    LOG(ERROR) << "Found:";
    for (const auto& s : cb_.data) {
      LOG(ERROR) << "  " << s;
    }
  }

  struct Callback : public ClassLoadCallback {
    void ClassPreDefine(const char* descriptor,
                        Handle<mirror::Class> klass ATTRIBUTE_UNUSED,
                        Handle<mirror::ClassLoader> class_loader ATTRIBUTE_UNUSED,
                        const DexFile& initial_dex_file,
                        const dex::ClassDef& initial_class_def ATTRIBUTE_UNUSED,
                        /*out*/DexFile const** final_dex_file ATTRIBUTE_UNUSED,
                        /*out*/dex::ClassDef const** final_class_def ATTRIBUTE_UNUSED) override
        REQUIRES_SHARED(Locks::mutator_lock_) {
      const std::string& location = initial_dex_file.GetLocation();
      std::string event =
          std::string("PreDefine:") + descriptor + " <" +
          location.substr(location.rfind('/') + 1, location.size()) + ">";
      data.push_back(event);
    }

    void ClassLoad(Handle<mirror::Class> klass) override REQUIRES_SHARED(Locks::mutator_lock_) {
      std::string tmp;
      std::string event = std::string("Load:") + klass->GetDescriptor(&tmp);
      data.push_back(event);
    }

    void ClassPrepare(Handle<mirror::Class> temp_klass,
                      Handle<mirror::Class> klass) override REQUIRES_SHARED(Locks::mutator_lock_) {
      std::string tmp, tmp2;
      std::string event = std::string("Prepare:") + klass->GetDescriptor(&tmp)
          + "[" + temp_klass->GetDescriptor(&tmp2) + "]";
      data.push_back(event);
    }

    std::vector<std::string> data;
  };

  Callback cb_;
};

TEST_F(ClassLoadCallbackRuntimeCallbacksTest, ClassLoadCallback) {
  ScopedObjectAccess soa(Thread::Current());
  jobject jclass_loader = LoadDex("XandY");
  VariableSizedHandleScope hs(soa.Self());
  Handle<mirror::ClassLoader> class_loader(hs.NewHandle(
      soa.Decode<mirror::ClassLoader>(jclass_loader)));

  const char* descriptor_y = "LY;";
  Handle<mirror::Class> h_Y(
      hs.NewHandle(class_linker_->FindClass(soa.Self(), descriptor_y, class_loader)));
  ASSERT_TRUE(h_Y != nullptr);

  bool expect1 = Expect({ "PreDefine:LY; <art-gtest-XandY.jar>",
                          "PreDefine:LX; <art-gtest-XandY.jar>",
                          "Load:LX;",
                          "Prepare:LX;[LX;]",
                          "Load:LY;",
                          "Prepare:LY;[LY;]" });
  EXPECT_TRUE(expect1);

  cb_.data.clear();

  ASSERT_TRUE(class_linker_->EnsureInitialized(Thread::Current(), h_Y, true, true));

  bool expect2 = Expect({ "PreDefine:LY$Z; <art-gtest-XandY.jar>",
                          "Load:LY$Z;",
                          "Prepare:LY$Z;[LY$Z;]" });
  EXPECT_TRUE(expect2);
}

class RuntimeSigQuitCallbackRuntimeCallbacksTest : public RuntimeCallbacksTest {
 protected:
  void AddListener() override REQUIRES(Locks::mutator_lock_) {
    Runtime::Current()->GetRuntimeCallbacks()->AddRuntimeSigQuitCallback(&cb_);
  }
  void RemoveListener() override REQUIRES(Locks::mutator_lock_) {
    Runtime::Current()->GetRuntimeCallbacks()->RemoveRuntimeSigQuitCallback(&cb_);
  }

  struct Callback : public RuntimeSigQuitCallback {
    void SigQuit() override {
      ++sigquit_count;
    }

    size_t sigquit_count = 0;
  };

  Callback cb_;
};

TEST_F(RuntimeSigQuitCallbackRuntimeCallbacksTest, SigQuit) {
  // The runtime needs to be started for the signal handler.
  Thread* self = Thread::Current();

  self->TransitionFromSuspendedToRunnable();
  bool started = runtime_->Start();
  ASSERT_TRUE(started);

  EXPECT_EQ(0u, cb_.sigquit_count);

  kill(getpid(), SIGQUIT);

  // Try a few times.
  for (size_t i = 0; i != 30; ++i) {
    if (cb_.sigquit_count == 0) {
      sleep(1);
    } else {
      break;
    }
  }
  EXPECT_EQ(1u, cb_.sigquit_count);
}

class RuntimePhaseCallbackRuntimeCallbacksTest : public RuntimeCallbacksTest {
 protected:
  void AddListener() override REQUIRES(Locks::mutator_lock_) {
    Runtime::Current()->GetRuntimeCallbacks()->AddRuntimePhaseCallback(&cb_);
  }
  void RemoveListener() override REQUIRES(Locks::mutator_lock_) {
    Runtime::Current()->GetRuntimeCallbacks()->RemoveRuntimePhaseCallback(&cb_);
  }

  void TearDown() override {
    // Bypass RuntimeCallbacksTest::TearDown, as the runtime is already gone.
    CommonRuntimeTest::TearDown();
  }

  struct Callback : public RuntimePhaseCallback {
    void NextRuntimePhase(RuntimePhaseCallback::RuntimePhase p) override {
      if (p == RuntimePhaseCallback::RuntimePhase::kInitialAgents) {
        if (start_seen > 0 || init_seen > 0 || death_seen > 0) {
          LOG(FATAL) << "Unexpected order";
        }
        ++initial_agents_seen;
      } else if (p == RuntimePhaseCallback::RuntimePhase::kStart) {
        if (init_seen > 0 || death_seen > 0) {
          LOG(FATAL) << "Init seen before start.";
        }
        ++start_seen;
      } else if (p == RuntimePhaseCallback::RuntimePhase::kInit) {
        ++init_seen;
      } else if (p == RuntimePhaseCallback::RuntimePhase::kDeath) {
        ++death_seen;
      } else {
        LOG(FATAL) << "Unknown phase " << static_cast<uint32_t>(p);
      }
    }

    size_t initial_agents_seen = 0;
    size_t start_seen = 0;
    size_t init_seen = 0;
    size_t death_seen = 0;
  };

  Callback cb_;
};

TEST_F(RuntimePhaseCallbackRuntimeCallbacksTest, Phases) {
  ASSERT_EQ(0u, cb_.initial_agents_seen);
  ASSERT_EQ(0u, cb_.start_seen);
  ASSERT_EQ(0u, cb_.init_seen);
  ASSERT_EQ(0u, cb_.death_seen);

  // Start the runtime.
  {
    Thread* self = Thread::Current();
    self->TransitionFromSuspendedToRunnable();
    bool started = runtime_->Start();
    ASSERT_TRUE(started);
  }

  ASSERT_EQ(0u, cb_.initial_agents_seen);
  ASSERT_EQ(1u, cb_.start_seen);
  ASSERT_EQ(1u, cb_.init_seen);
  ASSERT_EQ(0u, cb_.death_seen);

  // Delete the runtime.
  runtime_.reset();

  ASSERT_EQ(0u, cb_.initial_agents_seen);
  ASSERT_EQ(1u, cb_.start_seen);
  ASSERT_EQ(1u, cb_.init_seen);
  ASSERT_EQ(1u, cb_.death_seen);
}

class MonitorWaitCallbacksTest : public RuntimeCallbacksTest {
 protected:
  void AddListener() override REQUIRES(Locks::mutator_lock_) {
    Runtime::Current()->GetRuntimeCallbacks()->AddMonitorCallback(&cb_);
  }
  void RemoveListener() override REQUIRES(Locks::mutator_lock_) {
    Runtime::Current()->GetRuntimeCallbacks()->RemoveMonitorCallback(&cb_);
  }

  struct Callback : public MonitorCallback {
    bool IsInterestingObject(ObjPtr<mirror::Object> obj)
        REQUIRES_SHARED(art::Locks::mutator_lock_) {
      if (!obj->IsClass()) {
        return false;
      }
      std::lock_guard<std::mutex> lock(ref_guard_);
      ObjPtr<mirror::Class> k = obj->AsClass();
      ClassReference test = { &k->GetDexFile(), k->GetDexClassDefIndex() };
      return ref_ == test;
    }

    void SetInterestingObject(ObjPtr<mirror::Object> obj)
        REQUIRES_SHARED(art::Locks::mutator_lock_) {
      std::lock_guard<std::mutex> lock(ref_guard_);
      ObjPtr<mirror::Class> k = obj->AsClass();
      ref_ = { &k->GetDexFile(), k->GetDexClassDefIndex() };
    }

    void MonitorContendedLocking(Monitor* mon ATTRIBUTE_UNUSED) override
        REQUIRES_SHARED(Locks::mutator_lock_) { }

    void MonitorContendedLocked(Monitor* mon ATTRIBUTE_UNUSED) override
        REQUIRES_SHARED(Locks::mutator_lock_) { }

    void ObjectWaitStart(Handle<mirror::Object> obj, int64_t millis ATTRIBUTE_UNUSED) override
        REQUIRES_SHARED(Locks::mutator_lock_) {
      if (IsInterestingObject(obj.Get())) {
        saw_wait_start_ = true;
      }
    }

    void MonitorWaitFinished(Monitor* m, bool timed_out ATTRIBUTE_UNUSED) override
        REQUIRES_SHARED(Locks::mutator_lock_) {
      if (IsInterestingObject(m->GetObject())) {
        saw_wait_finished_ = true;
      }
    }

    std::mutex ref_guard_;
    ClassReference ref_ = {nullptr, 0};
    bool saw_wait_start_ = false;
    bool saw_wait_finished_ = false;
  };

  Callback cb_;
};

// TODO It would be good to have more tests for this but due to the multi-threaded nature of the
// callbacks this is difficult. For now the run-tests 1931 & 1932 should be sufficient.
TEST_F(MonitorWaitCallbacksTest, WaitUnlocked) {
  ASSERT_FALSE(cb_.saw_wait_finished_);
  ASSERT_FALSE(cb_.saw_wait_start_);
  {
    Thread* self = Thread::Current();
    self->TransitionFromSuspendedToRunnable();
    bool started = runtime_->Start();
    ASSERT_TRUE(started);
    {
      ScopedObjectAccess soa(self);
      cb_.SetInterestingObject(
          soa.Decode<mirror::Class>(WellKnownClasses::java_util_Collections));
      Monitor::Wait(
          self,
          // Just a random class
          soa.Decode<mirror::Class>(WellKnownClasses::java_util_Collections),
          /*ms=*/0,
          /*ns=*/0,
          /*interruptShouldThrow=*/false,
          /*why=*/kWaiting);
    }
  }
  ASSERT_TRUE(cb_.saw_wait_start_);
  ASSERT_FALSE(cb_.saw_wait_finished_);
}

}  // namespace art
