#!/usr/bin/python
# Copyright (C) 2014 Apple Inc. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
#    notice, this list of conditions and the following disclaimer.
# 2. 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.
#
# THIS SOFTWARE IS PROVIDED BY APPLE INC. ``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 APPLE INC. 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.

import argparse
import filecmp
import fnmatch
import os
import re
import shutil
import sys
import datetime
import json

parser = argparse.ArgumentParser()
parser.add_argument('input_file', nargs='*', help='Input JS files which builtins generated from')
parser.add_argument('--input-directory', help='All JS files will be used as input from this directory.')
parser.add_argument('--output', help='path to output cpp or h file')
parser.add_argument('--prefix', default='JSC', help='prefix used for public macros')
parser.add_argument('--namespace', default='JSC', help='C++ namespace')
args = parser.parse_args()

copyrightText = """ *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. 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.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``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 APPLE INC. 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. 
 */\n
"""

generatorString = "/* Generated by %s do not hand edit. */\n" % os.path.basename(__file__)

functionHeadRegExp = re.compile(r"(?:function|constructor)\s+\w+\s*\(.*?\)", re.MULTILINE | re.S)
functionNameRegExp = re.compile(r"(?:function|constructor)\s+(\w+)\s*\(", re.MULTILINE | re.S)
functionIsConstructorRegExp = re.compile(r"^constructor", re.MULTILINE | re.S)
functionParameterFinder = re.compile(r"^(?:function|constructor)\s+(?:\w+)\s*\(((?:\s*\w+)?\s*(?:\s*,\s*\w+)*)?\s*\)", re.MULTILINE | re.S)

multilineCommentRegExp = re.compile(r"\/\*.*?\*\/", re.MULTILINE | re.S)
singleLineCommentRegExp = re.compile(r"\/\/.*?\n", re.MULTILINE | re.S)

def getCopyright(source):
    copyrightBlock = multilineCommentRegExp.findall(source)[0]
    copyrightBlock = copyrightBlock[:copyrightBlock.index("Redistribution")]
    copyRightLines = []

    for line in copyrightBlock.split("\n"):
        line = line.replace("/*", "")
        line = line.replace("*/", "")
        line = line.replace("*", "")
        line = line.replace("Copyright", "")
        line = line.replace("copyright", "")
        line = line.replace("(C)", "")
        line = line.replace("(c)", "")
        line = line.strip()
        if len(line) == 0:
            continue

        copyRightLines.append(line)
    
    return list(set(copyRightLines))

class Function(object):
    def __init__(self, name, source, isConstructor, parameters):
        self.name = name
        self.source = source
        self.isConstructor = isConstructor
        self.parameters = parameters

    def mangleName(self, object):
        qName = object + "." + self.name
        mangledName = ""
        i = 0
        while i < len(qName):
            if qName[i] == '.':
                mangledName = mangledName + qName[i + 1].upper()
                i = i + 1
            else:
                mangledName = mangledName + qName[i]
            i = i + 1
        if self.isConstructor:
            mangledName = mangledName + "Constructor"
        return mangledName

def getFunctions(source):

    source = multilineCommentRegExp.sub("/**/", singleLineCommentRegExp.sub("//\n", source))

    matches = [ f for f in functionHeadRegExp.finditer(source)]
    functionBounds = []
    start = 0
    end = 0
    for match in matches:
        start = match.start()
        if start < end:
            continue
        end = match.end()
        while source[end] != '{':
            end = end + 1
        depth = 1
        end = end + 1
        while depth > 0:
            if source[end] == '{':
                depth = depth + 1
            elif source[end] == '}':
                depth = depth - 1
            end = end + 1
        functionBounds.append((start, end))

    functions = [source[start:end].strip() for (start, end) in functionBounds]
    result = []
    for function in functions:
        function = multilineCommentRegExp.sub("", function)
        functionName = functionNameRegExp.findall(function)[0]
        functionIsConstructor = functionIsConstructorRegExp.match(function) != None
        functionParameters = functionParameterFinder.findall(function)[0].split(',')
        if len(functionParameters[0]) == 0:
            functionParameters = []

        result.append(Function(functionName, function, functionIsConstructor, functionParameters))
    return result

