//===------- ServiceDomain.cpp - Service domain description ---------------===//
//
//                              JnJVM
//
// This file is distributed under the University of Illinois Open Source 
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#ifdef SERVICE_VM
#include "mvm/JIT.h"

#include "JavaJIT.h"
#include "JavaThread.h"
#include "JavaUpcalls.h"
#include "JnjvmModuleProvider.h"
#include "ServiceDomain.h"

extern "C" struct JNINativeInterface JNI_JNIEnvTable;
extern "C" const struct JNIInvokeInterface JNI_JavaVMTable;


using namespace jnjvm;

JavaMethod* ServiceDomain::ServiceErrorInit;
Class* ServiceDomain::ServiceErrorClass;
ServiceDomain* ServiceDomain::bootstrapDomain;

// OSGi specific fields
JavaField* ServiceDomain::OSGiFramework;
JavaMethod* ServiceDomain::uninstallBundle;


ServiceDomain::~ServiceDomain() {
  delete lock;
}

void ServiceDomain::print(mvm::PrintBuffer* buf) const {
  buf->write("Service domain: ");
  buf->write(name);
}

ServiceDomain* ServiceDomain::allocateService(JavaIsolate* callingVM) {
  ServiceDomain* service = vm_new(callingVM, ServiceDomain)();
  service->threadSystem = callingVM->threadSystem;
#ifdef MULTIPLE_GC
  service->GC = Collector::allocate();
#endif
  

  service->classpath = callingVM->classpath;
  service->bootClasspathEnv = callingVM->bootClasspathEnv;
  service->libClasspathEnv = callingVM->libClasspathEnv;
  service->bootClasspath = callingVM->bootClasspath;
  service->functions = vm_new(service, FunctionMap)();
  service->functionDefs = vm_new(service, FunctionDefMap)();
  service->module = new JnjvmModule("Service Domain");
  std::string str = 
    mvm::jit::executionEngine->getTargetData()->getStringRepresentation();
  service->module->setDataLayout(str);
  service->protectModule = mvm::Lock::allocNormal();
  service->TheModuleProvider = new JnjvmModuleProvider(service->module,
                                                       service->functions,
                                                       service->functionDefs); 
  

#ifdef MULTIPLE_GC
  mvm::jit::memoryManager->addGCForModule(service->module, service->GC);
#endif
  JavaJIT::initialiseJITIsolateVM(service);
  
  service->name = "service";
  service->jniEnv = &JNI_JNIEnvTable;
  service->javavmEnv = &JNI_JavaVMTable;
  service->appClassLoader = callingVM->appClassLoader;

  // We copy so that bootstrap utf8 such as "<init>" are unique  
  service->hashUTF8 = vm_new(service, UTF8Map)();
  callingVM->hashUTF8->copy(service->hashUTF8);
  service->hashStr = vm_new(service, StringMap)();
  service->bootstrapClasses = callingVM->bootstrapClasses;
  service->loadedMethods = vm_new(service, MethodMap)();
  service->loadedFields = vm_new(service, FieldMap)();
  service->javaTypes = vm_new(service, TypeMap)(); 
  service->javaSignatures = vm_new(service, SignMap)(); 
  service->globalRefsLock = mvm::Lock::allocNormal();
#ifdef MULTIPLE_VM
  service->statics = vm_new(service, StaticInstanceMap)();  
  service->delegatees = vm_new(service, DelegateeMap)();  
#endif
  
  // A service is related to a class loader
  // Here are the classes it loaded
  service->classes = vm_new(service, ClassMap)();

  service->executionTime = 0;
  service->numThreads = 0;
  
  service->lock = mvm::Lock::allocNormal();
  service->state = DomainLoaded;
  return service;
}

void ServiceDomain::serviceError(ServiceDomain* errorDomain,
                                 const char* str) {
  if (ServiceErrorClass) {
    JavaObject* obj = (*ServiceErrorClass)(bootstrapDomain);
    ServiceErrorInit->invokeIntVirtual(bootstrapDomain, 
                                       bootstrapDomain->asciizToStr(str),
                                       errorDomain);
    JavaThread::throwException(obj);
  } else {
    fprintf(stderr, str);
    abort();
  }
}

