// Copyright (c) 2012, 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.

// Generate a snapshot file after loading all the scripts specified on the
// command line.

#include <stdlib.h>
#include <string.h>
#include <stdio.h>

#include "include/dart_api.h"

#include "bin/builtin.h"
#include "bin/dartutils.h"
#include "bin/file.h"
#include "platform/globals.h"

#define CHECK_RESULT(result)                                                   \
  if (Dart_IsError(result)) {                                                  \
    free(snapshot_buffer);                                                     \
    fprintf(stderr, "Error: %s", Dart_GetError(result));                       \
    Dart_ExitScope();                                                          \
    Dart_ShutdownIsolate();                                                    \
    exit(255);                                                                 \
  }                                                                            \


// Global state that indicates whether a snapshot is to be created and
// if so which file to write the snapshot into.
static const char* snapshot_filename = NULL;
static bool script_snapshot = false;
static const char* package_root = NULL;
static uint8_t* snapshot_buffer = NULL;


// Global state which contains a pointer to the script name for which
// a snapshot needs to be created (NULL would result in the creation
// of a generic snapshot that contains only the corelibs).
static char* app_script_name = NULL;


// Global state that captures the URL mappings specified on the command line.
static CommandLineOptions* url_mapping = NULL;

static bool IsValidFlag(const char* name,
                        const char* prefix,
                        intptr_t prefix_length) {
  intptr_t name_length = strlen(name);
  return ((name_length > prefix_length) &&
          (strncmp(name, prefix, prefix_length) == 0));
}


static const char* ProcessOption(const char* option, const char* name) {
  const intptr_t length = strlen(name);
  if (strncmp(option, name, length) == 0) {
    return (option + length);
  }
  return NULL;
}


static bool ProcessSnapshotOption(const char* option) {
  const char* name = ProcessOption(option, "--snapshot=");
  if (name != NULL) {
    script_snapshot = false;
    snapshot_filename = name;
    return true;
  }
  name = ProcessOption(option, "--script_snapshot=");
  if (name != NULL) {
    script_snapshot = true;
    snapshot_filename = name;
    return true;
  }
  return false;
}


static bool ProcessPackageRootOption(const char* option) {
  const char* name = ProcessOption(option, "--package_root=");
  if (name != NULL) {
    package_root = name;
    return true;
  }
  return false;
}


static bool ProcessURLmappingOption(const char* option) {
  const char* mapping = ProcessOption(option, "--url_mapping=");
  if (mapping == NULL) {
    mapping = ProcessOption(option, "--url-mapping=");
  }
  if (mapping != NULL) {
    url_mapping->AddArgument(mapping);
    return true;
  }
  return false;
}


// Parse out the command line arguments. Returns -1 if the arguments
// are incorrect, 0 otherwise.
static int ParseArguments(int argc,
                          char** argv,
                          CommandLineOptions* vm_options,
                          char** script_name) {
  const char* kPrefix = "--";
  const intptr_t kPrefixLen = strlen(kPrefix);

  // Skip the binary name.
  int i = 1;

  // Parse out the vm options.
  while ((i < argc) && IsValidFlag(argv[i], kPrefix, kPrefixLen)) {
    if (ProcessSnapshotOption(argv[i]) ||
        ProcessURLmappingOption(argv[i]) ||
        ProcessPackageRootOption(argv[i])) {
      i += 1;
      continue;
    }
    vm_options->AddArgument(argv[i]);
    i += 1;
  }

  // Get the script name.
  if (i < argc) {
    *script_name = argv[i];
    i += 1;
  } else {
    *script_name = NULL;
  }

  return 0;
}


static void WriteSnapshotFile(const uint8_t* buffer, const intptr_t size) {
  File* file = File::Open(snapshot_filename, File::kWriteTruncate);
  ASSERT(file != NULL);
  for (intptr_t i = 0; i < size; i++) {
    file->WriteByte(buffer[i]);
  }
  delete file;
}