def writeIncludeDirectives(writer, headerNames):
    for headerName in headerNames:
        writer.write("#include " + headerName + "\n")

def generateCode(source):
    inputFile = open(source, "r")
    baseName = os.path.basename(source).replace(".js", "")
    
    source = ""
    for line in inputFile:
        source = source + line
    
    if sys.platform == "cygwin":
        source = source.replace("\r\n", "\n")
    return (baseName, getFunctions(source), getCopyright(source))

builtins = []
copyrights = []
(output_base, _) = os.path.splitext(args.output)

if args.input_directory:
    for file in os.listdir(args.input_directory):
        args.input_file.append(os.path.join(args.input_directory, file))

for file in args.input_file:
    if fnmatch.fnmatch(file, '*.js'):
        (baseName, functions, objectCopyrights) = generateCode(file)
        copyrights.extend(objectCopyrights)
        builtins.append((baseName, functions))
namespace = args.namespace
macroPrefix = args.prefix
scopeName = os.path.splitext(os.path.basename(args.output))[0]
includeGuard = scopeName + "_H"
headerName = scopeName + ".h"

headerIncludes = ["\"BuiltinUtils.h\""] if namespace == "JSC" else ["<builtins/BuiltinUtils.h>"]
contentIncludes = ["\"BuiltinExecutables.h\"", "\"Executable.h\"", "\"JSCellInlines.h\"", "\"VM.h\""] if namespace == "JSC" else ["<runtime/Executable.h>", "<runtime/StructureInlines.h>", "<runtime/JSCJSValueInlines.h>", "<runtime/JSCellInlines.h>", "<runtime/VM.h>", "\"WebCoreJSClientData.h\""]

copyrights = list(set(copyrights))

copyrightBody = ""
for copyright in copyrights:
    copyrightBody = copyrightBody +" * Copyright (C) " + copyright + "\n"

builtinsHeader = open(output_base + ".h.tmp", "w")
builtinsImplementation = open(output_base + ".cpp.tmp", "w")
copyrightText = "/*\n" + copyrightBody + copyrightText
builtinsHeader.write("""%s
%s

#ifndef %s
#define %s

""" % (generatorString, copyrightText, includeGuard, includeGuard))

writeIncludeDirectives(builtinsHeader, headerIncludes)

builtinsHeader.write("""
namespace JSC {
    class FunctionExecutable;
}

namespace %s {

""" % namespace)

codeReferences = []

for (objectName, functions) in builtins:
    print("Generating bindings for the %s builtin." % objectName)
    builtinsHeader.write("/* %s functions */\n" % objectName)
    for function in functions:
        name = function.name
        mangledName = function.mangleName(objectName)
        mangledName = mangledName[0].lower() + mangledName[1:] + "Code"
        codeReferences.append((mangledName, function))
        builtinsHeader.write("extern const char* s_%s;\n" % mangledName)
        builtinsHeader.write("extern const int s_%sLength;\n" % mangledName)
        builtinsHeader.write("extern const JSC::ConstructAbility s_%sConstructAbility;\n" % mangledName)
    builtinsHeader.write("\n")
    builtinsHeader.write("#define %s_FOREACH_%s_BUILTIN(macro) \\\n" % (macroPrefix, objectName.replace(".", "_").upper()))
    for function in functions:
        mangledName = function.mangleName(objectName)
        builtinsHeader.write("    macro(%s, %s, %d) \\\n" % (function.name, mangledName, len(function.parameters)))
    builtinsHeader.write("\n")
    for function in functions:
        builtinsHeader.write("#define %s_BUILTIN_%s 1\n" % (macroPrefix, function.mangleName(objectName).upper()))
    builtinsHeader.write("\n\n")
names = []
builtinsHeader.write("#define %s_FOREACH_BUILTIN(macro)\\\n" % macroPrefix)
for (codeReference, function) in codeReferences:
    builtinsHeader.write("    macro(%s, %s, s_%sLength) \\\n" % (codeReference, function.name, codeReference))
    names.append(function.name)

