/*
 * Copyright (C) 2019 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_RUNTIME_REFLECTIVE_VALUE_VISITOR_H_
#define ART_RUNTIME_REFLECTIVE_VALUE_VISITOR_H_

#include <android-base/logging.h>

#include <array>
#include <compare>
#include <functional>
#include <stack>

#include "android-base/macros.h"
#include "base/enums.h"
#include "base/globals.h"
#include "base/locks.h"
#include "base/macros.h"
#include "base/value_object.h"
#include "dex/dex_file.h"
#include "jni.h"
#include "mirror/dex_cache.h"
#include "obj_ptr.h"

namespace art {

class ArtField;
class ArtMethod;
class BaseReflectiveHandleScope;
class Thread;

class ReflectionSourceInfo;

class ReflectiveValueVisitor : public ValueObject {
 public:
  virtual ~ReflectiveValueVisitor() {}

  virtual ArtMethod* VisitMethod(ArtMethod* in, const ReflectionSourceInfo& info)
      REQUIRES_SHARED(Locks::mutator_lock_) = 0;
  virtual ArtField* VisitField(ArtField* in, const ReflectionSourceInfo& info)
      REQUIRES_SHARED(Locks::mutator_lock_) = 0;

  // Give it an entrypoint through operator() to interact with things that expect lambda-like things
  template <typename T,
            typename = typename std::enable_if<std::is_same_v<T, ArtField> ||
                                               std::is_same_v<T, ArtMethod>>>
  T* operator()(T* t, const ReflectionSourceInfo& info) REQUIRES_SHARED(Locks::mutator_lock_) {
    if constexpr (std::is_same_v<T, ArtField>) {
      return VisitField(t, info);
    } else {
      static_assert(std::is_same_v<T, ArtMethod>, "Expected ArtField or ArtMethod");
      return VisitMethod(t, info);
    }
  }
};

template <typename FieldVis, typename MethodVis>
class FunctionReflectiveValueVisitor : public ReflectiveValueVisitor {
 public:
  FunctionReflectiveValueVisitor(FieldVis fv, MethodVis mv) : fv_(fv), mv_(mv) {}
  ArtField* VisitField(ArtField* in, const ReflectionSourceInfo& info) override
      REQUIRES(Locks::mutator_lock_) {
    return fv_(in, info);
  }
  ArtMethod* VisitMethod(ArtMethod* in, const ReflectionSourceInfo& info) override
      REQUIRES(Locks::mutator_lock_) {
    return mv_(in, info);
  }

 private:
  FieldVis fv_;
  MethodVis mv_;
};

enum ReflectionSourceType {
  kSourceUnknown = 0,
  kSourceJavaLangReflectExecutable,
  kSourceJavaLangReflectField,
  kSourceJavaLangInvokeMethodHandle,
  kSourceJavaLangInvokeFieldVarHandle,
  kSourceThreadHandleScope,
  kSourceJniFieldId,
  kSourceJniMethodId,
  kSourceDexCacheResolvedMethod,
  kSourceDexCacheResolvedField,
  kSourceMiscInternal,
};
std::ostream& operator<<(std::ostream& os, ReflectionSourceType type);

class ReflectionSourceInfo : public ValueObject {
 public:
  virtual ~ReflectionSourceInfo() {}
  // Thread id 0 is for non thread roots.
  explicit ReflectionSourceInfo(ReflectionSourceType type) : type_(type) {}
  virtual void Describe(std::ostream& os) const {
    os << "Type=" << type_;
  }

  ReflectionSourceType GetType() const {
    return type_;
  }

 private:
  const ReflectionSourceType type_;

  DISALLOW_COPY_AND_ASSIGN(ReflectionSourceInfo);
};
inline std::ostream& operator<<(std::ostream& os, const ReflectionSourceInfo& info) {
  info.Describe(os);
  return os;
}

class ReflectiveHandleScopeSourceInfo : public ReflectionSourceInfo {
 public:
  explicit ReflectiveHandleScopeSourceInfo(BaseReflectiveHandleScope* source)
      : ReflectionSourceInfo(kSourceThreadHandleScope), source_(source) {}

  void Describe(std::ostream& os) const override;

 private:
  BaseReflectiveHandleScope* source_;
};

// TODO Maybe give this the ability to retrieve the type and ref, if it's useful.
class HeapReflectiveSourceInfo : public ReflectionSourceInfo {
 public:
  HeapReflectiveSourceInfo(ReflectionSourceType t, mirror::Object* src)
      : ReflectionSourceInfo(t), src_(src) {}
  void Describe(std::ostream& os) const override;

 private:
  ObjPtr<mirror::Object> src_;
};

// TODO Maybe give this the ability to retrieve the id if it's useful.
template <typename T,
          typename = typename std::enable_if_t<std::is_same_v<T, jmethodID> ||
                                               std::is_same_v<T, jfieldID>>>
class JniIdReflectiveSourceInfo : public ReflectionSourceInfo {
 public:
  explicit JniIdReflectiveSourceInfo(T id)
      : ReflectionSourceInfo(std::is_same_v<T, jmethodID> ? kSourceJniMethodId : kSourceJniFieldId),
        id_(id) {}
  void Describe(std::ostream& os) const override;

 private:
  T id_;
};

class DexCacheSourceInfo : public ReflectionSourceInfo {
 public:
  explicit DexCacheSourceInfo(ReflectionSourceType type,
                              size_t index,
                              ObjPtr<mirror::DexCache> cache)
      : ReflectionSourceInfo(type), index_(index), cache_(cache) {}

  void Describe(std::ostream& os) const override REQUIRES(Locks::mutator_lock_) {
    ReflectionSourceInfo::Describe(os);
    os << " index=" << index_ << " cache_=" << cache_.PtrUnchecked()
       << " files=" << *cache_->GetDexFile();
  }

 private:
  size_t index_;
  ObjPtr<mirror::DexCache> cache_;
};
}  // namespace art

#endif  // ART_RUNTIME_REFLECTIVE_VALUE_VISITOR_H_
