// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

#include "bin/vmservice_dartium.h"

#include "bin/builtin.h"
#include "bin/dartutils.h"
#include "bin/eventhandler.h"
#include "bin/platform.h"
#include "bin/thread.h"
#include "bin/vmservice_impl.h"

namespace dart {
namespace bin {

#define CHECK_RESULT(result)                                                   \
  if (Dart_IsError(result)) {                                                  \
    fprintf(stderr, "CHECK_RESULT failed: %s", Dart_GetError(result));         \
    Dart_ExitScope();                                                          \
    Dart_ShutdownIsolate();                                                    \
    return 0;                                                                  \
  }                                                                            \



static const char* DEFAULT_VM_SERVICE_SERVER_IP = "127.0.0.1";
static const int DEFAULT_VM_SERVICE_SERVER_PORT = 0;

void VmServiceServer::Bootstrap() {
  if (!Platform::Initialize()) {
    fprintf(stderr, "Platform::Initialize() failed\n");
  }
  DartUtils::SetOriginalWorkingDirectory();
  Thread::InitOnce();
  EventHandler::Start();
}


Dart_Isolate VmServiceServer::CreateIsolate(const uint8_t* snapshot_buffer) {
  ASSERT(snapshot_buffer != NULL);
  // Create the isolate.
  char* error = 0;
  Dart_Isolate isolate = Dart_CreateIsolate(DART_VM_SERVICE_ISOLATE_NAME,
                                            "main",
                                            snapshot_buffer,
                                            NULL,
                                            NULL,
                                            &error);
  if (!isolate) {
    fprintf(stderr, "Dart_CreateIsolate failed: %s\n", error);
    return 0;
  }

  Dart_EnterScope();
  Builtin::SetNativeResolver(Builtin::kBuiltinLibrary);
  Builtin::SetNativeResolver(Builtin::kIOLibrary);

  Dart_Handle builtin_lib =
      Builtin::LoadAndCheckLibrary(Builtin::kBuiltinLibrary);
  CHECK_RESULT(builtin_lib);

  Dart_Handle result;

  // Prepare for script loading by setting up the 'print' and 'timer'
  // closures and setting up 'package root' for URI resolution.
  result = DartUtils::PrepareForScriptLoading(NULL, true, false, builtin_lib);
  CHECK_RESULT(result);

  ASSERT(Dart_IsServiceIsolate(isolate));
  if (!VmService::Setup(DEFAULT_VM_SERVICE_SERVER_IP,
                        DEFAULT_VM_SERVICE_SERVER_PORT)) {
    fprintf(stderr,
            "Vmservice::Setup failed: %s\n", VmService::GetErrorMessage());
    isolate = NULL;
  }
  Dart_ExitScope();
  Dart_ExitIsolate();
  return isolate;
}


const char* VmServiceServer::GetServerIP() {
  return VmService::GetServerIP();
}


intptr_t VmServiceServer::GetServerPort() {
  return VmService::GetServerPort();
}


/* DISALLOW_ALLOCATION */
void VmServiceServer::operator delete(void* pointer)  {
  fprintf(stderr, "unreachable code\n");
  abort();
}

}  // namespace bin
}  // namespace dart
