// Copyright 2006-2008 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <errno.h>
#include <signal.h>
#include <stdio.h>
#include <iomanip>

#include "include/libplatform/libplatform.h"
#include "src/base/platform/platform.h"
#include "src/base/platform/wrappers.h"
#include "src/codegen/assembler-arch.h"
#include "src/codegen/source-position-table.h"
#include "src/flags/flags.h"
#include "src/sanitizer/msan.h"
#include "src/snapshot/context-serializer.h"
#include "src/snapshot/embedded/embedded-file-writer.h"
#include "src/snapshot/snapshot.h"
#include "src/snapshot/startup-serializer.h"

namespace {

class SnapshotFileWriter {
 public:
  void SetSnapshotFile(const char* snapshot_cpp_file) {
    snapshot_cpp_path_ = snapshot_cpp_file;
  }

  void SetStartupBlobFile(const char* snapshot_blob_file) {
    snapshot_blob_path_ = snapshot_blob_file;
  }

  void WriteSnapshot(v8::StartupData blob) const {
    // TODO(crbug/633159): if we crash before the files have been fully created,
    // we end up with a corrupted snapshot file. The build step would succeed,
    // but the build target is unusable. Ideally we would write out temporary
    // files and only move them to the final destination as last step.
    i::Vector<const i::byte> blob_vector(
        reinterpret_cast<const i::byte*>(blob.data), blob.raw_size);
    MaybeWriteSnapshotFile(blob_vector);
    MaybeWriteStartupBlob(blob_vector);
  }

 private:
  void MaybeWriteStartupBlob(const i::Vector<const i::byte>& blob) const {
    if (!snapshot_blob_path_) return;

    FILE* fp = GetFileDescriptorOrDie(snapshot_blob_path_);
    size_t written = fwrite(blob.begin(), 1, blob.length(), fp);
    v8::base::Fclose(fp);
    if (written != static_cast<size_t>(blob.length())) {
      i::PrintF("Writing snapshot file failed.. Aborting.\n");
      remove(snapshot_blob_path_);
      exit(1);
    }
  }

  void MaybeWriteSnapshotFile(const i::Vector<const i::byte>& blob) const {
    if (!snapshot_cpp_path_) return;

    FILE* fp = GetFileDescriptorOrDie(snapshot_cpp_path_);

    WriteSnapshotFilePrefix(fp);
    WriteSnapshotFileData(fp, blob);
    WriteSnapshotFileSuffix(fp);

    v8::base::Fclose(fp);
  }

  static void WriteSnapshotFilePrefix(FILE* fp) {
    fprintf(fp, "// Autogenerated snapshot file. Do not edit.\n\n");
    fprintf(fp, "#include \"src/init/v8.h\"\n");
    fprintf(fp, "#include \"src/base/platform/platform.h\"\n\n");
    fprintf(fp, "#include \"src/snapshot/snapshot.h\"\n\n");
    fprintf(fp, "namespace v8 {\n");
    fprintf(fp, "namespace internal {\n\n");
  }

  static void WriteSnapshotFileSuffix(FILE* fp) {
    fprintf(fp, "const v8::StartupData* Snapshot::DefaultSnapshotBlob() {\n");
    fprintf(fp, "  return &blob;\n");
    fprintf(fp, "}\n\n");
    fprintf(fp, "}  // namespace internal\n");
    fprintf(fp, "}  // namespace v8\n");
  }

  static void WriteSnapshotFileData(FILE* fp,
                                    const i::Vector<const i::byte>& blob) {
    fprintf(fp,
            "alignas(kPointerAlignment) static const byte blob_data[] = {\n");
    WriteBinaryContentsAsCArray(fp, blob);
    fprintf(fp, "};\n");
    fprintf(fp, "static const int blob_size = %d;\n", blob.length());
    fprintf(fp, "static const v8::StartupData blob =\n");
    fprintf(fp, "{ (const char*) blob_data, blob_size };\n");
  }