ServiceDomain* ServiceDomain::getDomainFromLoader(JavaObject* loader) {
  ServiceDomain* vm = 
    (ServiceDomain*)(*Classpath::vmdataClassLoader)(loader).PointerVal;
  return vm;
}

#include "gccollector.h"
#include "gcthread.h"

extern "C" void serviceCallStart(ServiceDomain* caller,
                                 ServiceDomain* callee) {
  assert(caller && "No caller in service start?");
  assert(callee && "No callee in service start?");
  assert(caller->getVirtualTable() == ServiceDomain::VT && 
         "Caller not a service domain?");
  assert(callee->getVirtualTable() == ServiceDomain::VT && 
         "Callee not a service domain?");
  if (callee->state != DomainLoaded) {
    ServiceDomain::serviceError(callee, "calling a stopped bundle");
  }
  JavaThread* th = JavaThread::get();
  th->isolate = callee;
  caller->lock->lock();
  caller->interactions[callee]++;
  caller->lock->unlock();
  mvm::GCThreadCollector* cur = mvm::GCCollector::threads->myloc();
  cur->meta = callee;
}

extern "C" void serviceCallStop(ServiceDomain* caller,
                                ServiceDomain* callee) {
  assert(caller && "No caller in service stop?");
  assert(callee && "No callee in service stop?");
  assert(caller->getVirtualTable() == ServiceDomain::VT && 
         "Caller not a service domain?");
  assert(callee->getVirtualTable() == ServiceDomain::VT && 
         "Callee not a service domain?");
  if (caller->state != DomainLoaded) {
    ServiceDomain::serviceError(caller, "Returning to a stopped bundle");
  }
  JavaThread* th = JavaThread::get();
  th->isolate = caller;
  mvm::GCThreadCollector* cur = mvm::GCCollector::threads->myloc();
  cur->meta = caller;
}


static int updateCPUUsage(void* unused) {
  mvm::GCThreadCollector *cur;
  while (true) {
    sleep(1);
    for(cur=(mvm::GCThreadCollector *)mvm::GCCollector::threads->base.next();
        cur!=&(mvm::GCCollector::threads->base); 
        cur=(mvm::GCThreadCollector *)cur->next()) {
      ServiceDomain* executingDomain = (ServiceDomain*)cur->meta;
      if (executingDomain)
        ++executingDomain->executionTime;
    }
  }
}

void ServiceDomain::initialise(ServiceDomain* boot) {
  ServiceDomain::bootstrapDomain = boot;
  Jnjvm::bootstrapVM->appClassLoader = boot->appClassLoader;
  (*Classpath::vmdataClassLoader)(boot->appClassLoader, (JavaObject*)boot);
  int tid = 0;
  mvm::Thread::start(&tid, (int (*)(void *))updateCPUUsage, 0);
  ServiceErrorClass = UPCALL_CLASS(Jnjvm::bootstrapVM, "JnJVMBundleException");
  ServiceErrorInit = UPCALL_METHOD(Jnjvm::bootstrapVM, "JnjvmBundleException", 
                                   "<init>", 
                                   "(Ljava/lang/String;Ljava/lang/Object;)V",
                                   ACC_VIRTUAL);
  Class* MainClass = bootstrapDomain->constructClass(bootstrapDomain->asciizConstructUTF8("Main"), 
                                                     Jnjvm::bootstrapVM->appClassLoader);
  OSGiFramework = bootstrapDomain->constructField(MainClass, bootstrapDomain->asciizConstructUTF8("m_felix"),
                                            bootstrapDomain->asciizConstructUTF8("Lorg/apache/felix/framework/Felix;"),
                                            ACC_STATIC);
  uninstallBundle = bootstrapDomain->constructMethod(OSGiFramework->classDef, bootstrapDomain->asciizConstructUTF8("uninstallBundle"),
                                                     bootstrapDomain->asciizConstructUTF8("(Lorg/apache/felix/framework/FelixBundle;)V"),
                                                     ACC_VIRTUAL);
}

void ServiceDomain::startExecution() {
  JavaThread::get()->isolate = this;
  mvm::GCThreadCollector* cur = mvm::GCCollector::threads->myloc();
  cur->meta = this;
}

#endif