static Dart_Handle CreateSnapshotLibraryTagHandler(Dart_LibraryTag tag,
                                                   Dart_Handle library,
                                                   Dart_Handle url) {
  if (!Dart_IsLibrary(library)) {
    return Dart_Error("not a library");
  }
  if (!Dart_IsString8(url)) {
    return Dart_Error("url is not a string");
  }
  const char* url_string = NULL;
  Dart_Handle result = Dart_StringToCString(url, &url_string);
  if (Dart_IsError(result)) {
    return result;
  }

  // If the URL starts with "dart:" then it is handled specially.
  bool is_dart_scheme_url = DartUtils::IsDartSchemeURL(url_string);
  if (tag == kCanonicalizeUrl) {
    if (is_dart_scheme_url) {
      return url;
    }
    return DartUtils::CanonicalizeURL(url_mapping, library, url_string);
  }
  return DartUtils::LoadSource(url_mapping,
                               library,
                               url,
                               tag,
                               url_string);
}


static Dart_Handle LoadSnapshotCreationScript(const char* script_name) {
  Dart_Handle source = DartUtils::ReadStringFromFile(script_name);
  if (Dart_IsError(source)) {
    return source;  // source contains the error string.
  }
  Dart_Handle url = Dart_NewString(script_name);

  return Dart_LoadScript(url, source);
}


static Dart_Handle LoadGenericSnapshotCreationScript(
    Builtin::BuiltinLibraryId id) {
  Dart_Handle source = Builtin::Source(id);
  if (Dart_IsError(source)) {
    return source;  // source contains the error string.
  }
  Dart_Handle lib;
  // Load the builtin library to make it available in the snapshot
  // for importing.
  lib = Builtin::LoadAndCheckLibrary(id);
  ASSERT(!Dart_IsError(lib));
  return lib;
}


static void PrintUsage() {
  fprintf(stderr,
          "dart [<vm-flags>] "
          "[<dart-script-file>]\n");
}


static void VerifyLoaded(Dart_Handle library) {
  if (Dart_IsError(library)) {
    const char* err_msg = Dart_GetError(library);
    fprintf(stderr, "Errors encountered while loading: %s\n", err_msg);
    Dart_ExitScope();
    Dart_ShutdownIsolate();
    exit(255);
  }
  ASSERT(Dart_IsLibrary(library));
}


static void CreateAndWriteSnapshot(bool script_snapshot) {
  Dart_Handle result;
  uint8_t* buffer = NULL;
  intptr_t size = 0;

  // First create a snapshot.
  if (script_snapshot) {
    // Script snapshot specified so create a script snapshot.
    result = Dart_CreateScriptSnapshot(&buffer, &size);
  } else {
    // Create a full snapshot.
    result = Dart_CreateSnapshot(&buffer, &size);
  }
  CHECK_RESULT(result);

  // Now write the snapshot out to specified file and exit.
  WriteSnapshotFile(buffer, size);
  Dart_ExitScope();

  // Shutdown the isolate.
  Dart_ShutdownIsolate();
}


static void SetupForGenericSnapshotCreation() {
  // Set up the library tag handler for this isolate.
  Dart_Handle result = Dart_SetLibraryTagHandler(DartUtils::LibraryTagHandler);
  if (Dart_IsError(result)) {
    fprintf(stderr, "%s", Dart_GetError(result));
    Dart_ExitScope();
    Dart_ShutdownIsolate();
    exit(255);
  }
  // This is a generic dart snapshot which needs builtin library setup.
  Dart_Handle library =
      LoadGenericSnapshotCreationScript(Builtin::kBuiltinLibrary);
  VerifyLoaded(library);
  library = LoadGenericSnapshotCreationScript(Builtin::kJsonLibrary);
  VerifyLoaded(library);
  library = LoadGenericSnapshotCreationScript(Builtin::kUriLibrary);
  VerifyLoaded(library);
  library = LoadGenericSnapshotCreationScript(Builtin::kCryptoLibrary);
  VerifyLoaded(library);
  library = LoadGenericSnapshotCreationScript(Builtin::kIOLibrary);
  VerifyLoaded(library);
  library = LoadGenericSnapshotCreationScript(Builtin::kUtfLibrary);
  VerifyLoaded(library);
}


