#! /usr/bin/env python3
#
# SPDX-License-Identifier: GPL-2.0-only
#

import sys
try:
    import xml.etree.cElementTree as etree
except:
    import xml.etree.ElementTree as etree

def child (elem, name):
    for e in elem.getchildren():
        if e.tag == name:
            return e
    return None

def children (elem, name=None):
    l = elem.getchildren()
    if name:
        l = [e for e in l if e.tag == name]
    return l

if len(sys.argv) < 2 or sys.argv[1] in ('-h', '--help'):
    print('oe-trim-schemas: error: the following arguments are required: schema\n'
          'Usage: oe-trim-schemas schema\n\n'
          'OpenEmbedded trim schemas - remove unneeded schema locale translations\n'
          '                            from gconf schema files\n\n'
          'arguments:\n'
          '  schema                gconf schema file to trim\n')
    sys.exit(2)

xml = etree.parse(sys.argv[1])

for schema in child(xml.getroot(), "schemalist").getchildren():
    e = child(schema, "short")
    if e is not None:
        schema.remove(e)

    e = child(schema, "long")
    if e is not None:
        schema.remove(e)

    for locale in children(schema, "locale"):
        # One locale must exist so leave C locale...
        a = locale.attrib.get("name")
        if a == 'C':
            continue
        e = child(locale, "default")
        if e is None:
            schema.remove(locale)
        else:
            e = child(locale, "short")
            if e is not None:
                locale.remove(e)
            e = child(locale, "long")
            if e is not None:
                locale.remove(e)

xml.write(sys.stdout, "UTF-8")

