#!/usr/bin/env python
#
# Copyright 2012 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.

# This is a utility for converting JavaScript source code into C-style
# char arrays. It is used for embedded JavaScript code in the V8
# library.

# for py2/py3 compatibility
from functools import reduce

import os, re
import optparse
import textwrap


class Error(Exception):
  def __init__(self, msg):
    Exception.__init__(self, msg)


def ToCArray(byte_sequence):
  result = []
  for chr in byte_sequence:
    result.append(str(ord(chr)))
  joined = ", ".join(result)
  return textwrap.fill(joined, 80)


def RemoveCommentsEmptyLinesAndWhitespace(lines):
  lines = re.sub(r'\n+', '\n', lines) # empty lines
  lines = re.sub(r'//.*\n', '\n', lines) # end-of-line comments
  lines = re.sub(re.compile(r'/\*.*?\*/', re.DOTALL), '', lines) # comments.
  lines = re.sub(r'\s+\n', '\n', lines) # trailing whitespace
  lines = re.sub(r'\n\s+', '\n', lines) # initial whitespace
  return lines


def ReadFile(filename):
  file = open(filename, "rt")
  try:
    lines = file.read()
  finally:
    file.close()
  return lines


EVAL_PATTERN = re.compile(r'\beval\s*\(')
WITH_PATTERN = re.compile(r'\bwith\s*\(')
INVALID_ERROR_MESSAGE_PATTERN = re.compile(
    r'Make(?!Generic)\w*Error\(([kA-Z]\w+)')
NEW_ERROR_PATTERN = re.compile(r'new \$\w*Error\((?!\))')

def Validate(lines):
  # Because of simplified context setup, eval and with is not
  # allowed in the natives files.
  if EVAL_PATTERN.search(lines):
    raise Error("Eval disallowed in natives.")
  if WITH_PATTERN.search(lines):
    raise Error("With statements disallowed in natives.")
  invalid_error = INVALID_ERROR_MESSAGE_PATTERN.search(lines)
  if invalid_error:
    raise Error("Unknown error message template '%s'" % invalid_error.group(1))
  if NEW_ERROR_PATTERN.search(lines):
    raise Error("Error constructed without message template.")
  # Pass lines through unchanged.
  return lines


def ExpandConstants(lines, constants):
  for key, value in constants:
    lines = key.sub(str(value), lines)
  return lines


HEADER_TEMPLATE = """\
// Copyright 2011 Google Inc. All Rights Reserved.

// This file was generated from .js source files by GYP.  If you
// want to make changes to this file you should either change the
// javascript source files or the GYP script.

#include "src/init/v8.h"
#include "src/snapshot/natives.h"
#include "src/utils/utils.h"

namespace v8 {
namespace internal {

%(sources_declaration)s\

  template <>
  int NativesCollection<%(type)s>::GetBuiltinsCount() {
    return %(builtin_count)i;
  }

  template <>
  int NativesCollection<%(type)s>::GetIndex(const char* name) {
%(get_index_cases)s\
    return -1;
  }

  template <>
  Vector<const char> NativesCollection<%(type)s>::GetScriptSource(int index) {
%(get_script_source_cases)s\
    return Vector<const char>("", 0);
  }

  template <>
  Vector<const char> NativesCollection<%(type)s>::GetScriptName(int index) {
%(get_script_name_cases)s\
    return Vector<const char>("", 0);
  }

  template <>
  Vector<const char> NativesCollection<%(type)s>::GetScriptsSource() {
    return Vector<const char>(sources, %(total_length)i);
  }
}  // internal
}  // v8
"""

SOURCES_DECLARATION = """\
  static const char sources[] = { %s };
"""


GET_INDEX_CASE = """\
    if (strcmp(name, "%(id)s") == 0) return %(i)i;
"""


GET_SCRIPT_SOURCE_CASE = """\
    if (index == %(i)i) return Vector<const char>(sources + %(offset)i, %(source_length)i);
"""


GET_SCRIPT_NAME_CASE = """\
    if (index == %(i)i) return Vector<const char>("%(name)s", %(length)i);
"""


def BuildFilterChain():
  """Build the chain of filter functions to be applied to the sources.

  Returns:
    A function (string -> string) that processes a source file.
  """
  filter_chain = [
    RemoveCommentsEmptyLinesAndWhitespace,
    Validate,
  ]

  def chain(f1, f2):
    return lambda x: f2(f1(x))

  return reduce(chain, filter_chain)

def BuildExtraFilterChain():
  return lambda x: RemoveCommentsEmptyLinesAndWhitespace(Validate(x))

class Sources:
  def __init__(self):
    self.names = []
    self.modules = []

