"""
Read the the NeXus NXDL types specification and find
all the valid types of units.  Write a restructured
text (.rst) document for use in the NeXus manual in
the NXDL chapter.
"""


from pathlib import Path
from typing import List

import lxml.etree

from ..globals.nxdl import XSD_NAMESPACE
from ..utils.types import PathLike


def generate_xsd_units_doc(
    xsd_file: PathLike, nodeMatchString: str, section: str
) -> List[str]:
    xsd_file = str(Path(xsd_file))
    tree = lxml.etree.parse(xsd_file)

    rst_lines = [f".. auto-generated by {__name__} -- DO NOT EDIT\n"]
    rst_lines.append("\n")

    rst_lines.append(f".. nodeMatchString : {nodeMatchString}\n")
    rst_lines.append("\n")

    db = {}
    ns = {"xs": XSD_NAMESPACE}
    node_list = tree.xpath("//xs:simpleType", namespaces=ns)

    # get the names of all the types of units
    members = []
    for node in node_list:
        if node.get("name") == nodeMatchString:
            union = node.xpath("xs:union", namespaces=ns)
            members = union[0].get("memberTypes", "").split()

    # get the definition of each type of units
    for node in node_list:
        node_name = node.get("name")
        if node_name is None:
            continue
        if "nxdl:" + node_name in members:
            words = node.xpath("xs:annotation/xs:documentation", namespaces=ns)[0]
            examples = []
            for example in words.iterchildren():
                nm = example.attrib.get("name")
                if nm is not None and nm == "example":
                    examples.append("``" + example.text + "``")
            a = words.text
            if len(examples) > 0:
                a = " ".join(a.split()) + ",\n\texample(s): " + " | ".join(examples)
            db[node_name] = a

            # for item in node.xpath("xs:restriction//xs:enumeration", namespaces=ns):
            #    key = "%s" % item.get("value")
            #    words = item.xpath("xs:annotation/xs:documentation", namespaces=ns)[0]
            #    db[key] = words.text

    # this list is too long to make this a table in latex
    # for two columns, a Sphinx fieldlist will do just as well
    for key in sorted(db):
        rst_lines.append(f".. index:: ! {key} ({section} type)\n\n")  # index entry
        rst_lines.append(f".. _{key}:\n\n")  # cross-reference point
        rst_lines.append(f":{key}:\n")
        for line in db[key].splitlines():
            rst_lines.append(f"    {line}\n")
        rst_lines.append("\n")
    return rst_lines
