//===- ClasspathReflect.cpp - Internal representation of core system classes -//
//
//                            The VMKit project
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "ClasspathReflect.h"
#include "JavaArray.h"
#include "JavaClass.h"
#include "JavaConstantPool.h"
#include "JavaObject.h"
#include "JavaThread.h"
#include "JavaTypes.h"
#include "JavaUpcalls.h"
#include "Jnjvm.h"
#include "Reader.h"

#include "Reflect.inc"

namespace j3 {

JavaMethod* JavaObjectConstructor::getInternalMethod(JavaObjectConstructor* self) {
  llvm_gcroot(self, 0);
  UserCommonClass* cls = JavaObjectClass::getClass(self->clazz);
  return &(cls->asClass()->virtualMethods[self->slot]);
}

JavaMethod* JavaObjectMethod::getInternalMethod(JavaObjectMethod* self) {
  llvm_gcroot(self, 0);
  UserCommonClass* cls = JavaObjectClass::getClass(self->clazz);
  return &(cls->asClass()->virtualMethods[self->slot]);
}


int JavaObjectThrowable::getStackTraceBase(JavaObjectThrowable * self) {
  JavaObject * stack = NULL;
  llvm_gcroot(self, 0);
  llvm_gcroot(stack, 0);

  if (!self->backtrace) return 0;

  Jnjvm* vm = JavaThread::get()->getJVM();

  stack = self->backtrace;
  sint32 index = 2;;
  while (index != JavaArray::getSize(stack)) {
    vmkit::FrameInfo* FI = vm->IPToFrameInfo(ArrayPtr::getElement((ArrayPtr*)stack, index));
    if (FI->Metadata == NULL) ++index;
    else {
      JavaMethod* meth = (JavaMethod*)FI->Metadata;
      assert(meth && "Wrong stack trace");
      if (meth->classDef->isSubclassOf(vm->upcalls->newThrowable)) {
        ++index;
      } else return index;
    }
  }

  assert(0 && "Invalid stack trace!");
  return 0;
}

int JavaObjectThrowable::getStackTraceDepth(JavaObjectThrowable * self) {
  JavaObject * stack = NULL;
  llvm_gcroot(self, 0);
  llvm_gcroot(stack, 0);

  if (!self->backtrace) return 0;

  Jnjvm* vm = JavaThread::get()->getJVM();

  stack = self->backtrace;
  sint32 index = getStackTraceBase(self);

  sint32 size = 0;
  sint32 cur = index;
  while (cur < JavaArray::getSize(stack)) {
    vmkit::FrameInfo* FI = vm->IPToFrameInfo(ArrayPtr::getElement((ArrayPtr*)stack, cur));
    ++cur;
    if (FI->Metadata != NULL) ++size;
  }

  return size;
}

JavaObjectConstructor* JavaObjectConstructor::createFromInternalConstructor(JavaMethod * cons, int i) {
  JavaObjectConstructor* ret = 0;
  JavaObject* pArr = 0;
  JavaObject* eArr = 0;
  ArraySInt8* ann = 0;
  ArraySInt8* pmAnn = 0;
  llvm_gcroot(ret, 0);
  llvm_gcroot(pArr, 0);
  llvm_gcroot(eArr, 0);
  llvm_gcroot(ann, 0);
  llvm_gcroot(pmAnn, 0);

  Jnjvm* vm = JavaThread::get()->getJVM();
  JnjvmClassLoader * classLoader = cons->classDef->classLoader;

  UserClass* Cons = vm->upcalls->newConstructor;
  pArr = cons->getParameterTypes(classLoader);
  eArr = cons->getExceptionTypes(classLoader);
  ret = (JavaObjectConstructor*)Cons->doNew(vm);
  JavaObject* const* Cl = cons->classDef->getDelegateePtr();

  JavaString ** sig = getSignature(cons);
  ann = getAnnotations(cons);
  pmAnn = getParamAnnotations(cons);

  vm->upcalls->initConstructor->invokeIntSpecial(vm, Cons, ret,
    Cl,           /* declaringClass */
    &pArr,        /* parameterTypes */
    &eArr,        /* checkedExceptions */
    cons->access, /* modifiers */
    i,            /* slot */
    sig,          /* String signature */
    &ann,         /* annotations */
    &pmAnn        /* parameterAnnotations */
  );

  return ret;
}

JavaObjectMethod* JavaObjectMethod::createFromInternalMethod(JavaMethod* meth, int i) {
  JavaObjectMethod* ret = 0;
  JavaString* str = 0;
  JavaObject* pArr = 0;
  JavaObject* eArr = 0;
  JavaObject* retTy = 0;
  ArraySInt8* ann = 0;
  ArraySInt8* pmAnn = 0;
  ArraySInt8* defAnn = 0;
  llvm_gcroot(ret, 0);
  llvm_gcroot(str, 0);
  llvm_gcroot(pArr, 0);
  llvm_gcroot(eArr, 0);
  llvm_gcroot(retTy, 0);
  llvm_gcroot(ann, 0);
  llvm_gcroot(pmAnn, 0);
  llvm_gcroot(defAnn, 0);

  // TODO: check parameter types
  Jnjvm* vm = JavaThread::get()->getJVM();
  JnjvmClassLoader * classLoader = meth->classDef->classLoader;

  UserClass* Meth = vm->upcalls->newMethod;
  ret = (JavaObjectMethod*)Meth->doNew(vm);
  str = vm->internalUTF8ToStr(meth->name);
  pArr = meth->getParameterTypes(classLoader);
  eArr = meth->getExceptionTypes(classLoader);
  retTy = meth->getReturnType(classLoader);
  JavaString ** sig = getSignature(meth);
  ann = getAnnotations(meth);
  pmAnn = getParamAnnotations(meth);
  defAnn = getAnnotationDefault(meth);

  JavaObject* const* Cl = meth->classDef->getClassDelegateePtr(vm);
  vm->upcalls->initMethod->invokeIntSpecial(vm, Meth, ret,
    Cl,           /* declaring class */
    &str,         /* name */
    &pArr,        /* parameter types */
    &retTy,       /* return type */
    &eArr,        /* exceptions */
    meth->access, /* modifiers */
    i,            /* slot */
    sig,          /* signature */
    &ann,         /* annotations */
    &pmAnn,       /* parameter annotations */
    &defAnn);     /* default annotations */

  return ret;
}

JavaObjectField* JavaObjectField::createFromInternalField(JavaField* field, int i) {
  JavaObjectField* ret = 0;
  JavaString* name = 0;
  ArraySInt8* ann = 0;
  llvm_gcroot(ret, 0);
  llvm_gcroot(name, 0);
  llvm_gcroot(ann, 0);

  // TODO: check parameter types
  Jnjvm* vm = JavaThread::get()->getJVM();
  UserClass* Field = vm->upcalls->newField;
  ret = (JavaObjectField*)Field->doNew(vm);
  name = vm->internalUTF8ToStr(field->name);

  //type->Class
  JnjvmClassLoader* loader = field->classDef->classLoader;
  UserCommonClass * fieldCl = field->getSignature()->assocClass(loader);
  assert(fieldCl);
  JavaObject* const* type = fieldCl->getClassDelegateePtr(vm);
  JavaObject* const* Cl = field->classDef->getClassDelegateePtr(vm);

  JavaString** sig = getSignature(field);
  ann = getAnnotations(field);

  /* java.reflect.Field(
  *   Class declaringClass,
  *   String name,
  *   Class type,
  *   int modifiers,
  *   int slot,
  *   String signature,
  *   byte[] annotations)
  */
  vm->upcalls->initField->invokeIntSpecial(vm, Field, ret,
    Cl,
    &name,
    type,
    field->access,
    i,
    sig,
    &ann);

  return ret;
}

static inline JavaString** getSignatureString(JavaAttribute* sigAtt, Class* cl) {
  if (!sigAtt) return 0;

  Reader reader(sigAtt, cl->bytes);
  uint16 index = reader.readU2();

  return cl->classLoader->UTF8ToStr(cl->getConstantPool()->UTF8At(index));

}

JavaString** JavaObjectClass::getSignature(Class *cl) {
  JavaAttribute* sigAtt = cl->lookupAttribute(JavaAttribute::signatureAttribute);
  return getSignatureString(sigAtt, cl);
}

JavaString** JavaObjectField::getSignature(JavaField* field) {
  JavaAttribute* sigAtt = field->lookupAttribute(JavaAttribute::signatureAttribute);
  return getSignatureString(sigAtt, field->classDef);
}

JavaString** JavaObjectMethod::getSignature(JavaMethod* meth) {
  JavaAttribute* sigAtt = meth->lookupAttribute(JavaAttribute::signatureAttribute);
  return getSignatureString(sigAtt, meth->classDef);
}

JavaString** JavaObjectConstructor::getSignature(JavaMethod* cons) {
  JavaAttribute* sigAtt = cons->lookupAttribute(JavaAttribute::signatureAttribute);
  return getSignatureString(sigAtt, cons->classDef);
}

inline ArraySInt8* getAttrBytes(JavaAttribute* annotationsAtt, Class* cl) {
  ArraySInt8* ret = 0;
  llvm_gcroot(ret, 0);

  if (!annotationsAtt) return 0;

  JavaThread* th = JavaThread::get();
  Jnjvm* vm = th->getJVM();

  uint32 len = annotationsAtt->nbb;
  ret = (ArraySInt8*)vm->upcalls->ArrayOfByte->doNew(len, vm);

  Reader reader(annotationsAtt, cl->bytes);
  for(uint32 i = 0; i < len; ++i) {
    ArraySInt8::setElement(ret, reader.readS1(), i);
  }

  return ret;
}

ArraySInt8* JavaObjectClass::getAnnotations(Class *cl) {
  JavaAttribute* attr =
    cl->lookupAttribute(JavaAttribute::annotationsAttribute);

  return getAttrBytes(attr, cl);
}

ArraySInt8* JavaObjectField::getAnnotations(JavaField *field) {
  JavaAttribute* attr =
    field->lookupAttribute(JavaAttribute::annotationsAttribute);

  return getAttrBytes(attr, field->classDef);
}

ArraySInt8* JavaObjectMethod::getAnnotations(JavaMethod *meth) {
  JavaAttribute* attr =
    meth->lookupAttribute(JavaAttribute::annotationsAttribute);

  return getAttrBytes(attr, meth->classDef);
}
ArraySInt8* JavaObjectMethod::getParamAnnotations(JavaMethod *meth) {
  JavaAttribute* attr =
    meth->lookupAttribute(JavaAttribute::paramAnnotationsAttribute);

  return getAttrBytes(attr, meth->classDef);
}
ArraySInt8* JavaObjectMethod::getAnnotationDefault(JavaMethod *meth) {
  JavaAttribute* attr =
    meth->lookupAttribute(JavaAttribute::annotationDefaultAttribute);

  return getAttrBytes(attr, meth->classDef);
}

ArraySInt8* JavaObjectConstructor::getAnnotations(JavaMethod *cons) {
  JavaAttribute* attr =
    cons->lookupAttribute(JavaAttribute::annotationsAttribute);

  return getAttrBytes(attr, cons->classDef);
}
ArraySInt8* JavaObjectConstructor::getParamAnnotations(JavaMethod *cons) {
  JavaAttribute* attr =
    cons->lookupAttribute(JavaAttribute::paramAnnotationsAttribute);

  return getAttrBytes(attr, cons->classDef);
}

} // end namespace j3
