#!/usr/bin/env python

# Copyright (C) 2018 Andy VanWagoner (andy@vanwagoner.family)
#
# 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 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 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.

# This tool processes the IANA file language-subtag-registry.txt to create
# information required to canonicalize language tags according to ECMA 402 and
# RFC 5646 Section 4.5.
# https://www.iana.org/assignments/language-subtag-registry
# https://tc39.github.io/ecma402/#sec-canonicalizelanguagetag
# https://tools.ietf.org/html/rfc5646#section-4.5

import sys
import optparse
import os

header = """// DO NO EDIT! - This file was generated by """ + __file__ + """
"""


footer = """
"""


def openOrExit(path, mode):
    try:
        if sys.version_info.major >= 3:
            return open(path, mode, encoding="UTF-8")
        else:
            return open(path, mode)
    except IOError as e:
        print("I/O error opening {0}, ({1}): {2}".format(path, e.errno, e.strerror))
        exit(1)


class SubtagRegistry:
    def __init__(self):
        self.languageMap = {}
        self.extlangMap = {}
        self.regionMap = {}
        self.redundantMap = {}
        self.grandfatheredMap = {}

    def parse(self, file):
        record = {}
        for line in file:
            line = line.strip()
            if line.startswith("#"):
                continue

            if line == "%%":
                self.process(record)
                record = {}
                continue

            if ":" in line:
                key, value = line.split(":", 1)
                record[key.strip()] = value.strip()
            else:
                # Description often continues on the next line
                record[key.strip()] = " " + line
        self.process(record)

    def process(self, record):
        if "File-Date" in record:
            self.fileDate = record["File-Date"]

        if not ("Type" in record):
            return

        type = record["Type"]
        preferred = record.get("Preferred-Value")
        if type == "language" and preferred:
            self.languageMap[record["Subtag"]] = preferred
        elif type == "extlang":
            self.extlangMap[record["Subtag"]] = record["Prefix"]
        elif type == "region" and preferred:
            self.regionMap[record["Subtag"]] = preferred
        elif type == "redundant" and preferred:
            lang = self.extlangMap.get(preferred)
            if "{}-{}".format(lang, preferred) != record["Tag"]:
                self.redundantMap[record["Tag"]] = preferred
        elif type == "variant" and preferred:
            key = "{}-{}".format(record['Prefix'], record['Subtag'])
            if preferred == "alalc97":
                preferred = "ja-Latn-alalc97"
            self.redundantMap[key] = preferred
        elif type == "grandfathered":
            key = record["Tag"].lower()
            value = record.get("Preferred-Value", key)
            self.grandfatheredMap[key] = value

    def dump(self, file):
        if self.fileDate:
            file.write("// language-subtag-registry file date: {}\n".format(self.fileDate))
        file.write("\n#pragma once\n")
        file.write("\n#if ENABLE(INTL)\n")
        file.write("\nnamespace JSC {\n")
        self.dumpLookup(file, "intlPreferredLanguageTag", self.languageMap)
        self.dumpLookup(file, "intlPreferredExtlangTag", self.extlangMap)
        self.dumpLookup(file, "intlPreferredRegionTag", self.regionMap)
        self.dumpLookup(file, "intlRedundantLanguageTag", self.redundantMap)
        self.dumpLookup(file, "intlGrandfatheredLanguageTag", self.grandfatheredMap)
        file.write("\n} // namespace JSC\n")
        file.write("\n#endif // ENABLE(INTL)\n")

    def dumpLookup(self, file, name, map):
        file.write("\nstatic String {}(const String& tag)\n{{\n".format(name))
        file.write("    // {} possible replacements\n".format(len(map)))
        # We could pick the lookup implementation per map if desired
        # Anecdotal perf: if > switch > hash (slowest)
        # Code complexity: switch > if > hash (least complex)
        # Algo complexity: if = O(N) > switch > O(log N) > hash = O(1) (least complex)
        self.dumpIfLookup(file, name, map)
        file.write("}\n")

    def dumpHashLookup(self, file, name, map):
        file.write("    static NeverDestroyed<HashMap<String, String>> cache;\n")
        file.write("    HashMap<String, String>& map = cache.get();\n")
        file.write("    if (UNLIKELY(map.isEmpty())) {\n")
        entries = ["        map.add(\"{}\"_s, \"{}\"_s);\n".format(k, v) for k, v in map.items()]
        entries.sort()
        file.write("".join(entries))
        file.write("    }\n")
        file.write("    return map.get(tag);\n")

    def dumpIfLookup(self, file, name, map):
        entries = ["    if (tag == \"{}\")\n        return \"{}\"_s;".format(k, v) for k, v in map.items()]
        entries.sort()
        file.write("\n".join(entries))
        file.write("\n    return String();\n")

    def dumpSwitchLookup(self, file, name, map):
        tree = {}
        for k, v in map.items():
            node = tree
            for char in k:
                if not (char in node):
                    node[char] = {}
                node = node[char]
            node["value"] = v
        self.dumpSwitchLookupTree(file, tree, 0)
        file.write("\n    return String();\n")

    def dumpSwitchLookupTree(self, file, tree, level):
        indent = "".ljust((level + 1) * 4)
        if "value" in tree:
            file.write(indent + "if (tag.length() == {})\n".format(level))
            file.write(indent + "    return \"{}\"_s;\n".format(tree["value"]))
            del tree["value"]
        keys = tree.keys()
        keys.sort()
        if len(keys) == 0:
            return
        file.write(indent + "switch (tag[{}]) {{\n".format(level))
        for key in keys:
            file.write(indent + "case {}:\n".format(ord(key)))
            self.dumpSwitchLookupTree(file, tree[key], level + 1)
            file.write(indent + "    break;\n")
        file.write(indent + "default: break;\n")
        file.write(indent + "}\n")


if __name__ == "__main__":
    parser = optparse.OptionParser(usage="usage: %prog <language-subtag-registry.txt> <IntlCanonicalizeLanguage.h>")
    (options, args) = parser.parse_args()

    if len(args) != 2:
        parser.error("<language-subtag-registry.txt> <IntlCanonicalizeLanguage.h>")

    registryPath = args[0]
    intlCanonHPath = args[1]

    registryFile = openOrExit(registryPath, "r")
    intlCanonHFile = openOrExit(intlCanonHPath, "w")

    intlCanonHFile.write(header)

    registry = SubtagRegistry()
    registry.parse(registryFile)
    registry.dump(intlCanonHFile)

    intlCanonHFile.write(footer)

    exit(0)