  static void WriteBinaryContentsAsCArray(
      FILE* fp, const i::Vector<const i::byte>& blob) {
    for (int i = 0; i < blob.length(); i++) {
      if ((i & 0x1F) == 0x1F) fprintf(fp, "\n");
      if (i > 0) fprintf(fp, ",");
      fprintf(fp, "%u", static_cast<unsigned char>(blob.at(i)));
    }
    fprintf(fp, "\n");
  }

  static FILE* GetFileDescriptorOrDie(const char* filename) {
    FILE* fp = v8::base::OS::FOpen(filename, "wb");
    if (fp == nullptr) {
      i::PrintF("Unable to open file \"%s\" for writing.\n", filename);
      exit(1);
    }
    return fp;
  }

  const char* snapshot_cpp_path_ = nullptr;
  const char* snapshot_blob_path_ = nullptr;
};

char* GetExtraCode(char* filename, const char* description) {
  if (filename == nullptr || strlen(filename) == 0) return nullptr;
  ::printf("Loading script for %s: %s\n", description, filename);
  FILE* file = v8::base::OS::FOpen(filename, "rb");
  if (file == nullptr) {
    fprintf(stderr, "Failed to open '%s': errno %d\n", filename, errno);
    exit(1);
  }
  fseek(file, 0, SEEK_END);
  size_t size = ftell(file);
  rewind(file);
  char* chars = new char[size + 1];
  chars[size] = '\0';
  for (size_t i = 0; i < size;) {
    size_t read = fread(&chars[i], 1, size - i, file);
    if (ferror(file)) {
      fprintf(stderr, "Failed to read '%s': errno %d\n", filename, errno);
      exit(1);
    }
    i += read;
  }
  v8::base::Fclose(file);
  return chars;
}

v8::StartupData CreateSnapshotDataBlob(v8::Isolate* isolate,
                                       const char* embedded_source) {
  v8::base::ElapsedTimer timer;
  timer.Start();

  v8::StartupData result = i::CreateSnapshotDataBlobInternal(
      v8::SnapshotCreator::FunctionCodeHandling::kClear, embedded_source,
      isolate);

  if (i::FLAG_profile_deserialization) {
    i::PrintF("Creating snapshot took %0.3f ms\n",
              timer.Elapsed().InMillisecondsF());
  }

  timer.Stop();
  return result;
}

v8::StartupData WarmUpSnapshotDataBlob(v8::StartupData cold_snapshot_blob,
                                       const char* warmup_source) {
  v8::base::ElapsedTimer timer;
  timer.Start();

  v8::StartupData result =
      i::WarmUpSnapshotDataBlobInternal(cold_snapshot_blob, warmup_source);

  if (i::FLAG_profile_deserialization) {
    i::PrintF("Warming up snapshot took %0.3f ms\n",
              timer.Elapsed().InMillisecondsF());
  }

  timer.Stop();
  return result;
}

void WriteEmbeddedFile(i::EmbeddedFileWriter* writer) {
  i::EmbeddedData embedded_blob = i::EmbeddedData::FromBlob();
  writer->WriteEmbedded(&embedded_blob);
}

using CounterMap = std::map<std::string, int>;
CounterMap* counter_map_ = nullptr;

void MaybeSetCounterFunction(v8::Isolate* isolate) {
  // If --native-code-counters is on then we enable all counters to make
  // sure we generate code to increment them from the snapshot.
  //
  // Note: For the sake of the mksnapshot, the counter function must only
  // return distinct addresses for each counter s.t. the serializer can properly
  // distinguish between them. In theory it should be okay to just return an
  // incremented int value each time this function is called, but we play it
  // safe and return a real distinct memory location tied to every counter name.
  if (i::FLAG_native_code_counters) {
    counter_map_ = new CounterMap();
    isolate->SetCounterFunction([](const char* name) -> int* {
      auto map_entry = counter_map_->find(name);
      if (map_entry == counter_map_->end()) {
        counter_map_->emplace(name, 0);
      }
      return &counter_map_->at(name);
    });
  }
}

}  // namespace

