#!/usr/bin/env python3
#
# Copyright (c) 2015-2016 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. 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 re
import os

from builtins_templates import BuiltinsGeneratorTemplates as Templates

log = logging.getLogger('global')

_FRAMEWORK_CONFIG_MAP = {
    "JavaScriptCore": {
        "macro_prefix": "JSC",
        "namespace": "JSC",
    },
    "WebCore": {
        "macro_prefix": "WEBCORE",
        "namespace": "WebCore",
    },
}

functionHeadRegExp = re.compile(r"(?:@[\w|=\[\] \"\.]+\s*\n)*(?:async\s+)?function\s+\w+\s*\(.*?\)", re.MULTILINE | re.DOTALL)
functionGlobalPrivateRegExp = re.compile(r".*^@globalPrivate", re.MULTILINE | re.DOTALL)
functionNakedConstructorRegExp = re.compile(r".*^@nakedConstructor", re.MULTILINE | re.DOTALL)
functionIntrinsicRegExp = re.compile(r".*^@intrinsic=(\w+)", re.MULTILINE | re.DOTALL)
functionIsConstructorRegExp = re.compile(r".*^@constructor", re.MULTILINE | re.DOTALL)
functionIsGetterRegExp = re.compile(r".*^@getter", re.MULTILINE | re.DOTALL)
functionIsAsyncRegExp = re.compile(r"(async)?\s*function", re.MULTILINE | re.DOTALL)
functionNameRegExp = re.compile(r"function\s+(\w+)\s*\(", re.MULTILINE | re.DOTALL)
functionOverriddenNameRegExp = re.compile(r".*^@overriddenName=(\".+\")$", re.MULTILINE | re.DOTALL)
functionParameterFinder = re.compile(r"^(?:async\s+)?function\s+(?:\w+)\s*\(((?:\s*\w+)?\s*(?:\s*,\s*\w+)*)?\s*\)", re.MULTILINE | re.DOTALL)

multilineCommentRegExp = re.compile(r"\/\*.*?\*\/", re.MULTILINE | re.DOTALL)
singleLineCommentRegExp = re.compile(r"\/\/.*?\n", re.MULTILINE | re.DOTALL)
keyValueAnnotationCommentRegExp = re.compile(r"^\/\/ @(\w+)=([^=]+?)\n", re.MULTILINE | re.DOTALL)
flagAnnotationCommentRegExp = re.compile(r"^\/\/ @(\w+)[^=]*?\n", re.MULTILINE | re.DOTALL)
lineWithOnlySingleLineCommentRegExp = re.compile(r"^\s*\/\/\n", re.MULTILINE | re.DOTALL)
lineWithTrailingSingleLineCommentRegExp = re.compile(r"\s*\/\/\n", re.MULTILINE | re.DOTALL)
leadingWhitespaceRegExp = re.compile(r"^ +", re.MULTILINE | re.DOTALL)
multipleEmptyLinesRegExp = re.compile(r"\n{2,}", re.MULTILINE | re.DOTALL)

class ParseException(Exception):
    pass


class Framework:
    def __init__(self, name):
        self._settings = _FRAMEWORK_CONFIG_MAP[name]
        self.name = name

    def setting(self, key, default=''):
        return self._settings.get(key, default)

    @staticmethod
    def fromString(frameworkString):
        if frameworkString == "JavaScriptCore":
            return Frameworks.JavaScriptCore

        if frameworkString == "WebCore":
            return Frameworks.WebCore

        raise ParseException("Unknown framework: %s" % frameworkString)


class Frameworks:
    JavaScriptCore = Framework("JavaScriptCore")
    WebCore = Framework("WebCore")


class BuiltinObject:
    def __init__(self, object_name, annotations, functions):
        self.object_name = object_name
        self.annotations = annotations
        self.functions = functions
        self.collection = None  # Set by the owning BuiltinsCollection

        for function in self.functions:
            function.object = self


