/*
 * Copyright (C) 2016 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.
 */

#ifndef ART_OPENJDKJVMTI_EVENTS_H_
#define ART_OPENJDKJVMTI_EVENTS_H_

#include <bitset>
#include <vector>

#include "base/logging.h"
#include "jvmti.h"
#include "thread.h"

namespace openjdkjvmti {

struct ArtJvmTiEnv;
class JvmtiAllocationListener;
class JvmtiGcPauseListener;
class JvmtiMethodTraceListener;

// an enum for ArtEvents. This differs from the JVMTI events only in that we distinguish between
// retransformation capable and incapable loading
enum class ArtJvmtiEvent {
    kMinEventTypeVal = JVMTI_MIN_EVENT_TYPE_VAL,
    kVmInit = JVMTI_EVENT_VM_INIT,
    kVmDeath = JVMTI_EVENT_VM_DEATH,
    kThreadStart = JVMTI_EVENT_THREAD_START,
    kThreadEnd = JVMTI_EVENT_THREAD_END,
    kClassFileLoadHookNonRetransformable = JVMTI_EVENT_CLASS_FILE_LOAD_HOOK,
    kClassLoad = JVMTI_EVENT_CLASS_LOAD,
    kClassPrepare = JVMTI_EVENT_CLASS_PREPARE,
    kVmStart = JVMTI_EVENT_VM_START,
    kException = JVMTI_EVENT_EXCEPTION,
    kExceptionCatch = JVMTI_EVENT_EXCEPTION_CATCH,
    kSingleStep = JVMTI_EVENT_SINGLE_STEP,
    kFramePop = JVMTI_EVENT_FRAME_POP,
    kBreakpoint = JVMTI_EVENT_BREAKPOINT,
    kFieldAccess = JVMTI_EVENT_FIELD_ACCESS,
    kFieldModification = JVMTI_EVENT_FIELD_MODIFICATION,
    kMethodEntry = JVMTI_EVENT_METHOD_ENTRY,
    kMethodExit = JVMTI_EVENT_METHOD_EXIT,
    kNativeMethodBind = JVMTI_EVENT_NATIVE_METHOD_BIND,
    kCompiledMethodLoad = JVMTI_EVENT_COMPILED_METHOD_LOAD,
    kCompiledMethodUnload = JVMTI_EVENT_COMPILED_METHOD_UNLOAD,
    kDynamicCodeGenerated = JVMTI_EVENT_DYNAMIC_CODE_GENERATED,
    kDataDumpRequest = JVMTI_EVENT_DATA_DUMP_REQUEST,
    kMonitorWait = JVMTI_EVENT_MONITOR_WAIT,
    kMonitorWaited = JVMTI_EVENT_MONITOR_WAITED,
    kMonitorContendedEnter = JVMTI_EVENT_MONITOR_CONTENDED_ENTER,
    kMonitorContendedEntered = JVMTI_EVENT_MONITOR_CONTENDED_ENTERED,
    kResourceExhausted = JVMTI_EVENT_RESOURCE_EXHAUSTED,
    kGarbageCollectionStart = JVMTI_EVENT_GARBAGE_COLLECTION_START,
    kGarbageCollectionFinish = JVMTI_EVENT_GARBAGE_COLLECTION_FINISH,
    kObjectFree = JVMTI_EVENT_OBJECT_FREE,
    kVmObjectAlloc = JVMTI_EVENT_VM_OBJECT_ALLOC,
    kClassFileLoadHookRetransformable = JVMTI_MAX_EVENT_TYPE_VAL + 1,
    kMaxEventTypeVal = kClassFileLoadHookRetransformable,
};

// Convert a jvmtiEvent into a ArtJvmtiEvent
ALWAYS_INLINE static inline ArtJvmtiEvent GetArtJvmtiEvent(ArtJvmTiEnv* env, jvmtiEvent e);

static inline jvmtiEvent GetJvmtiEvent(ArtJvmtiEvent e) {
  if (UNLIKELY(e == ArtJvmtiEvent::kClassFileLoadHookRetransformable)) {
    return JVMTI_EVENT_CLASS_FILE_LOAD_HOOK;
  } else {
    return static_cast<jvmtiEvent>(e);
  }
}

struct EventMask {
  static constexpr size_t kEventsSize =
      static_cast<size_t>(ArtJvmtiEvent::kMaxEventTypeVal) -
      static_cast<size_t>(ArtJvmtiEvent::kMinEventTypeVal) + 1;
  std::bitset<kEventsSize> bit_set;

  static bool EventIsInRange(ArtJvmtiEvent event) {
    return event >= ArtJvmtiEvent::kMinEventTypeVal && event <= ArtJvmtiEvent::kMaxEventTypeVal;
  }

  void Set(ArtJvmtiEvent event, bool value = true) {
    DCHECK(EventIsInRange(event));
    bit_set.set(static_cast<size_t>(event) - static_cast<size_t>(ArtJvmtiEvent::kMinEventTypeVal),
                value);
  }

  bool Test(ArtJvmtiEvent event) const {
    DCHECK(EventIsInRange(event));
    return bit_set.test(
        static_cast<size_t>(event) - static_cast<size_t>(ArtJvmtiEvent::kMinEventTypeVal));
  }
};

struct EventMasks {
  // The globally enabled events.
  EventMask global_event_mask;

