// Copyright 2006-2008 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
//       copyright notice, this list of conditions and the following
//       disclaimer in the documentation and/or other materials provided
//       with the distribution.
//     * Neither the name of Google Inc. nor the names of its
//       contributors may be used to endorse or promote products derived
//       from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#include <errno.h>
#include <stdio.h>
#ifdef COMPRESS_STARTUP_DATA_BZ2
#include <bzlib.h>
#endif
#include <signal.h>

#include "v8.h"

#include "bootstrapper.h"
#include "flags.h"
#include "natives.h"
#include "platform.h"
#include "serialize.h"
#include "list.h"

using namespace v8;


class Compressor {
 public:
  virtual ~Compressor() {}
  virtual bool Compress(i::Vector<char> input) = 0;
  virtual i::Vector<char>* output() = 0;
};


class PartialSnapshotSink : public i::SnapshotByteSink {
 public:
  PartialSnapshotSink() : data_(), raw_size_(-1) { }
  virtual ~PartialSnapshotSink() { data_.Free(); }
  virtual void Put(int byte, const char* description) {
    data_.Add(byte);
  }
  virtual int Position() { return data_.length(); }
  void Print(FILE* fp) {
    int length = Position();
    for (int j = 0; j < length; j++) {
      if ((j & 0x1f) == 0x1f) {
        fprintf(fp, "\n");
      }
      if (j != 0) {
        fprintf(fp, ",");
      }
      fprintf(fp, "%u", static_cast<unsigned char>(at(j)));
    }
  }
  char at(int i) { return data_[i]; }
  bool Compress(Compressor* compressor) {
    ASSERT_EQ(-1, raw_size_);
    raw_size_ = data_.length();
    if (!compressor->Compress(data_.ToVector())) return false;
    data_.Clear();
    data_.AddAll(*compressor->output());
    return true;
  }
  int raw_size() { return raw_size_; }

 private:
  i::List<char> data_;
  int raw_size_;
};


class CppByteSink : public PartialSnapshotSink {
 public:
  explicit CppByteSink(const char* snapshot_file) {
    fp_ = i::OS::FOpen(snapshot_file, "wb");
    if (fp_ == NULL) {
      i::PrintF("Unable to write to snapshot file \"%s\"\n", snapshot_file);
      exit(1);
    }
    fprintf(fp_, "// Autogenerated snapshot file. Do not edit.\n\n");
    fprintf(fp_, "#include \"v8.h\"\n");
    fprintf(fp_, "#include \"platform.h\"\n\n");
    fprintf(fp_, "#include \"snapshot.h\"\n\n");
    fprintf(fp_, "namespace v8 {\nnamespace internal {\n\n");
    fprintf(fp_, "const byte Snapshot::data_[] = {");
  }

  virtual ~CppByteSink() {
    fprintf(fp_, "const int Snapshot::size_ = %d;\n", Position());
#ifdef COMPRESS_STARTUP_DATA_BZ2
    fprintf(fp_, "const byte* Snapshot::raw_data_ = NULL;\n");
    fprintf(fp_,
            "const int Snapshot::raw_size_ = %d;\n\n",
            raw_size());
#else
    fprintf(fp_,
            "const byte* Snapshot::raw_data_ = Snapshot::data_;\n");
    fprintf(fp_,
            "const int Snapshot::raw_size_ = Snapshot::size_;\n\n");
#endif
    fprintf(fp_, "} }  // namespace v8::internal\n");
    fclose(fp_);
  }

  void WriteSpaceUsed(
      const char* prefix,
      int new_space_used,
      int pointer_space_used,
      int data_space_used,
      int code_space_used,
      int map_space_used,
      int cell_space_used,
      int property_cell_space_used) {
    fprintf(fp_,
            "const int Snapshot::%snew_space_used_ = %d;\n",
            prefix,
            new_space_used);
    fprintf(fp_,
            "const int Snapshot::%spointer_space_used_ = %d;\n",
            prefix,
            pointer_space_used);
    fprintf(fp_,
            "const int Snapshot::%sdata_space_used_ = %d;\n",
            prefix,
            data_space_used);
    fprintf(fp_,
            "const int Snapshot::%scode_space_used_ = %d;\n",
            prefix,
            code_space_used);
    fprintf(fp_,
            "const int Snapshot::%smap_space_used_ = %d;\n",
            prefix,
            map_space_used);
    fprintf(fp_,
            "const int Snapshot::%scell_space_used_ = %d;\n",
            prefix,
            cell_space_used);
    fprintf(fp_,
            "const int Snapshot::%sproperty_cell_space_used_ = %d;\n",
            prefix,
            property_cell_space_used);
  }