int main(int argc, char** argv) {
  v8::base::EnsureConsoleOutput();

  // Make mksnapshot runs predictable to create reproducible snapshots.
  i::FLAG_predictable = true;

  // Print the usage if an error occurs when parsing the command line
  // flags or if the help flag is set.
  using HelpOptions = i::FlagList::HelpOptions;
  std::string usage = "Usage: " + std::string(argv[0]) +
                      " [--startup-src=file]" + " [--startup-blob=file]" +
                      " [--embedded-src=file]" + " [--embedded-variant=label]" +
                      " [--target-arch=arch]" +
                      " [--target-os=os] [extras]\n\n";
  int result = i::FlagList::SetFlagsFromCommandLine(
      &argc, argv, true, HelpOptions(HelpOptions::kExit, usage.c_str()));
  if (result > 0 || (argc > 3)) {
    i::PrintF(stdout, "%s", usage.c_str());
    return result;
  }

  i::CpuFeatures::Probe(true);
  v8::V8::InitializeICUDefaultLocation(argv[0]);
  std::unique_ptr<v8::Platform> platform = v8::platform::NewDefaultPlatform();
  v8::V8::InitializePlatform(platform.get());
  v8::V8::Initialize();

  {
    SnapshotFileWriter snapshot_writer;
    snapshot_writer.SetSnapshotFile(i::FLAG_startup_src);
    snapshot_writer.SetStartupBlobFile(i::FLAG_startup_blob);

    i::EmbeddedFileWriter embedded_writer;
    embedded_writer.SetEmbeddedFile(i::FLAG_embedded_src);
    embedded_writer.SetEmbeddedVariant(i::FLAG_embedded_variant);
    embedded_writer.SetTargetArch(i::FLAG_target_arch);
    embedded_writer.SetTargetOs(i::FLAG_target_os);

    std::unique_ptr<char> embed_script(
        GetExtraCode(argc >= 2 ? argv[1] : nullptr, "embedding"));
    std::unique_ptr<char> warmup_script(
        GetExtraCode(argc >= 3 ? argv[2] : nullptr, "warm up"));

    i::DisableEmbeddedBlobRefcounting();
    v8::StartupData blob;
    {
      v8::Isolate* isolate = v8::Isolate::Allocate();

      MaybeSetCounterFunction(isolate);

      // Set code range such that relative jumps for builtins to
      // builtin calls in the snapshot are possible.
      i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
      size_t code_range_size_mb =
          i::kMaximalCodeRangeSize == 0
              ? i::kMaxPCRelativeCodeRangeInMB
              : std::min(i::kMaximalCodeRangeSize / i::MB,
                         i::kMaxPCRelativeCodeRangeInMB);
      v8::ResourceConstraints constraints;
      constraints.set_code_range_size_in_bytes(code_range_size_mb * i::MB);
      i_isolate->heap()->ConfigureHeap(constraints);
      // The isolate contains data from builtin compilation that needs
      // to be written out if builtins are embedded.
      i_isolate->RegisterEmbeddedFileWriter(&embedded_writer);

      blob = CreateSnapshotDataBlob(isolate, embed_script.get());

      // At this point, the Isolate has been torn down but the embedded blob
      // is still alive (we called DisableEmbeddedBlobRefcounting above).
      // That's fine as far as the embedded file writer is concerned.
      WriteEmbeddedFile(&embedded_writer);
    }

    if (warmup_script) {
      v8::StartupData cold = blob;
      blob = WarmUpSnapshotDataBlob(cold, warmup_script.get());
      delete[] cold.data;
    }

    delete counter_map_;

    CHECK(blob.data);
    snapshot_writer.WriteSnapshot(blob);
    delete[] blob.data;
  }
  i::FreeCurrentEmbeddedBlob();

  v8::V8::Dispose();
  v8::V8::ShutdownPlatform();
  return 0;
}
