/*
 * Copyright (C) 2018 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 "arch/context.h"
#include "art_method-inl.h"
#include "jni.h"
#include "oat/oat_quick_method_header.h"
#include "scoped_thread_state_change-inl.h"
#include "stack.h"
#include "thread.h"

namespace art {

namespace {

// Visit a proxy method Quick frame at a given depth.
class GetProxyQuickFrameVisitor final : public StackVisitor {
 public:
  GetProxyQuickFrameVisitor(art::Thread* target, art::Context* ctx, size_t frame_depth)
      REQUIRES_SHARED(art::Locks::mutator_lock_)
      : art::StackVisitor(target, ctx, art::StackVisitor::StackWalkKind::kIncludeInlinedFrames),
        cur_depth_(0u),
        frame_depth_(frame_depth),
        quick_frame_(nullptr) {}

  bool VisitFrame() override REQUIRES_SHARED(Locks::mutator_lock_) {
    if (GetMethod()->IsRuntimeMethod()) {
      return true;
    }
    if (cur_depth_ == frame_depth_) {
      // Found frame.
      ShadowFrame* shadow_frame = GetCurrentShadowFrame();
      if (shadow_frame != nullptr) {
        // Nothing to do.
      } else {
        VisitQuickFrameAtSearchedDepth();
      }
      return false;
    } else {
      ++cur_depth_;
      return true;
    }
  }

  void VisitQuickFrameAtSearchedDepth() REQUIRES_SHARED(Locks::mutator_lock_) {
    quick_frame_ = GetCurrentQuickFrame();
    CHECK(quick_frame_ != nullptr);
    ArtMethod* method = *quick_frame_;
    CHECK(method != nullptr);
    CHECK(method->IsProxyMethod()) << method->PrettyMethod();
  }

  // Return the found Quick frame.
  ArtMethod** GetQuickFrame() {
    return quick_frame_;
  }

 private:
  // The depth of the currently visited frame.
  size_t cur_depth_;
  // The depth of the currently searched frame.
  size_t frame_depth_;
  // The quick frame, if found.
  ArtMethod** quick_frame_;
  // Method name

  DISALLOW_COPY_AND_ASSIGN(GetProxyQuickFrameVisitor);
};

extern "C" StackReference<mirror::Object>* artQuickGetProxyReferenceArgumentAt(size_t arg_pos,
                                                                               ArtMethod** sp)
    REQUIRES_SHARED(Locks::mutator_lock_);

jobject GetProxyReferenceArgument(size_t arg_pos, size_t proxy_method_frame_depth) {
  Thread* self = Thread::Current();
  ScopedObjectAccess soa(self);
  std::unique_ptr<Context> context(Context::Create());

  GetProxyQuickFrameVisitor visitor(self, context.get(), proxy_method_frame_depth);
  visitor.WalkStack();
  ArtMethod** quick_frame = visitor.GetQuickFrame();
  CHECK(quick_frame != nullptr);

  // Find reference argument in frame.
  StackReference<mirror::Object>* ref_arg =
      artQuickGetProxyReferenceArgumentAt(arg_pos, quick_frame);
  CHECK(ref_arg != nullptr);
  art::ObjPtr<mirror::Object> obj = ref_arg->AsMirrorPtr();

  return obj.IsNull() ? nullptr : soa.AddLocalReference<jobject>(obj);
}

extern "C" JNIEXPORT jobject JNICALL Java_TestInvocationHandler_getArgument(
    [[maybe_unused]] JNIEnv* env, [[maybe_unused]] jobject thiz, int arg_pos, int frame_depth) {
  return GetProxyReferenceArgument(arg_pos, frame_depth);
}

}  // namespace

}  // namespace art