builtinsHeader.write("\n\n")
builtinsHeader.write("#define %s_FOREACH_BUILTIN_FUNCTION_NAME(macro) \\\n" % macroPrefix)
for name in sorted(set(names)):
    builtinsHeader.write("    macro(%s) \\\n" % name)
builtinsHeader.write("""

#define DECLARE_BUILTIN_GENERATOR(codeName, functionName, argumentCount) \\
    JSC::FunctionExecutable* codeName##Generator(JSC::VM&);

%s_FOREACH_BUILTIN(DECLARE_BUILTIN_GENERATOR)
#undef DECLARE_BUILTIN_GENERATOR

#define %s_BUILTIN_EXISTS(name) defined %s_BUILTIN_ ## name

}

#endif // %s

""" % (macroPrefix, macroPrefix, macroPrefix, includeGuard))

builtinsImplementation.write("""%s
%s

#include "config.h"

#include "%s"

"""  % (generatorString, copyrightText, headerName))

writeIncludeDirectives(builtinsImplementation, contentIncludes)

builtinsImplementation.write("""
namespace %s {

"""  % (namespace))



for (codeReference, function) in codeReferences:
    source = function.source
    source = "(function " + source[source.index("("):] + ")"
    lines = json.dumps(source)[1:-1].split("\\n")
    sourceLength = len(source)
    source = ""
    for line in lines:
        source = source + ("    \"%s\\n\" \\\n" % line)
    builtinsImplementation.write("const char* s_%s =\n%s;\n\n" % (codeReference, source))
    builtinsImplementation.write("const int s_%sLength = %d;\n\n" % (codeReference, sourceLength + 1)) # + 1 for \n
    constructAbility = "JSC::ConstructAbility::CannotConstruct"
    if function.isConstructor:
        constructAbility = "JSC::ConstructAbility::CanConstruct"
    builtinsImplementation.write("const JSC::ConstructAbility s_%sConstructAbility = %s;\n\n" % (codeReference, constructAbility)) # + 1 for \n

builtinsImplementation.write("""
#define DEFINE_BUILTIN_GENERATOR(codeName, functionName, argumentCount) \\
JSC::FunctionExecutable* codeName##Generator(JSC::VM& vm) \\
""");

if (namespace == "JSC"):
    builtinsImplementation.write("""{\\
    return vm.builtinExecutables()->codeName##Executable()->link(vm, vm.builtinExecutables()->codeName##Source()); \\
""")
else:
    builtinName = scopeName[0].lower() + scopeName[1:]
    builtinsImplementation.write("""{\\
    JSVMClientData* clientData = static_cast<JSVMClientData*>(vm.clientData); \\
    return clientData->builtinFunctions().%s().codeName##Executable()->link(vm, clientData->builtinFunctions().%s().codeName##Source()); \\
"""% (builtinName, builtinName))

builtinsImplementation.write("""}
%s_FOREACH_BUILTIN(DEFINE_BUILTIN_GENERATOR)
#undef DEFINE_BUILTIN_GENERATOR
}

"""% (macroPrefix))

builtinsHeader.close()
builtinsImplementation.close()

if (not os.path.exists(output_base + ".h")) or (not filecmp.cmp(output_base + ".h.tmp", output_base + ".h", shallow=False)):
    if (os.path.exists(output_base + ".h")):
        os.remove(output_base + ".h")
    os.rename(output_base + ".h.tmp", output_base + ".h")
else:
    os.remove(output_base + ".h.tmp")

if (not os.path.exists(output_base + ".cpp")) or (not filecmp.cmp(output_base + ".cpp.tmp", output_base + ".cpp", shallow=False)):
    if (os.path.exists(output_base + ".cpp")):
        os.remove(output_base + ".cpp")
    os.rename(output_base + ".cpp.tmp", output_base + ".cpp")
else:
    os.remove(output_base + ".cpp.tmp")
