# SPDX-License-Identifier: GPL-2.0
#
# Copyright © 2023, Oracle and/or its affiliates.
# Author: Vegard Nossum <vegard.nossum@oracle.com>
#
# Add translation links to the top of the document.
#

import os

from docutils import nodes
from docutils.transforms import Transform

import sphinx
from sphinx import addnodes
from sphinx.errors import NoUri

all_languages = {
    # English is always first
    None: 'English',

    # Keep the rest sorted alphabetically
    'zh_CN': 'Chinese (Simplified)',
    'zh_TW': 'Chinese (Traditional)',
    'it_IT': 'Italian',
    'ja_JP': 'Japanese',
    'ko_KR': 'Korean',
    'sp_SP': 'Spanish',
}

class LanguagesNode(nodes.Element):
    def __init__(self, current_language, *args, **kwargs):
        super().__init__(*args, **kwargs)

        self.current_language = current_language

class TranslationsTransform(Transform):
    default_priority = 900

    def apply(self):
        app = self.document.settings.env.app
        docname = self.document.settings.env.docname

        this_lang_code = None
        components = docname.split(os.sep)
        if components[0] == 'translations' and len(components) > 2:
            this_lang_code = components[1]

            # normalize docname to be the untranslated one
            docname = os.path.join(*components[2:])

        new_nodes = LanguagesNode(all_languages[this_lang_code])

        for lang_code, lang_name in all_languages.items():
            if lang_code == this_lang_code:
                continue

            if lang_code is None:
                target_name = docname
            else:
                target_name = os.path.join('translations', lang_code, docname)

            pxref = addnodes.pending_xref('', refdomain='std',
                reftype='doc', reftarget='/' + target_name, modname=None,
                classname=None, refexplicit=True)
            pxref += nodes.Text(lang_name)
            new_nodes += pxref

        self.document.insert(0, new_nodes)

def process_languages(app, doctree, docname):
    for node in doctree.traverse(LanguagesNode):
        if app.builder.format not in ['html']:
            node.parent.remove(node)
            continue

        languages = []

        # Iterate over the child nodes; any resolved links will have
        # the type 'nodes.reference', while unresolved links will be
        # type 'nodes.Text'.
        languages = list(filter(lambda xref:
            isinstance(xref, nodes.reference), node.children))

        html_content = app.builder.templates.render('translations.html',
            context={
                'current_language': node.current_language,
                'languages': languages,
            })

        node.replace_self(nodes.raw('', html_content, format='html'))

def setup(app):
    app.add_node(LanguagesNode)
    app.add_transform(TranslationsTransform)
    app.connect('doctree-resolved', process_languages)

    return {
        'parallel_read_safe': True,
        'parallel_write_safe': True,
    }
