#!/usr/bin/env python
#
# Copyright (c) 2014, 2015 Apple Inc. All rights reserved.
# Copyright (c) 2014 University of Washington. 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. AND ITS 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 APPLE INC. OR ITS 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 logging
import os.path
import re
from string import Template
import json

from builtins_model import BuiltinFunction, BuiltinObject
from builtins_templates import BuiltinsGeneratorTemplates as Templates

log = logging.getLogger('global')

# These match WK_lcfirst and WK_ucfirst defined in CodeGenerator.pm.
def WK_lcfirst(str):
    str = str[:1].lower() + str[1:]
    str = str.replace('dOM', 'dom')
    str = str.replace('uRL', 'url')
    str = str.replace('jS', 'js')
    str = str.replace('xML', 'xml')
    str = str.replace('xSLT', 'xslt')
    str = str.replace('cSS', 'css')
    str = str.replace('rTC', 'rtc')
    return str

def WK_ucfirst(str):
    str = str[:1].upper() + str[1:]
    str = str.replace('Xml', 'XML')
    str = str.replace('Svg', 'SVG')
    return str

class BuiltinsGenerator:
    def __init__(self, model):
        self._model = model

    def model(self):
        return self._model

    # These methods are overridden by subclasses.

    def generate_output(self):
        pass

    def output_filename(self):
        pass


    # Shared code generation methods.
    def generate_license(self):
        raw_license = Template(Templates.LicenseText).substitute(None)
        copyrights = self._model.copyrights()
        copyrights.sort()

        license_block = []
        license_block.append("/*")
        for copyright in copyrights:
            license_block.append(" * Copyright (c) %s" % copyright)
        if len(copyrights) > 0:
            license_block.append(" * ")

        for line in raw_license.split('\n'):
            license_block.append(" * " + line)

        license_block.append(" */")

        return '\n'.join(license_block)

    def generate_includes_from_entries(self, entries):
        includes = set()
        for entry in entries:
            (allowed_framework_names, data) = entry
            (framework_name, header_path) = data

            if self.model().framework.name not in allowed_framework_names:
                continue
            if self.model().framework.name != framework_name:
                includes.add("#include <%s/%s>" % (framework_name, os.path.basename(header_path)))
            else:
                includes.add("#include \"%s\"" % os.path.basename(header_path))

        return sorted(list(includes))

    def generate_primary_header_includes(self):
        name, _ = os.path.splitext(self.output_filename())
        return '\n'.join([
            "#include \"config.h\"",
            "#include \"%s.h\"" % name,
        ])

    def generate_embedded_code_string_section_for_function(self, function):
        text = function.function_source
        # Wrap it in parens to avoid adding to global scope.
        text = "(function " + text[text.index("("):] + ")"
        embeddedSourceLength = len(text) + 1  # For extra \n.
        # Lazy way to escape quotes, I think?
        textLines = json.dumps(text)[1:-1].split("\\n")
        # This looks scary because we need the JS source itself to have newlines.
        embeddedSource = '\n'.join(['    "%s\\n" \\' % line for line in textLines])

        constructAbility = "CannotConstruct"
        if function.is_constructor:
            constructAbility = "CanConstruct"

        args = {
            'codeName': BuiltinsGenerator.mangledNameForFunction(function) + 'Code',
            'embeddedSource': embeddedSource,
            'embeddedSourceLength': embeddedSourceLength,
            'canConstruct': constructAbility,
            'intrinsic': function.intrinsic
        }

        lines = []
        lines.append("const JSC::ConstructAbility s_%(codeName)sConstructAbility = JSC::ConstructAbility::%(canConstruct)s;" % args);
        lines.append("const int s_%(codeName)sLength = %(embeddedSourceLength)d;" % args);
        lines.append("static const JSC::Intrinsic s_%(codeName)sIntrinsic = JSC::%(intrinsic)s;" % args);
        lines.append("const char* s_%(codeName)s =\n%(embeddedSource)s\n;" % args);
        return '\n'.join(lines)

    # Helper methods.

    @staticmethod
    def wrap_with_guard(guard, text):
        if not guard:
            return text
        return '\n'.join([
            '#if %s' % guard,
            text,
            '#endif // %s' % guard,
        ])

    @staticmethod
    def mangledNameForObject(object):
        if not isinstance(object, BuiltinObject):
            raise Exception("Invalid argument passed to mangledNameForObject()")

        def toCamel(match):
            str = match.group(0)
            return str[1].upper()
        return re.sub(r'\.[a-z]', toCamel, object.object_name, flags=re.IGNORECASE)


    @staticmethod
    def mangledNameForFunction(function):
        if not isinstance(function, BuiltinFunction):
            raise Exception("Invalid argument passed to mangledNameForFunction()")

        function_name = WK_ucfirst(function.function_name)

        def toCamel(match):
            str = match.group(0)
            return str[1].upper()
        function_name = re.sub(r'\.[a-z]', toCamel, function_name, flags=re.IGNORECASE)
        if function.is_constructor:
            function_name = function_name + "Constructor"

        object_name = BuiltinsGenerator.mangledNameForObject(function.object)
        return WK_lcfirst(object_name + function_name)
