#include "runtime.h"
#include <stdlib.h>
#include <string.h>

jint llvm_java_is_primitive_class(struct llvm_java_class_record* cr)
{
  return cr->typeinfo.elementSize == -2;
}

jint llvm_java_is_interface_class(struct llvm_java_class_record* cr)
{
  return cr->typeinfo.elementSize == -1;
}

jint llvm_java_is_array_class(struct llvm_java_class_record* cr)
{
  return cr->typeinfo.elementSize > 0;
}

struct llvm_java_class_record* llvm_java_get_class_record(jobject obj) {
  return obj->classRecord;
}

void llvm_java_set_class_record(jobject obj,
                                struct llvm_java_class_record* cr) {
  obj->classRecord = cr;
}

struct llvm_java_class_record*
llvm_java_get_superclass_record(struct llvm_java_class_record* cr) {
  /* If this is an interface or java/lang/Object return NULL. */
  if (llvm_java_is_interface_class(cr) || cr->typeinfo.depth == 0)
    return NULL;

  return cr->typeinfo.superclasses[cr->typeinfo.depth - 1];
}

jboolean llvm_java_is_assignable_from(struct llvm_java_class_record* cr,
                                      struct llvm_java_class_record* from) {
  /* trivial case: class records are the same */
  if (cr == from)
    return JNI_TRUE;

  /* if from is a primitive class then they must be of the same class */
  if (llvm_java_is_primitive_class(from))
    return cr == from;

  /* if from is an interface class then the current class must
   * implement that interface */
  if (llvm_java_is_interface_class(from)) {
    int index = from->typeinfo.interfaceIndex;
    return (cr->typeinfo.interfaceIndex >= index &&
            cr->typeinfo.interfaces[index]);
  }

  /* if from is an array class then the component types of must be
   * assignable from */
  if (llvm_java_is_array_class(from))
    return (cr->typeinfo.component &&
            llvm_java_is_assignable_from(cr->typeinfo.component,
                                         from->typeinfo.component));

  /* otherwise this is a class, check if from is a superclass of this
   * class */
  if (cr->typeinfo.depth > from->typeinfo.depth) {
    int index = from->typeinfo.depth;
    return cr->typeinfo.superclasses[index] == from;
  }

  return JNI_FALSE;
}

jboolean llvm_java_is_instance_of(jobject obj,
                                  struct llvm_java_class_record* cr) {
  /* trivial case: a null object can be cast to any type */
  if (!obj)
    return JNI_TRUE;

  return llvm_java_is_assignable_from(obj->classRecord, cr);
}

jint llvm_java_throw(jthrowable obj) {
  abort();
}

extern struct llvm_java_class_record* llvm_java_class_records;

struct llvm_java_class_record*
llvm_java_find_class_record(const char* name) {
  struct llvm_java_class_record** cr = &llvm_java_class_records;
  for (; *cr; ++cr)
    if (strcmp((*cr)->typeinfo.name, name) == 0)
      return *cr;

  return NULL;
}

void Java_java_lang_VMSystem_arraycopy(JNIEnv *env, jobject clazz,
                                       jobject srcObj, jint srcStart,
                                       jobject dstObj, jint dstStart,
                                       jint length) {
  struct llvm_java_bytearray* srcArray = (struct llvm_java_bytearray*) srcObj;
  struct llvm_java_bytearray* dstArray = (struct llvm_java_bytearray*) dstObj;
  unsigned nbytes = length * srcObj->classRecord->typeinfo.elementSize;

  jbyte* src = srcArray->data;
  jbyte* dst = dstArray->data;

  // FIXME: Need to perform a proper type check here.
  if (srcObj->classRecord->typeinfo.elementSize !=
      dstObj->classRecord->typeinfo.elementSize)
    llvm_java_throw(NULL);

  src += srcStart * srcObj->classRecord->typeinfo.elementSize;
  dst += dstStart * dstObj->classRecord->typeinfo.elementSize;

  memmove(dst, src, nbytes);
}

void Java_gnu_classpath_VMSystemProperties_preInit(JNIEnv *env, jobject clazz,
                                                   jobject properties) {

}

typedef void (*ClassInitializerFunction)(void);

extern const ClassInitializerFunction llvm_java_class_initializers;

extern void llvm_java_main(int, char**);

int main(int argc, char** argv) {
  const ClassInitializerFunction* classInit = &llvm_java_class_initializers;
  for (; *classInit; ++classInit)
    (*classInit)();

  llvm_java_main(argc, argv);
  return 0;
}
