/*
 * 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_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(
    JNIEnv* env ATTRIBUTE_UNUSED, jobject thiz ATTRIBUTE_UNUSED, int arg_pos, int frame_depth) {
  return GetProxyReferenceArgument(arg_pos, frame_depth);
}

}  // namespace

}  // namespace art