int main(int argc, char** argv) {
  CommandLineOptions vm_options(argc);

  // Initialize the URL mapping array.
  CommandLineOptions url_mapping_array(argc);
  url_mapping = &url_mapping_array;

  // Parse command line arguments.
  if (ParseArguments(argc,
                     argv,
                     &vm_options,
                     &app_script_name) < 0) {
    PrintUsage();
    return 255;
  }

  if (snapshot_filename == NULL) {
    fprintf(stderr, "No snapshot output file specified\n");
    return 255;
  }

  DartUtils::SetOriginalWorkingDirectory();

  Dart_SetVMFlags(vm_options.count(), vm_options.arguments());

  // Initialize the Dart VM.
  // Note: We don't expect isolates to be created from dart code during
  // snapshot generation.
  if (!Dart_Initialize(NULL, NULL, NULL)) {
    fprintf(stderr, "VM initialization failed\n");
    return 255;
  }

  char* error;
  Dart_Isolate isolate = Dart_CreateIsolate(NULL, NULL, NULL, NULL, &error);
  if (isolate == NULL) {
    fprintf(stderr, "Error: %s", error);
    free(error);
    exit(255);
  }

  Dart_Handle result;
  Dart_Handle library;
  Dart_EnterScope();

  ASSERT(snapshot_filename != NULL);
  // Load up the script before a snapshot is created.
  if (app_script_name != NULL) {
    if (!script_snapshot) {
      // This is the case of a custom embedder (e.g: dartium) trying to
      // create a full snapshot. Set up the library tag handler for this case
      // in such a manner that it will use the URL mapping specified on the
      // command line to load the libraries.
      result = Dart_SetLibraryTagHandler(CreateSnapshotLibraryTagHandler);
      CHECK_RESULT(result);
      // Load the specified script.
      library = LoadSnapshotCreationScript(app_script_name);
      VerifyLoaded(library);
      CreateAndWriteSnapshot(false);
    } else {
      // This is the case where we want to create a script snapshot of
      // the specified script. There will be no URL mapping specified for
      // this case, use the generic library tag handler.

      // First setup and create a generic full snapshot.
      SetupForGenericSnapshotCreation();
      uint8_t* buffer = NULL;
      intptr_t size = 0;
      result = Dart_CreateSnapshot(&buffer, &size);
      CHECK_RESULT(result);

      // Save the snapshot buffer as we are about to shutdown the isolate.
      snapshot_buffer = reinterpret_cast<uint8_t*>(malloc(size));
      ASSERT(snapshot_buffer != NULL);
      memmove(snapshot_buffer, buffer, size);

      // Shutdown the isolate.
      Dart_ExitScope();
      Dart_ShutdownIsolate();

      // Now load the specified script and create a script snapshot.
      Dart_Isolate isolate = Dart_CreateIsolate(NULL,
                                                NULL,
                                                snapshot_buffer,
                                                NULL,
                                                &error);
      if (isolate == NULL) {
        fprintf(stderr, "%s", error);
        free(error);
        free(snapshot_buffer);
        exit(255);
      }
      Dart_EnterScope();

      // Setup generic library tag handler.
      result = Dart_SetLibraryTagHandler(DartUtils::LibraryTagHandler);
      CHECK_RESULT(result);

      // Get handle to builtin library.
      Dart_Handle builtin_lib =
          Builtin::LoadAndCheckLibrary(Builtin::kBuiltinLibrary);
      CHECK_RESULT(builtin_lib);

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

      // Load specified script.
      library = DartUtils::LoadScript(app_script_name, builtin_lib);

      // Now create and write snapshot of script.
      CreateAndWriteSnapshot(true);

      free(snapshot_buffer);
    }
  } else {
    SetupForGenericSnapshotCreation();
    CreateAndWriteSnapshot(false);
  }
  return 0;
}