  void WritePartialSnapshot() {
    int length = partial_sink_.Position();
    fprintf(fp_, "};\n\n");
    fprintf(fp_, "const int Snapshot::context_size_ = %d;\n",  length);
#ifdef COMPRESS_STARTUP_DATA_BZ2
    fprintf(fp_,
            "const int Snapshot::context_raw_size_ = %d;\n",
            partial_sink_.raw_size());
#else
    fprintf(fp_,
            "const int Snapshot::context_raw_size_ = "
            "Snapshot::context_size_;\n");
#endif
    fprintf(fp_, "const byte Snapshot::context_data_[] = {\n");
    partial_sink_.Print(fp_);
    fprintf(fp_, "};\n\n");
#ifdef COMPRESS_STARTUP_DATA_BZ2
    fprintf(fp_, "const byte* Snapshot::context_raw_data_ = NULL;\n");
#else
    fprintf(fp_, "const byte* Snapshot::context_raw_data_ ="
            " Snapshot::context_data_;\n");
#endif
  }

  void WriteSnapshot() {
    Print(fp_);
  }

  PartialSnapshotSink* partial_sink() { return &partial_sink_; }

 private:
  FILE* fp_;
  PartialSnapshotSink partial_sink_;
};


#ifdef COMPRESS_STARTUP_DATA_BZ2
class BZip2Compressor : public Compressor {
 public:
  BZip2Compressor() : output_(NULL) {}
  virtual ~BZip2Compressor() {
    delete output_;
  }
  virtual bool Compress(i::Vector<char> input) {
    delete output_;
    output_ = new i::ScopedVector<char>((input.length() * 101) / 100 + 1000);
    unsigned int output_length_ = output_->length();
    int result = BZ2_bzBuffToBuffCompress(output_->start(), &output_length_,
                                          input.start(), input.length(),
                                          9, 1, 0);
    if (result == BZ_OK) {
      output_->Truncate(output_length_);
      return true;
    } else {
      fprintf(stderr, "bzlib error code: %d\n", result);
      return false;
    }
  }
  virtual i::Vector<char>* output() { return output_; }

 private:
  i::ScopedVector<char>* output_;
};


class BZip2Decompressor : public StartupDataDecompressor {
 public:
  virtual ~BZip2Decompressor() { }

 protected:
  virtual int DecompressData(char* raw_data,
                             int* raw_data_size,
                             const char* compressed_data,
                             int compressed_data_size) {
    ASSERT_EQ(StartupData::kBZip2,
              V8::GetCompressedStartupDataAlgorithm());
    unsigned int decompressed_size = *raw_data_size;
    int result =
        BZ2_bzBuffToBuffDecompress(raw_data,
                                   &decompressed_size,
                                   const_cast<char*>(compressed_data),
                                   compressed_data_size,
                                   0, 1);
    if (result == BZ_OK) {
      *raw_data_size = decompressed_size;
    }
    return result;
  }
};
#endif


void DumpException(Handle<Message> message) {
  String::Utf8Value message_string(message->Get());
  String::Utf8Value message_line(message->GetSourceLine());
  fprintf(stderr, "%s at line %d\n", *message_string, message->GetLineNumber());
  fprintf(stderr, "%s\n", *message_line);
  for (int i = 0; i <= message->GetEndColumn(); ++i) {
    fprintf(stderr, "%c", i < message->GetStartColumn() ? ' ' : '^');
  }
  fprintf(stderr, "\n");
}


