#!/usr/bin/env python
#############################################################################
##
## Copyright (C) 2016 The Qt Company Ltd.
## Contact: https://www.qt.io/licensing/
##
## This file is part of the test suite of the Qt Toolkit.
##
## $QT_BEGIN_LICENSE:GPL-EXCEPT$
## Commercial License Usage
## Licensees holding valid commercial Qt licenses may use this file in
## accordance with the commercial license agreement provided with the
## Software or, alternatively, in accordance with the terms contained in
## a written agreement between you and The Qt Company. For licensing terms
## and conditions see https://www.qt.io/terms-conditions. For further
## information use the contact form at https://www.qt.io/contact-us.
##
## GNU General Public License Usage
## Alternatively, this file may be used under the terms of the GNU
## General Public License version 3 as published by the Free Software
## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
## included in the packaging of this file. Please review the following
## information to ensure the GNU General Public License requirements will
## be met: https://www.gnu.org/licenses/gpl-3.0.html.
##
## $QT_END_LICENSE$
##
#############################################################################

import sys
import os
import xml.dom.minidom

class DraftResolution:
    # See http://www.unicode.org/cldr/process.html for description
    unconfirmed = 'unconfirmed'
    provisional = 'provisional'
    contributed = 'contributed'
    approved = 'approved'
    _values = { unconfirmed : 1, provisional : 2, contributed : 3, approved : 4 }
    def __init__(self, resolution):
        self.resolution = resolution
    def toInt(self):
        return DraftResolution._values[self.resolution]

class Error:
    def __init__(self, msg):
        self.msg = msg
    def __str__(self):
        return self.msg

doc_cache = {}
def parseDoc(file):
    if not doc_cache.has_key(file):
        doc_cache[file] = xml.dom.minidom.parse(file)
    return doc_cache[file]

def findChild(parent, tag_name, arg_name=None, arg_value=None, draft=None):
    for node in parent.childNodes:
        if node.nodeType != node.ELEMENT_NODE:
            continue
        if node.nodeName != tag_name:
            continue
        if arg_value:
            if not node.attributes.has_key(arg_name):
                continue
            if node.attributes[arg_name].nodeValue != arg_value:
                continue
        if draft:
            if not node.attributes.has_key('draft'):
                # if draft is not specified then it's approved
                return node
            value = node.attributes['draft'].nodeValue
            value = DraftResolution(value).toInt()
            exemplar = DraftResolution(draft).toInt()
            if exemplar > value:
                continue
        return node
    return False

def codeMapsFromFile(file):
    """Extract mappings of language, script and country codes to names.

    The file shall typically be common/main/en.xml, which contains a
    localeDisplayNames element with children languages, scripts and
    territories; each element in each of these has a code as its type
    attribute and its name as element content.  This returns a mapping
    withe keys 'language', 'script' and 'country', each of which
    has, as value, a mapping of the relevant codes to names.
    """
    parent = findChild(findChild(parseDoc(file), 'ldml'), 'localeDisplayNames')
    keys, result = {'languages': 'language', 'scripts': 'script', 'territories': 'country'}, {}
    for src, dst in keys.items():
        child = findChild(parent, src)
        data = result[dst] = {}
        for elt in child.childNodes:
            if elt.attributes and elt.attributes.has_key('type'):
                key, value = elt.attributes['type'].value, elt.childNodes[0].wholeText
                # Don't over-write previously-read data for an alt form:
                if elt.attributes.has_key('alt') and data.has_key(key):
                    continue
                data[key] = value

    return result

def findTagsInFile(file, path):
    doc = parseDoc(file)

    elt = doc.documentElement
    tag_spec_list = path.split("/")
    last_entry = None
    for tag_spec in tag_spec_list:
        tag_name = tag_spec
        arg_name = 'type'
        arg_value = ''
        left_bracket = tag_spec.find('[')
        if left_bracket != -1:
            tag_name = tag_spec[:left_bracket]
            arg_value = tag_spec[left_bracket+1:-1].split("=")
            if len(arg_value) == 2:
                arg_name = arg_value[0]
                arg_value = arg_value[1]
            else:
                arg_value = arg_value[0]
        elt = findChild(elt, tag_name, arg_name, arg_value)
        if not elt:
            return None
    ret = []
    if elt.childNodes:
        for node in elt.childNodes:
            if node.attributes:
                element = [node.nodeName, None]
                element[1] = node.attributes.items()
                ret.append(element)
    else:
        if elt.attributes:
            element = [elt.nodeName, None]
            element[1] = elt.attributes.items()
            ret.append(element)
    return ret

