/*
 * 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.
 */

#include "java_lang_reflect_Parameter.h"

#include "android-base/stringprintf.h"
#include "nativehelper/jni_macros.h"

#include "art_method-inl.h"
#include "base/utils.h"
#include "common_throws.h"
#include "dex/dex_file-inl.h"
#include "dex/dex_file_annotations.h"
#include "jni/jni_internal.h"
#include "native_util.h"
#include "scoped_fast_native_object_access-inl.h"

namespace art HIDDEN {

using android::base::StringPrintf;

static jobject Parameter_getAnnotationNative(JNIEnv* env,
                                             jclass,
                                             jobject javaMethod,
                                             jint parameterIndex,
                                             jclass annotationType) {
  ScopedFastNativeObjectAccess soa(env);
  if (UNLIKELY(javaMethod == nullptr)) {
    ThrowNullPointerException("javaMethod == null");
    return nullptr;
  }

  ArtMethod* method = ArtMethod::FromReflectedMethod(soa, javaMethod);
  if (method->IsProxyMethod()) {
    return nullptr;
  }

  uint32_t parameter_count = method->GetParameterTypeList()->Size();
  if (UNLIKELY(parameterIndex < 0 || static_cast<uint32_t>(parameterIndex) >= parameter_count)) {
    ThrowIllegalArgumentException(
        StringPrintf("Illegal parameterIndex %d for %s, parameter_count is %d",
                     parameterIndex,
                     method->PrettyMethod().c_str(),
                     parameter_count).c_str());
    return nullptr;
  }

  uint32_t annotated_parameter_count = annotations::GetNumberOfAnnotatedMethodParameters(method);
  if (annotated_parameter_count == 0u) {
    return nullptr;
  }

  // For constructors with implicit arguments, we may need to adjust
  // annotation positions based on whether the implicit parameters are
  // expected to known and not just a compiler implementation detail.
  if (method->IsConstructor()) {
    StackHandleScope<1> hs(soa.Self());
    // If declaring class is a local or an enum, do not pad parameter
    // annotations, as the implicit constructor parameters are an
    // implementation detail rather than required by JLS.
    Handle<mirror::Class> declaring_class = hs.NewHandle(method->GetDeclaringClass());
    if (annotations::GetEnclosingMethod(declaring_class) == nullptr && !declaring_class->IsEnum()) {
      // Adjust the parameter index if the number of annotations does
      // not match the number of parameters.
      if (annotated_parameter_count <= parameter_count) {
        // Workaround for dexer not inserting annotation state for implicit parameters (b/68033708).
        uint32_t skip_count = parameter_count - annotated_parameter_count;
        DCHECK_GE(2u, skip_count);
        if (parameterIndex < static_cast<jint>(skip_count)) {
          return nullptr;
        }
        parameterIndex -= skip_count;
      } else {
        // Workaround for Jack erroneously inserting implicit parameter for local classes
        // (b/68033708).
        DCHECK_EQ(1u, annotated_parameter_count - parameter_count);
        parameterIndex += static_cast<jint>(annotated_parameter_count - parameter_count);
      }
    }
  }

  StackHandleScope<1> hs(soa.Self());
  Handle<mirror::Class> klass(hs.NewHandle(soa.Decode<mirror::Class>(annotationType)));
  return soa.AddLocalReference<jobject>(
      annotations::GetAnnotationForMethodParameter(method, parameterIndex, klass));
}

static JNINativeMethod gMethods[] = {
  FAST_NATIVE_METHOD(
      Parameter,
      getAnnotationNative,
      "(Ljava/lang/reflect/Executable;ILjava/lang/Class;)Ljava/lang/annotation/Annotation;"),
};

void register_java_lang_reflect_Parameter(JNIEnv* env) {
  REGISTER_NATIVE_METHODS("java/lang/reflect/Parameter");
}

}  // namespace art