int main(int argc, char** argv) {
  V8::InitializeICU();
  i::Isolate::SetCrashIfDefaultIsolateInitialized();

  // By default, log code create information in the snapshot.
  i::FLAG_log_code = true;

  // Print the usage if an error occurs when parsing the command line
  // flags or if the help flag is set.
  int result = i::FlagList::SetFlagsFromCommandLine(&argc, argv, true);
  if (result > 0 || argc != 2 || i::FLAG_help) {
    ::printf("Usage: %s [flag] ... outfile\n", argv[0]);
    i::FlagList::PrintHelp();
    return !i::FLAG_help;
  }
#ifdef COMPRESS_STARTUP_DATA_BZ2
  BZip2Decompressor natives_decompressor;
  int bz2_result = natives_decompressor.Decompress();
  if (bz2_result != BZ_OK) {
    fprintf(stderr, "bzip error code: %d\n", bz2_result);
    exit(1);
  }
#endif
  i::FLAG_logfile_per_isolate = false;

  Isolate* isolate = v8::Isolate::New();
  isolate->Enter();
  i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
  i::Serializer::Enable(internal_isolate);
  Persistent<Context> context;
  {
    HandleScope handle_scope(isolate);
    context.Reset(isolate, Context::New(isolate));
  }

  if (context.IsEmpty()) {
    fprintf(stderr,
            "\nException thrown while compiling natives - see above.\n\n");
    exit(1);
  }
  if (i::FLAG_extra_code != NULL) {
    // Capture 100 frames if anything happens.
    V8::SetCaptureStackTraceForUncaughtExceptions(true, 100);
    HandleScope scope(isolate);
    v8::Context::Scope cscope(v8::Local<v8::Context>::New(isolate, context));
    const char* name = i::FLAG_extra_code;
    FILE* file = i::OS::FOpen(name, "rb");
    if (file == NULL) {
      fprintf(stderr, "Failed to open '%s': errno %d\n", name, errno);
      exit(1);
    }

    fseek(file, 0, SEEK_END);
    int size = ftell(file);
    rewind(file);

    char* chars = new char[size + 1];
    chars[size] = '\0';
    for (int i = 0; i < size;) {
      int read = static_cast<int>(fread(&chars[i], 1, size - i, file));
      if (read < 0) {
        fprintf(stderr, "Failed to read '%s': errno %d\n", name, errno);
        exit(1);
      }
      i += read;
    }
    fclose(file);
    Local<String> source = String::NewFromUtf8(isolate, chars);
    TryCatch try_catch;
    Local<Script> script = Script::Compile(source);
    if (try_catch.HasCaught()) {
      fprintf(stderr, "Failure compiling '%s'\n", name);
      DumpException(try_catch.Message());
      exit(1);
    }
    script->Run();
    if (try_catch.HasCaught()) {
      fprintf(stderr, "Failure running '%s'\n", name);
      DumpException(try_catch.Message());
      exit(1);
    }
  }
  // Make sure all builtin scripts are cached.
  { HandleScope scope(isolate);
    for (int i = 0; i < i::Natives::GetBuiltinsCount(); i++) {
      internal_isolate->bootstrapper()->NativesSourceLookup(i);
    }
  }
  // If we don't do this then we end up with a stray root pointing at the
  // context even after we have disposed of the context.
  internal_isolate->heap()->CollectAllGarbage(
      i::Heap::kNoGCFlags, "mksnapshot");
  i::Object* raw_context = *v8::Utils::OpenPersistent(context);
  context.Reset();
  CppByteSink sink(argv[1]);
  // This results in a somewhat smaller snapshot, probably because it gets rid
  // of some things that are cached between garbage collections.
  i::StartupSerializer ser(internal_isolate, &sink);
  ser.SerializeStrongReferences();

  i::PartialSerializer partial_ser(
      internal_isolate, &ser, sink.partial_sink());
  partial_ser.Serialize(&raw_context);

  ser.SerializeWeakReferences();

#ifdef COMPRESS_STARTUP_DATA_BZ2
  BZip2Compressor compressor;
  if (!sink.Compress(&compressor))
    return 1;
  if (!sink.partial_sink()->Compress(&compressor))
    return 1;
#endif
  sink.WriteSnapshot();
  sink.WritePartialSnapshot();

  sink.WriteSpaceUsed(
      "context_",
      partial_ser.CurrentAllocationAddress(i::NEW_SPACE),
      partial_ser.CurrentAllocationAddress(i::OLD_POINTER_SPACE),
      partial_ser.CurrentAllocationAddress(i::OLD_DATA_SPACE),
      partial_ser.CurrentAllocationAddress(i::CODE_SPACE),
      partial_ser.CurrentAllocationAddress(i::MAP_SPACE),
      partial_ser.CurrentAllocationAddress(i::CELL_SPACE),
      partial_ser.CurrentAllocationAddress(i::PROPERTY_CELL_SPACE));
  sink.WriteSpaceUsed(
      "",
      ser.CurrentAllocationAddress(i::NEW_SPACE),
      ser.CurrentAllocationAddress(i::OLD_POINTER_SPACE),
      ser.CurrentAllocationAddress(i::OLD_DATA_SPACE),
      ser.CurrentAllocationAddress(i::CODE_SPACE),
      ser.CurrentAllocationAddress(i::MAP_SPACE),
      ser.CurrentAllocationAddress(i::CELL_SPACE),
      ser.CurrentAllocationAddress(i::PROPERTY_CELL_SPACE));
  isolate->Exit();
  isolate->Dispose();
  V8::Dispose();
  return 0;
}
