//===---- ClasspathVMClass.cpp - GNU classpath java/lang/VMClass ----------===//
//
//                              JnJVM
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "types.h"

#include "Classpath.h"
#include "ClasspathReflect.h"
#include "JavaAccess.h"
#include "JavaArray.h"
#include "JavaClass.h"
#include "JavaObject.h"
#include "JavaString.h"
#include "JavaTypes.h"
#include "JavaThread.h"
#include "JavaUpcalls.h"
#include "Jnjvm.h"

using namespace jnjvm;

extern "C" {

// Never throws
JNIEXPORT jboolean JNICALL Java_java_lang_VMClass_isArray(
#ifdef NATIVE_JNI
JNIEnv *env,
jclass clazz,
#endif
JavaObjectClass* klass) {

  llvm_gcroot(klass, 0);

  UserCommonClass* cl = klass->getClass();

  return cl->isArray();
  
}

JNIEXPORT JavaObject* JNICALL Java_java_lang_VMClass_forName(
#ifdef NATIVE_JNI
JNIEnv *env,
jclass clazz,
#endif
JavaString* str, 
jboolean clinit, 
JavaObject* loader) {

  JavaObject* res = 0;
  llvm_gcroot(loader, 0);
  llvm_gcroot(str, 0);
  llvm_gcroot(res, 0);

  BEGIN_NATIVE_EXCEPTION(0)

  verifyNull(str);
  Jnjvm* vm = JavaThread::get()->getJVM(); 
  JnjvmClassLoader* JCL = 
    JnjvmClassLoader::getJnjvmLoaderFromJavaObject(loader, vm);
  UserCommonClass* cl = JCL->loadClassFromJavaString(str, true, false);

  if (cl != 0) {
    if (clinit && cl->asClass()) {
      cl->asClass()->initialiseClass(vm);
    }
    res =cl->getClassDelegatee(vm);
  } else {
    vm->classNotFoundException(str);
  }

  END_NATIVE_EXCEPTION

  return res;
}

JNIEXPORT JavaObject* JNICALL Java_java_lang_VMClass_getDeclaredConstructors(
#ifdef NATIVE_JNI
JNIEnv *env,
jclass clazz,
#endif
JavaObject* Cl, 
jboolean publicOnly) {

  ArrayObject* ret = 0;
  JavaObject* tmp = 0;
  llvm_gcroot(Cl, 0);
  llvm_gcroot(ret, 0);
  llvm_gcroot(tmp, 0);

  BEGIN_NATIVE_EXCEPTION(0)

  Jnjvm* vm = JavaThread::get()->getJVM();
  UserCommonClass* cl = UserCommonClass::resolvedImplClass(vm, Cl, false);

  if (cl->isArray() || cl->isInterface() || cl->isPrimitive()) {
    ret = (ArrayObject*)vm->upcalls->constructorArrayClass->doNew(0, vm);
  } else {
    UserClass* realCl = cl->asClass();;
    JnjvmClassLoader* classLoader = cl->classLoader;
    uint32 size = 0;
    
    for (uint32 i = 0; i < realCl->nbVirtualMethods; ++i) {
      JavaMethod* meth = &realCl->virtualMethods[i];
      bool pub = isPublic(meth->access);
      if (meth->name->equals(classLoader->bootstrapLoader->initName) && 
          (!publicOnly || pub)) {
        ++size;
      }
    }
  
    ret = (ArrayObject*)vm->upcalls->constructorArrayClass->doNew(size, vm);

    sint32 index = 0;
    for (uint32 i = 0; i < realCl->nbVirtualMethods; ++i) {
      JavaMethod* meth = &realCl->virtualMethods[i];
      bool pub = isPublic(meth->access);
      if (meth->name->equals(classLoader->bootstrapLoader->initName) && 
          (!publicOnly || pub)) {
        UserClass* Cons = vm->upcalls->newConstructor;
        tmp = Cons->doNew(vm);
        vm->upcalls->initConstructor->invokeIntSpecial(vm, Cons, tmp, Cl, i);
        ret->elements[index++] = tmp;
      }
    }
  }

  END_NATIVE_EXCEPTION

  return ret;
}

JNIEXPORT JavaObject* JNICALL Java_java_lang_VMClass_getDeclaredMethods(
#ifdef NATIVE_JNI
JNIEnv *env,
jclass clazz,
#endif
JavaObject* Cl, 
jboolean publicOnly) {

  ArrayObject* ret = 0;
  JavaObject* tmp = 0;
  JavaString* str = 0;
  llvm_gcroot(Cl, 0);
  llvm_gcroot(ret, 0);
  llvm_gcroot(tmp, 0);
  llvm_gcroot(str, 0);

  BEGIN_NATIVE_EXCEPTION(0)

  Jnjvm* vm = JavaThread::get()->getJVM();
  UserCommonClass* cl = UserCommonClass::resolvedImplClass(vm, Cl, false);
  Classpath* upcalls = vm->upcalls;

  if (cl->isArray() || cl->isPrimitive()) {
    ret = (ArrayObject*)upcalls->methodArrayClass->doNew(0, vm);
  } else {
    UserClass* realCl = cl->asClass();
    JnjvmClassLoader* classLoader = cl->classLoader;
    uint32 size = 0;

    for (uint32 i = 0; i < realCl->nbVirtualMethods + realCl->nbStaticMethods;
         ++i) {
      JavaMethod* meth = &realCl->virtualMethods[i];
      bool pub = isPublic(meth->access);
      if (!(meth->name->equals(classLoader->bootstrapLoader->initName)) && 
          (!publicOnly || pub)) {
        ++size; 
      }
    }

    
    ret = (ArrayObject*)upcalls->methodArrayClass->doNew(size, vm);

    sint32 index = 0;
    for (uint32 i = 0; i < realCl->nbVirtualMethods + realCl->nbStaticMethods;
         ++i) {
      JavaMethod* meth = &realCl->virtualMethods[i];
      bool pub = isPublic(meth->access);
      if (!(meth->name->equals(classLoader->bootstrapLoader->initName)) && 
          (!publicOnly || pub)) {
        // TODO: check parameter types
        UserClass* Meth = vm->upcalls->newMethod;
        tmp = Meth->doNew(vm);
        str = vm->internalUTF8ToStr(meth->name);
        upcalls->initMethod->invokeIntSpecial(vm, Meth, tmp, Cl, str, i);
        ret->elements[index++] = tmp;
      }
    }
  }

  END_NATIVE_EXCEPTION

  return ret;
}

JNIEXPORT jint JNICALL Java_java_lang_VMClass_getModifiers(
#ifdef NATIVE_JNI
JNIEnv *env,
jclass clazz,
#endif
JavaObject* Cl, 
jboolean ignore) {
  
  jint res = 0;
  llvm_gcroot(Cl, 0);

  BEGIN_NATIVE_EXCEPTION(0)

  Jnjvm* vm = JavaThread::get()->getJVM();
  UserCommonClass* cl = UserCommonClass::resolvedImplClass(vm, Cl, false);
  res = cl->getAccess();

  END_NATIVE_EXCEPTION
  return res;
}

JNIEXPORT JavaObject* JNICALL Java_java_lang_VMClass_getName(
#ifdef NATIVE_JNI
JNIEnv *env,
jclass clazz, 
#endif
JavaObject* Cl) {

  JavaObject* result = 0;
  llvm_gcroot(Cl, 0);
  llvm_gcroot(result, 0);

  BEGIN_NATIVE_EXCEPTION(0)

  Jnjvm* vm = JavaThread::get()->getJVM();
  UserCommonClass* cl = UserCommonClass::resolvedImplClass(vm, Cl, false);
  
  const UTF8* iname = cl->getName();
  result = JavaString::internalToJava(iname, vm);

  END_NATIVE_EXCEPTION

  return result;
}

JNIEXPORT jboolean JNICALL Java_java_lang_VMClass_isPrimitive(
#ifdef NATIVE_JNI
JNIEnv *env,
jclass clazz, 
#endif
JavaObject* Cl) {
 
  jboolean res = 0;
  llvm_gcroot(Cl, 0);

  BEGIN_NATIVE_EXCEPTION(0)
  
  Jnjvm* vm = JavaThread::get()->getJVM();
  UserCommonClass* cl = UserCommonClass::resolvedImplClass(vm, Cl, false);
  
  res = cl->isPrimitive();

  END_NATIVE_EXCEPTION

  return res;
}

JNIEXPORT jboolean JNICALL Java_java_lang_VMClass_isInterface(
#ifdef NATIVE_JNI
JNIEnv *env,
jclass clazz, 
#endif
JavaObject* Cl) {

  jboolean res = 0;
  llvm_gcroot(Cl, 0);

  BEGIN_NATIVE_EXCEPTION(0)

  Jnjvm* vm = JavaThread::get()->getJVM();
  UserCommonClass* cl = UserCommonClass::resolvedImplClass(vm, Cl, false);

  res = cl->isInterface();

  END_NATIVE_EXCEPTION

  return res;
}

JNIEXPORT JavaObject* JNICALL Java_java_lang_VMClass_getComponentType(
#ifdef NATIVE_JNI
JNIEnv *env,
jclass clazz, 
#endif
JavaObject* Cl) {
  
  JavaObject* res = 0;
  llvm_gcroot(res, 0);
  llvm_gcroot(Cl, 0);

  
  BEGIN_NATIVE_EXCEPTION(0)

  Jnjvm* vm = JavaThread::get()->getJVM();
  UserCommonClass* cl = UserCommonClass::resolvedImplClass(vm, Cl, false);

  if (cl->isArray()) {
    UserCommonClass* bc = cl->asArrayClass()->baseClass();
    res = bc->getClassDelegatee(vm);
  } else {
    res = 0;
  }

  END_NATIVE_EXCEPTION
  return res;
}

JNIEXPORT JavaObject* JNICALL Java_java_lang_VMClass_getClassLoader(
#ifdef NATIVE_JNI
JNIEnv *env,
jclass clazz, 
#endif
JavaObject* Cl) {

  JavaObject* res = 0;
  llvm_gcroot(res, 0);
  llvm_gcroot(Cl, 0);

  BEGIN_NATIVE_EXCEPTION(0)

  Jnjvm* vm = JavaThread::get()->getJVM();
  UserCommonClass* cl = UserCommonClass::resolvedImplClass(vm, Cl, false);
  res = cl->classLoader->getJavaClassLoader();

  END_NATIVE_EXCEPTION

  return res;
}

JNIEXPORT jboolean JNICALL Java_java_lang_VMClass_isAssignableFrom(
#ifdef NATIVE_JNI
JNIEnv *env,
jclass clazz, 
#endif
JavaObject* Cl1, JavaObject* Cl2) {
  
  jboolean res = 0;
  llvm_gcroot(Cl1, 0);
  llvm_gcroot(Cl2, 0);
  
  BEGIN_NATIVE_EXCEPTION(0)

  Jnjvm* vm = JavaThread::get()->getJVM();
  if (!Cl2) vm->nullPointerException();

  UserCommonClass* cl1 = UserCommonClass::resolvedImplClass(vm, Cl1, false);
  UserCommonClass* cl2 = UserCommonClass::resolvedImplClass(vm, Cl2, false);

  res = cl2->isAssignableFrom(cl1);

  END_NATIVE_EXCEPTION

  return res;

}

JNIEXPORT JavaObject* JNICALL Java_java_lang_VMClass_getSuperclass(
#ifdef NATIVE_JNI
JNIEnv *env,
jclass clazz, 
#endif
JavaObject* Cl) {

  JavaObject* res = 0;
  llvm_gcroot(Cl, 0);
  llvm_gcroot(res, 0);

  BEGIN_NATIVE_EXCEPTION(0)

  Jnjvm* vm = JavaThread::get()->getJVM();
  UserCommonClass* cl = UserCommonClass::resolvedImplClass(vm, Cl, false);
  if (cl->isInterface()) res = 0;
  else {
    if (cl->getSuper()) res = cl->getSuper()->getClassDelegatee(vm);
    else res = 0;
  }

  END_NATIVE_EXCEPTION
  
  return res;
}

JNIEXPORT bool JNICALL Java_java_lang_VMClass_isInstance(
#ifdef NATIVE_JNI
JNIEnv *env,
jclass clazz, 
#endif
JavaObject* Cl, JavaObject* obj) {

  bool res = false;
  llvm_gcroot(Cl, 0);
  llvm_gcroot(obj, 0);

  BEGIN_NATIVE_EXCEPTION(0)

  Jnjvm* vm = JavaThread::get()->getJVM();
  UserCommonClass* cl = UserCommonClass::resolvedImplClass(vm, Cl, false);
  res = obj->instanceOf(cl);

  END_NATIVE_EXCEPTION

  return res;
}

JNIEXPORT JavaObject* JNICALL Java_java_lang_VMClass_getDeclaredFields(
#ifdef NATIVE_JNI
JNIEnv *env,
jclass clazz, 
#endif
JavaObject* Cl, jboolean publicOnly) {

  ArrayObject* ret = 0;
  JavaObject* tmp = 0;
  JavaString* name = 0;
  llvm_gcroot(Cl, 0);
  llvm_gcroot(ret, 0);
  llvm_gcroot(tmp, 0);
  llvm_gcroot(name, 0);

  BEGIN_NATIVE_EXCEPTION(0)

  Jnjvm* vm = JavaThread::get()->getJVM();
  UserCommonClass* cl = UserCommonClass::resolvedImplClass(vm, Cl, false);

  if (!cl->isClass()) {
    ret = (ArrayObject*)vm->upcalls->fieldArrayClass->doNew(0, vm);
  } else {
    UserClass* realCl = cl->asClass(); 
    uint32 size = 0;
    for (uint32 i = 0; i < realCl->nbVirtualFields + realCl->nbStaticFields;
         ++i) {
      JavaField* field = &realCl->virtualFields[i];
      if (!publicOnly || isPublic(field->access)) {
        ++size;
      }
    }


    ret = (ArrayObject*)vm->upcalls->fieldArrayClass->doNew(size, vm);

    sint32 index = 0;
    for (uint32 i = 0; i < realCl->nbVirtualFields + realCl->nbStaticFields;
         ++i) {
      JavaField* field = &realCl->virtualFields[i];
      if (!publicOnly || isPublic(field->access)) {
        // TODO: check parameter types
        UserClass* Field = vm->upcalls->newField;
        tmp = Field->doNew(vm);
        name = vm->internalUTF8ToStr(field->name);
        vm->upcalls->initField->invokeIntSpecial(vm, Field, tmp, Cl, name, i);
        ret->elements[index++] = tmp;
      }
    }
  }

  END_NATIVE_EXCEPTION

  return ret;
}

JNIEXPORT JavaObject* JNICALL Java_java_lang_VMClass_getInterfaces(
#ifdef NATIVE_JNI
JNIEnv *env,
jclass clazz, 
#endif
JavaObject* Cl) {

  ArrayObject* res = 0;
  llvm_gcroot(res, 0);
  llvm_gcroot(Cl, 0);

  BEGIN_NATIVE_EXCEPTION(0)

  Jnjvm* vm = JavaThread::get()->getJVM();
  UserCommonClass* cl = UserCommonClass::resolvedImplClass(vm, Cl, false);
  res = (ArrayObject*)vm->upcalls->classArrayClass->doNew(cl->nbInterfaces, vm);

  for (uint16 i = 0; i < cl->nbInterfaces; ++i) {
    UserClass* klass = cl->interfaces[i];
    res->elements[i] = klass->getClassDelegatee(vm);
  }

  END_NATIVE_EXCEPTION

  return res;
}


JNIEXPORT JavaObject* JNICALL Java_java_lang_VMClass_getDeclaringClass(
#ifdef NATIVE_JNI
JNIEnv *env,
jclass clazz, 
#endif
JavaObject* Cl) {
  JavaObject* res = 0;

  llvm_gcroot(res, 0);
  llvm_gcroot(Cl, 0);

  BEGIN_NATIVE_EXCEPTION(0)

  Jnjvm* vm = JavaThread::get()->getJVM();
  UserClass* cl = UserCommonClass::resolvedImplClass(vm, Cl, false)->asClass();

  if (cl) {
    cl->resolveInnerOuterClasses();
    UserClass* outer = cl->getOuterClass();
    if (outer) {
      res = outer->getClassDelegatee(vm);
    }
  }

  END_NATIVE_EXCEPTION

  return res;

}

JNIEXPORT JavaObject* JNICALL Java_java_lang_VMClass_getDeclaredClasses(
#ifdef NATIVE_JNI
JNIEnv *env,
jclass clazz, 
#endif
JavaObject* Cl, bool publicOnly) {


  ArrayObject* result = 0;
  llvm_gcroot(result, 0);
  llvm_gcroot(Cl, 0);

  BEGIN_NATIVE_EXCEPTION(0)

  Jnjvm* vm = JavaThread::get()->getJVM();
  UserClass* cl = UserCommonClass::resolvedImplClass(vm, Cl, false)->asClass();
  if (cl) {
    cl->resolveInnerOuterClasses();
    UserClassArray* array = vm->upcalls->constructorArrayClass;
    
    uint16 sizeArray = 0;

    if (publicOnly) {
      for (uint16 i = 0; i < cl->nbInnerClasses; ++i) {
        UserClass* klass = cl->innerClasses[i];
        if (isPublic(klass->innerAccess)) ++sizeArray;
      }
    } else {
      sizeArray = cl->nbInnerClasses;
    }

    result = (ArrayObject*)array->doNew(sizeArray, vm);
    for (uint16 i = 0; i < cl->nbInnerClasses; ++i) {
      UserClass* klass = cl->innerClasses[i];
      if (!publicOnly || isPublic(klass->innerAccess))
        result->elements[i] = klass->getClassDelegatee(vm); 
    }
  }
  

  END_NATIVE_EXCEPTION

  return result;

}

// Only throws.
JNIEXPORT void JNICALL Java_java_lang_VMClass_throwException(
#ifdef NATIVE_JNI
JNIEnv *env,
jclass clazz, 
#endif
JavaObject* throwable) {
  
  llvm_gcroot(throwable, 0);

  assert(throwable && "Using internal VM throw exception without exception");
  JavaThread::get()->pendingException = (JavaObject*)throwable;
}

JNIEXPORT ArrayObject* Java_java_lang_VMClass_getDeclaredAnnotations(
#ifdef NATIVE_JNI
JNIEnv *env,
jclass clazz, 
#endif
JavaObject* Cl) {
  // TODO implement me
  
  ArrayObject* res = 0;
  llvm_gcroot(res, 0);
  llvm_gcroot(Cl, 0);
  
  BEGIN_NATIVE_EXCEPTION(0)

  Jnjvm* vm = JavaThread::get()->getJVM();
  UserClassArray* array = vm->upcalls->constructorArrayAnnotation;
  res = (ArrayObject*)array->doNew(0, vm);

  END_NATIVE_EXCEPTION

  return res;
}

JNIEXPORT jboolean Java_java_lang_VMClass_isAnonymousClass(
#ifdef NATIVE_JNI
JNIEnv *env,
jclass clazz, 
#endif
JavaObject* Cl) {
 
  jboolean res = false;
  llvm_gcroot(Cl, 0);

  BEGIN_NATIVE_EXCEPTION(0)
  
  Jnjvm* vm = JavaThread::get()->getJVM();
  UserClass* cl = UserCommonClass::resolvedImplClass(vm, Cl, false)->asClass();

  if (cl) res = cl->isAnonymous;

  END_NATIVE_EXCEPTION

  return res;
}


}
