#!/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_data_for_function(self, function):
        text = function.function_source
        # Wrap it in parens to avoid adding to global scope.
        function_type_string = "function "
        if function.is_async:
            function_type_string = "async " + function_type_string

        text = "(" + function_type_string + 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"

        constructorKind = "None"
        if function.is_naked_constructor:
            constructorKind = "Naked"

        return {
            'codeName': BuiltinsGenerator.mangledNameForFunction(function) + 'Code',
            'embeddedSource': embeddedSource,
            'embeddedSourceLength': embeddedSourceLength,
            'originalSource': text + "\n",
            'constructAbility': constructAbility,
            'constructorKind': constructorKind,
            'intrinsic': function.intrinsic
        }

    def generate_embedded_code_string_section_for_data(self, data):
        lines = []
        lines.append("const JSC::ConstructAbility s_%(codeName)sConstructAbility = JSC::ConstructAbility::%(constructAbility)s;" % data);
        lines.append("const JSC::ConstructorKind s_%(codeName)sConstructorKind = JSC::ConstructorKind::%(constructorKind)s;" % data);
        lines.append("const int s_%(codeName)sLength = %(embeddedSourceLength)d;" % data);
        lines.append("static const JSC::Intrinsic s_%(codeName)sIntrinsic = JSC::%(intrinsic)s;" % data);
        lines.append("const char* const s_%(codeName)s =\n%(embeddedSource)s\n;" % data);
        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)
