//===------------- MSCorlib.cpp - mscorlib interface ----------------------===//
//
//                              N3
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include <math.h>

#include <dlfcn.h>
#include <stdio.h>

#include "mvm/JIT.h"

#include "Assembly.h"
#include "CLIAccess.h"
#include "CLIJit.h"
#include "NativeUtil.h"
#include "MSCorlib.h"
#include "N3.h"
#include "Reader.h"
#include "VMArray.h"
#include "VMClass.h"
#include "VMObject.h"
#include "VMThread.h"

using namespace n3;

extern "C" void System_Runtime_CompilerServices_RuntimeHelpers_InitializeArray(
                                               VMArray* array, VMField* field) {
  if (!array || !field) return;

  VMClass* type = field->classDef;
  VMClassArray* ts = (VMClassArray*)array->classOf;
  VMCommonClass* bs = ts->baseClass;
  Assembly* ass = type->assembly;

  uint32 rva = ass->getRVAFromField(field->token);
  Section* inSection = 0;
  
  if (rva >= ass->rsrcSection->virtualAddress && rva < ass->rsrcSection->virtualAddress + ass->rsrcSection->virtualSize)
    inSection = ass->rsrcSection;
  if (rva >= ass->textSection->virtualAddress && rva < ass->textSection->virtualAddress + ass->textSection->virtualSize)
    inSection = ass->textSection;
  if (rva >= ass->relocSection->virtualAddress && rva < ass->relocSection->virtualAddress + ass->relocSection->virtualSize)
    inSection = ass->relocSection;

  uint32 size = array->size;
  uint32 offset = inSection->rawAddress + (rva - inSection->virtualAddress);
  ByteCode* bytes = ass->bytes;

  if (bs == MSCorlib::pChar) {
    for (uint32 i = 0; i < size; ++i) {
      ((ArrayUInt16*)array)->elements[i] = READ_U2(bytes, offset);
    }
  } else if (bs == MSCorlib::pSInt32) {
    for (uint32 i = 0; i < size; ++i) {
      ((ArraySInt32*)array)->elements[i] = READ_U4(bytes, offset);
    }
  } else if (bs == MSCorlib::pDouble) {
    for (uint32 i = 0; i < size; ++i) {
      ((ArrayDouble*)array)->elements[i] = READ_U8(bytes, offset);
    }
  } else {
    VMThread::get()->getVM()->error("implement me");
  }
}

extern "C" VMObject* System_Type_GetTypeFromHandle(VMCommonClass* cl) {
  return cl->getClassDelegatee();
}


extern "C" VMObject* System_Reflection_Assembly_GetCallingAssembly() {
  // Call to this function.
  void** cur = (void**)__builtin_frame_address(0);
  
  // Stub from CLI to native.
  cur = (void**)cur[0];

  // The CLI function.
  cur = (void**)cur[0];
  
  // The caller of the CLI function;
  cur = (void**)cur[0];
 
  N3* vm = VMThread::get()->getVM();

  abort();
  VMMethod* meth = NULL; //vm->IPToMethod<VMMethod>(FRAME_IP(cur));

  assert(meth && "Wrong stack");
  
  return meth->classDef->assembly->getAssemblyDelegatee();
}

extern "C" VMObject* System_Reflection_Assembly_GetExecutingAssembly() {
  // Call to this function.
  void** cur = (void**)__builtin_frame_address(0);
  
  // Stub from CLI to native.
  cur = (void**)cur[0];

  // The CLI function.
  cur = (void**)cur[0];
  
  N3* vm = VMThread::get()->getVM();

  abort();
  VMMethod* meth = NULL; //vm->IPToMethod<VMMethod>(FRAME_IP(cur));
  assert(meth && "Wrong stack");
  return meth->classDef->assembly->getAssemblyDelegatee();
}

extern "C" void System_Reflection_Assembly_LoadFromFile() {
  VMThread::get()->getVM()->error("implement me");
}

extern "C" void System_Array_InternalCopy(VMArray* src, sint32 sstart, 
                                          VMArray* dst, sint32 dstart, 
                                          sint32 len) {
  N3* vm = (N3*)(VMThread::get()->getVM());
  verifyNull(src);
  verifyNull(dst);
  
  if (!(src->classOf->isArray && dst->classOf->isArray)) {
    vm->arrayStoreException();
  }
  
  VMClassArray* ts = (VMClassArray*)src->classOf;
  VMClassArray* td = (VMClassArray*)dst->classOf;
  VMCommonClass* dstType = td->baseClass;
  VMCommonClass* srcType = ts->baseClass;

  if (len > src->size) {
    vm->indexOutOfBounds(src, len);
  } else if (len > dst->size) {
    vm->indexOutOfBounds(dst, len);
  } else if (len + sstart > src->size) {
    vm->indexOutOfBounds(src, len + sstart);
  } else if (len + dstart > dst->size) {
    vm->indexOutOfBounds(dst, len + dstart);
  } else if (dstart < 0) {
    vm->indexOutOfBounds(dst, dstart);
  } else if (sstart < 0) {
    vm->indexOutOfBounds(src, sstart);
  } else if (len < 0) {
    vm->indexOutOfBounds(src, len);
  } 
  
  bool doThrow = false;
  
  if (srcType->super == MSCorlib::pValue && srcType != dstType) {
    vm->arrayStoreException();
  } else if (srcType->super != MSCorlib::pValue && srcType->super != MSCorlib::pEnum) {
    sint32 i = sstart;
    while (i < sstart + len && !doThrow) {
      VMObject* cur = ((ArrayObject*)src)->elements[i];
      if (cur) {
        if (!(cur->classOf->isAssignableFrom(dstType))) {
          doThrow = true;
          len = i;
        }
      }
      ++i;
    }
  }
  
  
  uint32 size = srcType->naturalType->getPrimitiveSizeInBits() / 8;
  if (size == 0) size = sizeof(void*);
  void* ptrDst = (void*)((int64_t)(dst->elements) + size * dstart);
  void* ptrSrc = (void*)((int64_t)(src->elements) + size * sstart);
  memmove(ptrDst, ptrSrc, size * len);

  if (doThrow)
    vm->arrayStoreException();
  
}

extern "C" sint32 System_Array_GetRank(VMObject* arr) {
  verifyNull(arr);
  if (arr->classOf->isArray) {
    return ((VMClassArray*)(arr->classOf))->dims;
  } else {
    VMThread::get()->getVM()->error("implement me");
    return 0;
  }
}

extern "C" sint32 System_Array_GetLength(VMObject* arr) {
  verifyNull(arr);
  if (arr->classOf->isArray) {
    return ((VMArray*)arr)->size;
  } else {
    VMThread::get()->getVM()->error("implement me");
    return 0;
  }
}

extern "C" sint32 System_Array_GetLowerBound(VMObject* arr, sint32 dim) {
  return 0;
}

extern "C" VMObject* System_Object_GetType(VMObject* obj) {
  verifyNull(obj);
  return obj->classOf->getClassDelegatee();
}

extern "C" double System_Decimal_ToDouble(void* ptr) {
  VMThread::get()->getVM()->error("implement me");
  return 0.0;
}

extern "C" double System_Math_Log10(double val) {
  return log10(val);
}

extern "C" double System_Math_Floor(double val) {
  return floor(val);
}

extern "C" void System_GC_Collect() {
#ifdef MULTIPLE_GC
  VMThread::get()->GC->collect();
#else
  mvm::Collector::collect();
#endif
}

extern "C" void System_GC_SuppressFinalize(VMObject* obj) {
  // TODO: implement me
}