def _findEntryInFile(file, path, draft=None, attribute=None):
    doc = parseDoc(file)

    elt = doc.documentElement
    tag_spec_list = path.split("/")
    last_entry = None
    for i in range(len(tag_spec_list)):
        tag_spec = tag_spec_list[i]
        tag_name = tag_spec
        arg_name = 'type'
        arg_value = ''
        left_bracket = tag_spec.find('[')
        if left_bracket != -1:
            tag_name = tag_spec[:left_bracket]
            arg_value = tag_spec[left_bracket+1:-1].split("=")
            if len(arg_value) == 2:
                arg_name = arg_value[0].replace("@", "").replace("'", "")
                arg_value = arg_value[1]
            else:
                arg_value = arg_value[0]
        alias = findChild(elt, 'alias')
        if alias and alias.attributes['source'].nodeValue == 'locale':
            path = alias.attributes['path'].nodeValue
            aliaspath = tag_spec_list[:i] + path.split("/")
            def resolve(x, y):
                if y == '..':
                    return x[:-1]
                return x + [y]
            # resolve all dot-dot parts of the path
            aliaspath = reduce(resolve, aliaspath, [])
            # remove attribute specification that our xpathlite doesnt support
            aliaspath = map(lambda x: x.replace("@type=", "").replace("'", ""), aliaspath)
            # append the remaining path
            aliaspath = aliaspath + tag_spec_list[i:]
            aliaspath = "/".join(aliaspath)
            # "locale" aliases are special - we need to start lookup from scratch
            return (None, aliaspath)
        elt = findChild(elt, tag_name, arg_name, arg_value, draft)
        if not elt:
            return ("", None)
    if attribute is not None:
        if elt.attributes.has_key(attribute):
            return (elt.attributes[attribute].nodeValue, None)
        return (None, None)
    try:
        return (elt.firstChild.nodeValue, None)
    except:
        pass
    return (None, None)

def findAlias(file):
    doc = parseDoc(file)

    alias_elt = findChild(doc.documentElement, "alias")
    if not alias_elt:
        return False
    if not alias_elt.attributes.has_key('source'):
        return False
    return alias_elt.attributes['source'].nodeValue

lookup_chain_cache = {}
parent_locales = {}
def _fixedLookupChain(dirname, name):
    if lookup_chain_cache.has_key(name):
        return lookup_chain_cache[name]

    # see http://www.unicode.org/reports/tr35/#Parent_Locales
    if not parent_locales:
        for ns in findTagsInFile(dirname + "/../supplemental/supplementalData.xml", "parentLocales"):
            tmp = {}
            parent_locale = ""
            for data in ns[1:][0]: # ns looks like this: [u'parentLocale', [(u'parent', u'root'), (u'locales', u'az_Cyrl bs_Cyrl en_Dsrt ..')]]
                tmp[data[0]] = data[1]
                if data[0] == u"parent":
                    parent_locale = data[1]
            parent_locales[parent_locale] = tmp[u"locales"].split(" ")

    items = name.split("_")
    # split locale name into items and iterate through them from back to front
    # example: az_Latn_AZ => [az_Latn_AZ, az_Latn, az]
    items = list(reversed(map(lambda x: "_".join(items[:x+1]), range(len(items)))))

    for i in range(len(items)):
        item = items[i]
        for parent_locale in parent_locales.keys():
            for locale in parent_locales[parent_locale]:
                if item == locale:
                    if parent_locale == u"root":
                        items = items[:i+1]
                    else:
                        items = items[:i+1] + _fixedLookupChain(dirname, parent_locale)
                    lookup_chain_cache[name] = items
                    return items

    lookup_chain_cache[name] = items
    return items

def _findEntry(base, path, draft=None, attribute=None):
    if base.endswith(".xml"):
        base = base[:-4]
    (dirname, filename) = os.path.split(base)

    items = _fixedLookupChain(dirname, filename)
    for item in items:
        file = dirname + "/" + item + ".xml"
        if os.path.isfile(file):
            alias = findAlias(file)
            if alias:
                # if alias is found we should follow it and stop processing current file
                # see http://www.unicode.org/reports/tr35/#Common_Elements
                aliasfile = os.path.dirname(file) + "/" + alias + ".xml"
                if not os.path.isfile(aliasfile):
                    raise Error("findEntry: fatal error: found an alias '%s' to '%s', but the alias file couldn't be found" % (filename, alias))
                # found an alias, recurse into parsing it
                result = _findEntry(aliasfile, path, draft, attribute)
                return result
            (result, aliaspath) = _findEntryInFile(file, path, draft, attribute)
            if aliaspath:
                # start lookup again because of the alias source="locale"
                return _findEntry(base, aliaspath, draft, attribute)
            if result:
                return result
    return None

def findEntry(base, path, draft=None, attribute=None):
    file = base
    if base.endswith(".xml"):
        file = base
        base = base[:-4]
    else:
        file = base + ".xml"
    (dirname, filename) = os.path.split(base)

    result = None
    while path:
        result = _findEntry(base, path, draft, attribute)
        if result:
            return result
        (result, aliaspath) = _findEntryInFile(dirname + "/root.xml", path, draft, attribute)
        if result:
            return result
        if not aliaspath:
            raise Error("findEntry: fatal error: %s: cannot find key %s" % (filename, path))
        path = aliaspath

    return result