class BuiltinFunction:
    def __init__(self, function_name, function_source, parameters, is_async, is_constructor, is_global_private, is_naked_constructor, intrinsic, overridden_name):
        self.function_name = function_name
        self.function_source = function_source
        self.parameters = parameters
        self.is_async = is_async
        self.is_constructor = is_constructor
        self.is_naked_constructor = is_naked_constructor
        self.is_global_private = is_global_private
        self.intrinsic = intrinsic
        self.overridden_name = overridden_name
        self.object = None  # Set by the owning BuiltinObject

    @staticmethod
    def fromString(function_string):
        function_source = multilineCommentRegExp.sub("", function_string)

        intrinsic = "NoIntrinsic"
        intrinsicMatch = functionIntrinsicRegExp.search(function_source)
        if intrinsicMatch:
            intrinsic = intrinsicMatch.group(1)
            function_source = functionIntrinsicRegExp.sub("", function_source)

        overridden_name = None
        overriddenNameMatch = functionOverriddenNameRegExp.search(function_source)
        if overriddenNameMatch:
            overridden_name = overriddenNameMatch.group(1)
            function_source = functionOverriddenNameRegExp.sub("", function_source)

        if not os.getenv("CONFIGURATION", "Debug").startswith("Debug"):
            function_source = lineWithOnlySingleLineCommentRegExp.sub("", function_source)
            function_source = lineWithTrailingSingleLineCommentRegExp.sub("\n", function_source)
            function_source = leadingWhitespaceRegExp.sub("", function_source)
            function_source = multipleEmptyLinesRegExp.sub("\n", function_source)

        function_name = functionNameRegExp.findall(function_source)[0]
        async_match = functionIsAsyncRegExp.match(function_source)
        is_async = async_match != None and async_match.group(1) == "async"
        is_constructor = functionIsConstructorRegExp.match(function_source) != None
        is_getter = functionIsGetterRegExp.match(function_source) != None
        is_global_private = functionGlobalPrivateRegExp.match(function_source) != None
        is_naked_constructor = functionNakedConstructorRegExp.match(function_source) != None
        if is_naked_constructor:
            is_constructor = True
        parameters = [s.strip() for s in functionParameterFinder.findall(function_source)[0].split(',')]
        if len(parameters[0]) == 0:
            parameters = []

        if is_getter and not overridden_name:
            overridden_name = "\"get %s\"" % (function_name)

        if not overridden_name:
            overridden_name = "static_cast<const char*>(nullptr)"

        return BuiltinFunction(function_name, function_source, parameters, is_async, is_constructor, is_global_private, is_naked_constructor, intrinsic, overridden_name)

    def __str__(self):
        interface = "%s(%s)" % (self.function_name, ', '.join(self.parameters))
        if self.is_constructor:
            interface = interface + " [Constructor]"

        if self.is_async:
            interface = "async " + interface

        return interface

    def __lt__(self, other):
        return self.function_name < other.function_name


class BuiltinsCollection:
    def __init__(self, framework_name):
        self._copyright_lines = set()
        self.objects = []
        self.framework = Framework.fromString(framework_name)
        log.debug("Created new Builtins collection.")

    def parse_builtins_file(self, filename, text):
        log.debug("Parsing builtins file: %s" % filename)

        parsed_copyrights = set(self._parse_copyright_lines(text))
        self._copyright_lines = self._copyright_lines.union(parsed_copyrights)

        log.debug("Found copyright lines:")
        for line in self._copyright_lines:
            log.debug(line)
        log.debug("")

        object_annotations = self._parse_annotations(text)

        object_name, ext = os.path.splitext(os.path.basename(filename))
        log.debug("Parsing object: %s" % object_name)

        parsed_functions = self._parse_functions(text)
        for function in parsed_functions:
            function.object = object_name

        log.debug("Parsed functions:")
        for func in parsed_functions:
            log.debug(func)
        log.debug("")

        new_object = BuiltinObject(object_name, object_annotations, parsed_functions)
        new_object.collection = self
        self.objects.append(new_object)

    def copyrights(self):
        owner_to_years = dict()
        copyrightYearRegExp = re.compile(r"(\d{4})[, ]{0,2}")
        ownerStartRegExp = re.compile(r"[^\d, ]")

        # Returns deduplicated copyrights keyed on the owner.
        for line in self._copyright_lines:
            years = set(copyrightYearRegExp.findall(line))
            ownerIndex = ownerStartRegExp.search(line).start()
            owner = line[ownerIndex:]
            log.debug("Found years: %s and owner: %s" % (years, owner))
            if owner not in owner_to_years:
                owner_to_years[owner] = set()

            owner_to_years[owner] = owner_to_years[owner].union(years)

        result = []

        for owner, years in list(owner_to_years.items()):
            sorted_years = list(years)
            sorted_years.sort()
            result.append("%s %s" % (', '.join(sorted_years), owner))

        return result

    def all_functions(self):
        result = []
        for object in self.objects:
            result.extend(object.functions)

        result.sort()
        return result

    def all_internal_functions(self):
        result = []
        for object in [o for o in self.objects if 'internal' in o.annotations]:
            result.extend(object.functions)

        result.sort()
        return result

    # Private methods.

    def _parse_copyright_lines(self, text):
        licenseBlock = multilineCommentRegExp.findall(text)[0]
        licenseBlock = licenseBlock[:licenseBlock.index("Redistribution")]

        copyrightLines = [Templates.DefaultCopyright]
        for line in licenseBlock.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 copyrightLines

    def _parse_annotations(self, text):
        annotations = {}

        for match in keyValueAnnotationCommentRegExp.finditer(text):
            (key, value) = match.group(1, 2)
            log.debug("Found annotation: '%s' => '%s'" % (key, value))
            if key in annotations:
                raise ParseException("Duplicate annotation found: %s" % key)

            annotations[key] = value

        for match in flagAnnotationCommentRegExp.finditer(text):
            key = match.group(1)
            log.debug("Found annotation: '%s' => 'TRUE'" % key)
            if key in annotations:
                raise ParseException("Duplicate annotation found: %s" % key)

            annotations[key] = True

        return annotations

    def _parse_functions(self, text):
        text = multilineCommentRegExp.sub("/**/", singleLineCommentRegExp.sub("//\n", text))

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

        functionStrings = [text[start:end].strip() for (start, end) in functionBounds]
        return list(map(BuiltinFunction.fromString, functionStrings))