  // The per-thread enabled events.

  // It is not enough to store a Thread pointer, as these may be reused. Use the pointer and the
  // thread id.
  // Note: We could just use the tid like tracing does.
  using UniqueThread = std::pair<art::Thread*, uint32_t>;
  // TODO: Native thread objects are immovable, so we can use them as keys in an (unordered) map,
  //       if necessary.
  std::vector<std::pair<UniqueThread, EventMask>> thread_event_masks;

  // A union of the per-thread events, for fast-pathing.
  EventMask unioned_thread_event_mask;

  EventMask& GetEventMask(art::Thread* thread);
  EventMask* GetEventMaskOrNull(art::Thread* thread);
  void EnableEvent(art::Thread* thread, ArtJvmtiEvent event);
  void DisableEvent(art::Thread* thread, ArtJvmtiEvent event);
  bool IsEnabledAnywhere(ArtJvmtiEvent event);
  // Make any changes to event masks needed for the given capability changes. If caps_added is true
  // then caps is all the newly set capabilities of the jvmtiEnv. If it is false then caps is the
  // set of all capabilities that were removed from the jvmtiEnv.
  void HandleChangedCapabilities(const jvmtiCapabilities& caps, bool caps_added);
};

// Helper class for event handling.
class EventHandler {
 public:
  EventHandler();
  ~EventHandler();

  // do cleanup for the event handler.
  void Shutdown();

  // Register an env. It is assumed that this happens on env creation, that is, no events are
  // enabled, yet.
  void RegisterArtJvmTiEnv(ArtJvmTiEnv* env);

  // Remove an env.
  void RemoveArtJvmTiEnv(ArtJvmTiEnv* env);

  bool IsEventEnabledAnywhere(ArtJvmtiEvent event) const {
    if (!EventMask::EventIsInRange(event)) {
      return false;
    }
    return global_mask.Test(event);
  }

  jvmtiError SetEvent(ArtJvmTiEnv* env,
                      art::Thread* thread,
                      ArtJvmtiEvent event,
                      jvmtiEventMode mode);

  // Dispatch event to all registered environments.
  template <ArtJvmtiEvent kEvent, typename ...Args>
  ALWAYS_INLINE
  inline void DispatchEvent(art::Thread* thread, Args... args) const;
  // Dispatch event to all registered environments stashing exceptions as needed. This works since
  // JNIEnv* is always the second argument if it is passed to an event. Needed since C++ does not
  // allow partial template function specialization.
  template <ArtJvmtiEvent kEvent, typename ...Args>
  ALWAYS_INLINE
  void DispatchEvent(art::Thread* thread, JNIEnv* jnienv, Args... args) const;
  // Dispatch event to the given environment, only.
  template <ArtJvmtiEvent kEvent, typename ...Args>
  ALWAYS_INLINE
  inline void DispatchEvent(ArtJvmTiEnv* env, art::Thread* thread, Args... args) const;

  // Tell the event handler capabilities were added/lost so it can adjust the sent events.If
  // caps_added is true then caps is all the newly set capabilities of the jvmtiEnv. If it is false
  // then caps is the set of all capabilities that were removed from the jvmtiEnv.
  ALWAYS_INLINE
  inline void HandleChangedCapabilities(ArtJvmTiEnv* env,
                                        const jvmtiCapabilities& caps,
                                        bool added);

 private:
  template <ArtJvmtiEvent kEvent>
  ALWAYS_INLINE
  static inline bool ShouldDispatch(ArtJvmTiEnv* env, art::Thread* thread);

  ALWAYS_INLINE
  inline bool NeedsEventUpdate(ArtJvmTiEnv* env,
                               const jvmtiCapabilities& caps,
                               bool added);

  // Recalculates the event mask for the given event.
  ALWAYS_INLINE
  inline void RecalculateGlobalEventMask(ArtJvmtiEvent event);

  template <ArtJvmtiEvent kEvent>
  ALWAYS_INLINE inline void DispatchClassFileLoadHookEvent(art::Thread* thread,
                                                           JNIEnv* jnienv,
                                                           jclass class_being_redefined,
                                                           jobject loader,
                                                           const char* name,
                                                           jobject protection_domain,
                                                           jint class_data_len,
                                                           const unsigned char* class_data,
                                                           jint* new_class_data_len,
                                                           unsigned char** new_class_data) const;

  void HandleEventType(ArtJvmtiEvent event, bool enable);
  void HandleLocalAccessCapabilityAdded();

  // List of all JvmTiEnv objects that have been created, in their creation order.
  // NB Some elements might be null representing envs that have been deleted. They should be skipped
  // anytime this list is used.
  std::vector<ArtJvmTiEnv*> envs;

  // A union of all enabled events, anywhere.
  EventMask global_mask;

  std::unique_ptr<JvmtiAllocationListener> alloc_listener_;
  std::unique_ptr<JvmtiGcPauseListener> gc_pause_listener_;
  std::unique_ptr<JvmtiMethodTraceListener> method_trace_listener_;
};

}  // namespace openjdkjvmti

#endif  // ART_OPENJDKJVMTI_EVENTS_H_
