#!/usr/bin/env python3
#
# This script is intended to be executed from Poedit
# See instructions in lang/README.
#
# As long as the xml files are well-formed XML documents with
# entry blocks like the following one (from scheme.xml) this
# script should have no problems extracting the strings.
# 		<entry ...>
# 			<short>Karaoke mode</short>
# 			<long>Hide pitch wave, notes and scoring.</long>
# 		</entry>

HEADER = r'''# Generated by xml_gettext.py
msgid ""
msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
'''

import sys

# Force pure python XML parser because we can't hook the C implementation
sys.modules['_elementtree'] = None
import xml.etree.ElementTree as ET

# Get line numbers, not provided by the stdlib implementation
class Parser(ET.XMLParser):
    def _start(self, *args, **kwargs):
        element = super()._start(*args, **kwargs)
        element.lineno = self.parser.CurrentLineNumber
        return element

_, pofile, *xmlfiles = sys.argv
assert pofile.lower().endswith(".po") or pofile.lower().endswith(".pot"), pofile
assert xmlfiles
for fn in xmlfiles:
    assert fn.lower().endswith(".xml"), fn

# Collect unique msgids in this dict
po = {}
for filename in xmlfiles:
    doc = ET.parse(filename, parser=Parser())
    parent = {c: p for p in doc.iter() for c in p}
    for elem in doc.iter():
        if elem.tag in ("short", "long") and not elem.text is None:
            text = (
                elem.text
                .replace('\\', '\\\\')
                .replace('"', '\\"')
                .replace('\n', '\\n')
            )
            s = parent[elem].find("short").text
            l = parent[elem].find("long").text
            info = f'#. {s}\n'
            info += f'#. {l}\n'
            for k, v in parent[elem].attrib.items():
                info += f"#. {k}: {v}\n"
            po[text] = (
                f'\n{info}'
                f'#: {filename}:{elem.lineno}\n'
                f'msgid "{text}"\n'
                'msgstr ""\n'
            )
        if elem.tag in ("enum") and not elem.text is None:
            text = (
                elem.text
                .replace('\\', '\\\\')
                .replace('"', '\\"')
                .replace('\n', '\\n')
            )
            s = parent[parent[elem]].find("short").text
            l = parent[parent[elem]].find("long").text
            info = f'#. {s}\n'
            info += f'#. {l}\n'
            for k, v in parent[parent[elem]].attrib.items():
                info += f"#. {k}: {v}\n"
            po[text] = (
                f'\n{info}'
                f'#: {filename}:{elem.lineno}\n'
                f'msgid "{text}"\n'
                'msgstr ""\n'
            )
        if elem.tag in ("ui"):
            text = (
                elem.attrib["unit"]
                .replace('\\', '\\\\')
                .replace('"', '\\"')
                .replace('\n', '\\n')
            )
            s = parent[elem].find("short").text
            l = parent[elem].find("long").text
            info = f'#. {s}\n'
            info += f'#. {l}\n'
            for k, v in parent[parent[elem]].attrib.items():
                info += f"#. {k}: {v}\n"
            po[text] = (
                f'\n{info}'
                f'#: {filename}:{elem.lineno}\n'
                f'msgid "{text}"\n'
                'msgstr ""\n'
            )

with open(pofile, "w") as f:
    f.write(HEADER)
    f.write("".join(po.values()))
