# SPDX-FileCopyrightText: 2024 Carl Schwan <carl@carlschwan.eu>
# SPDX-License-Identifier: LGPL-2.0-or-later

import argparse
import polib
from lxml import etree
import os
import os.path
import subprocess
import glob
import json

def extract_strings(output_dir):
    print("Extracting")

    subprocess.run(["xgettext", "-C", "--from-code=UTF-8", "-ci18n", "-ki18n:1", "-ki18nc:1c,2", "server/web/assets/script.js", "server/web/index.html", "-o", output_dir + "/gpgol-js-web.pot"])

    cpp_files = glob.glob("client/**/*.cpp") + glob.glob("client/**/*.h")
    subprocess.run(["xgettext", "-C", "--from-code=UTF-8", "-kde", "-ci18n", "-ki18n:1", "-ki18nc:1c,2",
                    "-ki18ncp:1c,2,3", "-ki18nd:2", "-ki18ndc:2c,3", "-ki18ndp:2,3", "-ki18ndcp:2c,3,4",
                    "-kki18n:1", "-kki18nc:1c,2", "-kki18np:1,2", "-kki18ncp:1c,2,3",
                    "-kki18nd:2", "-kki18ndc:2c,3", "-kki18ndp:2,3", "-kki18ndcp:2c,3,4",
                    "-kxi18n:1", "-kxi18nc:1c,2", "-kxi18np:1,2", "-kxi18ncp:1c,2,3",
                    "-kxi18nd:2", "-kxi18ndc:2c,3", "-kxi18ndp:2,3", "-kxi18ndcp:2c,3,4",
                    "-kkxi18n:1", "-kkxi18nc:1c,2", "-kkxi18np:1,2", "-kkxi18ncp:1c,2,3",
                    "-kkxi18nd:2", "-kkxi18ndc:2c,3", "-kkxi18ndp:2,3", "-kkxi18ndcp:2c,3,4",
                    "-kkli18n:1", "-kkli18nc:1c,2", "-kkli18np:1,2", "-kkli18ncp:1c,2,3",
                    "-kklxi18n:1", "-kklxi18nc:1c,2", "-kklxi18np:1,2", "-kklxi18ncp:1c,2,3",
                    "-kI18N_NOOP:1", "-kI18NC_NOOP:1c,2",
                    "-kI18N_NOOP2:1c,2", "-kI18N_NOOP2_NOSTRIP:1c,2",
                    "-ktr2i18n:1", "-ktr2xi18n:1"] + cpp_files + ["-o", output_dir + "/gpgol-js-native.pot"])

    tree = etree.parse('server/manifest.xml')
    root = tree.getroot()

    xml_version1 = "{http://schemas.microsoft.com/office/mailappversionoverrides}";
    xml_version = "{http://schemas.microsoft.com/office/mailappversionoverrides/1.1}";
    xml_bt = "{http://schemas.microsoft.com/office/officeappbasictypes/1.0}"

    resources = root.find(xml_version1 + "VersionOverrides").find(xml_version + "VersionOverrides").find(xml_version + "Resources")

    short_strings = resources.find(xml_bt + "ShortStrings")
    long_strings = resources.find(xml_bt + "LongStrings")

    po = polib.POFile()
    po.metadata = {
        'Project-Id-Version': '1.0',
        'Report-Msgid-Bugs-To': 'you@example.com',
        'POT-Creation-Date': '2007-10-18 14:00+0100',
        'PO-Revision-Date': '2007-10-18 14:00+0100',
        'Last-Translator': 'you <you@example.com>',
        'Language-Team': 'English <yourteam@example.com>',
        'MIME-Version': '1.0',
        'Content-Type': 'text/plain; charset=utf-8',
        'Content-Transfer-Encoding': '8bit',
    }

    for child in short_strings:
        entry = polib.POEntry(
            msgid=child.get("DefaultValue"),
            msgstr=u'',
            occurrences=[('server/manigest.xml', child.sourceline)]
        )
        po.append(entry)

    for child in long_strings:
        entry = polib.POEntry(
            msgid=child.get("DefaultValue"),
            msgstr=u'',
            occurrences=[('server/manigest.xml', child.sourceline)]
        )
        po.append(entry)

    po.save(output_dir + '/manifest.pot')


def import_strings(input_dir):
    print("Importing")

    ## Import string for manifest.py
    parser = etree.XMLParser(remove_blank_text=True)
    tree = etree.parse('server/manifest.xml', parser)
    root = tree.getroot()

    xml_version1 = "{http://schemas.microsoft.com/office/mailappversionoverrides}";
    xml_version = "{http://schemas.microsoft.com/office/mailappversionoverrides/1.1}";
    xml_bt = "{http://schemas.microsoft.com/office/officeappbasictypes/1.0}"

    resources = root.find(xml_version1 + "VersionOverrides").find(xml_version + "VersionOverrides").find(xml_version + "Resources")

    short_strings = resources.find(xml_bt + "ShortStrings")
    long_strings = resources.find(xml_bt + "LongStrings")

    for lang in next(os.walk(input_dir))[1]:
        manifest_po_path = input_dir + '/' + lang + '/manifest.po'

        if not os.path.isfile(manifest_po_path):
            continue

        po = polib.pofile(manifest_po_path)

        def fill_string(child):
            for entry in po.translated_entries():
                if entry.msgid == child.get("DefaultValue"):
                    lang_xml = lang + '-' + lang.upper() # HACK to use same format as outlook wants
                    override_found = False
                    for override in child:
                        if override.get('Locale') == lang_xml:
                            override.set("Value", entry.msgstr)
                            override_found = True

                    if not override_found:
                        override = etree.Element(xml_bt + "Override")
                        override.set("Locale", lang_xml)
                        override.set("Value", entry.msgstr)
                        child.append(override)

        for string in short_strings:
            fill_string(string)

        for string in long_strings:
            fill_string(string)

    tree.write('server/manifest.xml', pretty_print=True)

    ## Import strings for web vue

    lang_obj = {}

    for lang in next(os.walk(input_dir))[1]:
        web_po_path = input_dir + '/' + lang + '/gpgol-js-web.po'

        if not os.path.isfile(web_po_path):
            continue

        po = polib.pofile(web_po_path)
        obj = {}

        for entry in po.translated_entries():
            obj[entry.msgid] = entry.msgstr

        lang_obj[lang + '-' + lang.upper()] = obj

    f = open("server/web/assets/translation.js", "w")
    f.write("const messages = " + json.dumps(lang_obj))
    f.close()


def main():
    parser = argparse.ArgumentParser()
    subparsers = parser.add_subparsers(title="subcommands",
                                       description='valid subcommands',
                                       dest='command')

    extract_parser = subparsers.add_parser('extract', help="Extract strings from source code")
    extract_parser.add_argument("output_dir", default="pot_dir")

    import_parser = subparsers.add_parser('import', help="Import strings to source code")
    import_parser.add_argument("input_dir", default="po")

    args = parser.parse_args()

    if args.command == 'extract':
        try:
            os.mkdir(args.output_dir)
        except FileExistsError:
            pass
        extract_strings(args.output_dir)
    elif args.command == 'import':
        import_strings(args.input_dir)

if __name__ == "__main__":
    main()