def PrepareSources(source_files, native_type, emit_js):
  """Read, prepare and assemble the list of source files.

  Args:
    source_files: List of JavaScript-ish source files.
    native_type: String corresponding to a NativeType enum value, allowing us
        to treat different types of sources differently.
    emit_js: True if we should skip the byte conversion and just leave the
        sources as JS strings.

  Returns:
    An instance of Sources.
  """
  result = Sources()
  filters = BuildFilterChain()

  source_files_and_contents = [(f, ReadFile(f)) for f in source_files]

  for (source, contents) in source_files_and_contents:
    try:
      lines = filters(contents)
    except Error as e:
      raise Error("In file %s:\n%s" % (source, str(e)))

    result.modules.append(lines)

    name = os.path.basename(source)[:-3]
    result.names.append(name)

  return result


def BuildMetadata(sources, source_bytes, native_type):
  """Build the meta data required to generate a libaries file.

  Args:
    sources: A Sources instance with the prepared sources.
    source_bytes: A list of source bytes.
        (The concatenation of all sources; might be compressed.)
    native_type: The parameter for the NativesCollection template.

  Returns:
    A dictionary for use with HEADER_TEMPLATE.
  """
  total_length = len(source_bytes)
  raw_sources = "".join(sources.modules)

  # The sources are expected to be ASCII-only.
  try:
    raw_sources.encode('ascii')
  except UnicodeEncodeError:
    assert False

  # Loop over modules and build up indices into the source blob:
  get_index_cases = []
  get_script_name_cases = []
  get_script_source_cases = []
  offset = 0
  for i in range(len(sources.modules)):
    native_name = "native %s.js" % sources.names[i]
    d = {
        "i": i,
        "id": sources.names[i],
        "name": native_name,
        "length": len(native_name),
        "offset": offset,
        "source_length": len(sources.modules[i]),
    }
    get_index_cases.append(GET_INDEX_CASE % d)
    get_script_name_cases.append(GET_SCRIPT_NAME_CASE % d)
    get_script_source_cases.append(GET_SCRIPT_SOURCE_CASE % d)
    offset += len(sources.modules[i])
  assert offset == len(raw_sources)

  metadata = {
    "builtin_count": len(sources.modules),
    "sources_declaration": SOURCES_DECLARATION % ToCArray(source_bytes),
    "total_length": total_length,
    "get_index_cases": "".join(get_index_cases),
    "get_script_source_cases": "".join(get_script_source_cases),
    "get_script_name_cases": "".join(get_script_name_cases),
    "type": native_type,
  }
  return metadata


def PutInt(blob_file, value):
  assert(value >= 0 and value < (1 << 28))
  if (value < 1 << 6):
    size = 1
  elif (value < 1 << 14):
    size = 2
  elif (value < 1 << 22):
    size = 3
  else:
    size = 4
  value_with_length = (value << 2) | (size - 1)

  byte_sequence = bytearray()
  for i in range(size):
    byte_sequence.append(value_with_length & 255)
    value_with_length >>= 8;
  blob_file.write(byte_sequence)


def PutStr(blob_file, value):
  PutInt(blob_file, len(value.encode()))
  blob_file.write(value.encode())


def WriteStartupBlob(sources, startup_blob):
  """Write a startup blob, as expected by V8 Initialize ...
    TODO(vogelheim): Add proper method name.

  Args:
    sources: A Sources instance with the prepared sources.
    startup_blob_file: Name of file to write the blob to.
  """
  output = open(startup_blob, "wb")

  PutInt(output, len(sources.names))
  for i in range(len(sources.names)):
    PutStr(output, sources.names[i]);
    PutStr(output, sources.modules[i]);

  output.close()


def JS2C(sources, target, native_type, raw_file, startup_blob, emit_js):
  prepared_sources = PrepareSources(sources, native_type, emit_js)
  sources_output = "".join(prepared_sources.modules)
  metadata = BuildMetadata(prepared_sources, sources_output, native_type)

  # Optionally emit raw file.
  if raw_file:
    output = open(raw_file, "w")
    output.write(sources_output)
    output.close()

  if startup_blob:
    WriteStartupBlob(prepared_sources, startup_blob)

  # Emit resulting source file.
  output = open(target, "w")
  if emit_js:
    output.write(sources_output)
  else:
    output.write(HEADER_TEMPLATE % metadata)
  output.close()


def main():
  parser = optparse.OptionParser()
  parser.add_option("--raw",
                    help="file to write the processed sources array to.")
  parser.add_option("--startup_blob",
                    help="file to write the startup blob to.")
  parser.add_option("--js",
                    help="writes a JS file output instead of a C file",
                    action="store_true", default=False, dest='js')
  parser.add_option("--nojs", action="store_false", default=False, dest='js')
  parser.set_usage("""js2c out.cc type sources.js ...
        out.cc: C code to be generated.
        type: type parameter for NativesCollection template.
        sources.js: JS internal sources.""")
  (options, args) = parser.parse_args()
  JS2C(args[2:],
       args[0],
       args[1],
       options.raw,
       options.startup_blob,
       options.js)


if __name__ == "__main__":
  main()
