# coding=utf-8
#
# QEMU qapidoc QAPI file parsing extension
#
# Copyright (c) 2020 Linaro
#
# This work is licensed under the terms of the GNU GPLv2 or later.
# See the COPYING file in the top-level directory.

"""
qapidoc is a Sphinx extension that implements the qapi-doc directive

The purpose of this extension is to read the documentation comments
in QAPI schema files, and insert them all into the current document.

It implements one new rST directive, "qapi-doc::".
Each qapi-doc:: directive takes one argument, which is the
pathname of the schema file to process, relative to the source tree.

The docs/conf.py file must set the qapidoc_srctree config value to
the root of the QEMU source tree.

The Sphinx documentation on writing extensions is at:
https://www.sphinx-doc.org/en/master/development/index.html
"""

import os
import re

from docutils import nodes
from docutils.statemachine import ViewList
from docutils.parsers.rst import directives, Directive
from sphinx.errors import ExtensionError
from sphinx.util.nodes import nested_parse_with_titles
import sphinx
from qapi.gen import QAPISchemaVisitor
from qapi.error import QAPIError, QAPISemError
from qapi.schema import QAPISchema


# Sphinx up to 1.6 uses AutodocReporter; 1.7 and later
# use switch_source_input. Check borrowed from kerneldoc.py.
Use_SSI = sphinx.__version__[:3] >= '1.7'
if Use_SSI:
    from sphinx.util.docutils import switch_source_input
else:
    from sphinx.ext.autodoc import AutodocReporter


__version__ = '1.0'


# Function borrowed from pydash, which is under the MIT license
def intersperse(iterable, separator):
    """Yield the members of *iterable* interspersed with *separator*."""
    iterable = iter(iterable)
    yield next(iterable)
    for item in iterable:
        yield separator
        yield item


class QAPISchemaGenRSTVisitor(QAPISchemaVisitor):
    """A QAPI schema visitor which generates docutils/Sphinx nodes

    This class builds up a tree of docutils/Sphinx nodes corresponding
    to documentation for the various QAPI objects. To use it, first
    create a QAPISchemaGenRSTVisitor object, and call its
    visit_begin() method.  Then you can call one of the two methods
    'freeform' (to add documentation for a freeform documentation
    chunk) or 'symbol' (to add documentation for a QAPI symbol). These
    will cause the visitor to build up the tree of document
    nodes. Once you've added all the documentation via 'freeform' and
    'symbol' method calls, you can call 'get_document_nodes' to get
    the final list of document nodes (in a form suitable for returning
    from a Sphinx directive's 'run' method).
    """
    def __init__(self, sphinx_directive):
        self._cur_doc = None
        self._sphinx_directive = sphinx_directive
        self._top_node = nodes.section()
        self._active_headings = [self._top_node]

    def _make_dlitem(self, term, defn):
        """Return a dlitem node with the specified term and definition.

        term should be a list of Text and literal nodes.
        defn should be one of:
        - a string, which will be handed to _parse_text_into_node
        - a list of Text and literal nodes, which will be put into
          a paragraph node
        """
        dlitem = nodes.definition_list_item()
        dlterm = nodes.term('', '', *term)
        dlitem += dlterm
        if defn:
            dldef = nodes.definition()
            if isinstance(defn, list):
                dldef += nodes.paragraph('', '', *defn)
            else:
                self._parse_text_into_node(defn, dldef)
            dlitem += dldef
        return dlitem

    def _make_section(self, title):
        """Return a section node with optional title"""
        section = nodes.section(ids=[self._sphinx_directive.new_serialno()])
        if title:
            section += nodes.title(title, title)
        return section

    def _nodes_for_ifcond(self, ifcond, with_if=True):
        """Return list of Text, literal nodes for the ifcond

        Return a list which gives text like ' (If: condition)'.
        If with_if is False, we don't return the "(If: " and ")".
        """

        doc = ifcond.docgen()
        if not doc:
            return []
        doc = nodes.literal('', doc)
        if not with_if:
            return [doc]

        nodelist = [nodes.Text(' ('), nodes.strong('', 'If: ')]
        nodelist.append(doc)
        nodelist.append(nodes.Text(')'))
        return nodelist

    def _nodes_for_one_member(self, member):
        """Return list of Text, literal nodes for this member

        Return a list of doctree nodes which give text like
        'name: type (optional) (If: ...)' suitable for use as the
        'term' part of a definition list item.
        """
        term = [nodes.literal('', member.name)]
        if member.type.doc_type():
            term.append(nodes.Text(': '))
            term.append(nodes.literal('', member.type.doc_type()))
        if member.optional:
            term.append(nodes.Text(' (optional)'))
        if member.ifcond.is_present():
            term.extend(self._nodes_for_ifcond(member.ifcond))
        return term

    def _nodes_for_variant_when(self, variants, variant):
        """Return list of Text, literal nodes for variant 'when' clause

        Return a list of doctree nodes which give text like
        'when tagname is variant (If: ...)' suitable for use in
        the 'variants' part of a definition list.
        """
        term = [nodes.Text(' when '),
                nodes.literal('', variants.tag_member.name),
                nodes.Text(' is '),
                nodes.literal('', '"%s"' % variant.name)]
        if variant.ifcond.is_present():
            term.extend(self._nodes_for_ifcond(variant.ifcond))
        return term

    def _nodes_for_members(self, doc, what, base=None, variants=None):
        """Return list of doctree nodes for the table of members"""
        dlnode = nodes.definition_list()
        for section in doc.args.values():
            term = self._nodes_for_one_member(section.member)
            # TODO drop fallbacks when undocumented members are outlawed
            if section.text:
                defn = section.text
            elif (variants and variants.tag_member == section.member
                  and not section.member.type.doc_type()):
                values = section.member.type.member_names()
                defn = [nodes.Text('One of ')]
                defn.extend(intersperse([nodes.literal('', v) for v in values],
                                        nodes.Text(', ')))
            else:
                defn = [nodes.Text('Not documented')]

            dlnode += self._make_dlitem(term, defn)

        if base:
            dlnode += self._make_dlitem([nodes.Text('The members of '),
                                         nodes.literal('', base.doc_type())],
                                        None)

        if variants:
            for v in variants.variants:
                if v.type.is_implicit():
                    assert not v.type.base and not v.type.variants
                    for m in v.type.local_members:
                        term = self._nodes_for_one_member(m)
                        term.extend(self._nodes_for_variant_when(variants, v))
                        dlnode += self._make_dlitem(term, None)
                else:
                    term = [nodes.Text('The members of '),
                            nodes.literal('', v.type.doc_type())]
                    term.extend(self._nodes_for_variant_when(variants, v))
                    dlnode += self._make_dlitem(term, None)

        if not dlnode.children:
            return []

        section = self._make_section(what)
        section += dlnode
        return [section]

    def _nodes_for_enum_values(self, doc):
        """Return list of doctree nodes for the table of enum values"""
        seen_item = False
        dlnode = nodes.definition_list()
        for section in doc.args.values():
            termtext = [nodes.literal('', section.member.name)]
            if section.member.ifcond.is_present():
                termtext.extend(self._nodes_for_ifcond(section.member.ifcond))
            # TODO drop fallbacks when undocumented members are outlawed
            if section.text:
                defn = section.text
            else:
                defn = [nodes.Text('Not documented')]

            dlnode += self._make_dlitem(termtext, defn)
            seen_item = True

        if not seen_item:
            return []

        section = self._make_section('Values')
        section += dlnode
        return [section]

    def _nodes_for_arguments(self, doc, boxed_arg_type):
        """Return list of doctree nodes for the arguments section"""
        if boxed_arg_type:
            assert not doc.args
            section = self._make_section('Arguments')
            dlnode = nodes.definition_list()
            dlnode += self._make_dlitem(
                [nodes.Text('The members of '),
                 nodes.literal('', boxed_arg_type.name)],
                None)
            section += dlnode
            return [section]

        return self._nodes_for_members(doc, 'Arguments')

    def _nodes_for_features(self, doc):
        """Return list of doctree nodes for the table of features"""
        seen_item = False
        dlnode = nodes.definition_list()
        for section in doc.features.values():
            dlnode += self._make_dlitem([nodes.literal('', section.name)],
                                        section.text)
            seen_item = True

        if not seen_item:
            return []

        section = self._make_section('Features')
        section += dlnode
        return [section]

    def _nodes_for_example(self, exampletext):
        """Return list of doctree nodes for a code example snippet"""
        return [nodes.literal_block(exampletext, exampletext)]

    def _nodes_for_sections(self, doc):
        """Return list of doctree nodes for additional sections"""
        nodelist = []
        for section in doc.sections:
            if section.name and section.name == 'TODO':
                # Hide TODO: sections
                continue
            snode = self._make_section(section.name)
            if section.name and section.name.startswith('Example'):
                snode += self._nodes_for_example(section.text)
            else:
                self._parse_text_into_node(section.text, snode)
            nodelist.append(snode)
        return nodelist

    def _nodes_for_if_section(self, ifcond):
        """Return list of doctree nodes for the "If" section"""
        nodelist = []
        if ifcond.is_present():
            snode = self._make_section('If')
            snode += nodes.paragraph(
                '', '', *self._nodes_for_ifcond(ifcond, with_if=False)
            )
            nodelist.append(snode)
        return nodelist

    def _add_doc(self, typ, sections):
        """Add documentation for a command/object/enum...

        We assume we're documenting the thing defined in self._cur_doc.
        typ is the type of thing being added ("Command", "Object", etc)

        sections is a list of nodes for sections to add to the definition.
        """

        doc = self._cur_doc
        snode = nodes.section(ids=[self._sphinx_directive.new_serialno()])
        snode += nodes.title('', '', *[nodes.literal(doc.symbol, doc.symbol),
                                       nodes.Text(' (' + typ + ')')])
        self._parse_text_into_node(doc.body.text, snode)
        for s in sections:
            if s is not None:
                snode += s
        self._add_node_to_current_heading(snode)

    def visit_enum_type(self, name, info, ifcond, features, members, prefix):
        doc = self._cur_doc
        self._add_doc('Enum',
                      self._nodes_for_enum_values(doc)
                      + self._nodes_for_features(doc)
                      + self._nodes_for_sections(doc)
                      + self._nodes_for_if_section(ifcond))

    def visit_object_type(self, name, info, ifcond, features,
                          base, members, variants):
        doc = self._cur_doc
        if base and base.is_implicit():
            base = None
        self._add_doc('Object',
                      self._nodes_for_members(doc, 'Members', base, variants)
                      + self._nodes_for_features(doc)
                      + self._nodes_for_sections(doc)
                      + self._nodes_for_if_section(ifcond))

    def visit_alternate_type(self, name, info, ifcond, features, variants):
        doc = self._cur_doc
        self._add_doc('Alternate',
                      self._nodes_for_members(doc, 'Members')
                      + self._nodes_for_features(doc)
                      + self._nodes_for_sections(doc)
                      + self._nodes_for_if_section(ifcond))

    def visit_command(self, name, info, ifcond, features, arg_type,
                      ret_type, gen, success_response, boxed, allow_oob,
                      allow_preconfig, coroutine):
        doc = self._cur_doc
        self._add_doc('Command',
                      self._nodes_for_arguments(doc,
                                                arg_type if boxed else None)
                      + self._nodes_for_features(doc)
                      + self._nodes_for_sections(doc)
                      + self._nodes_for_if_section(ifcond))

    def visit_event(self, name, info, ifcond, features, arg_type, boxed):
        doc = self._cur_doc
        self._add_doc('Event',
                      self._nodes_for_arguments(doc,
                                                arg_type if boxed else None)
                      + self._nodes_for_features(doc)
                      + self._nodes_for_sections(doc)
                      + self._nodes_for_if_section(ifcond))

    def symbol(self, doc, entity):
        """Add documentation for one symbol to the document tree

        This is the main entry point which causes us to add documentation
        nodes for a symbol (which could be a 'command', 'object', 'event',
        etc). We do this by calling 'visit' on the schema entity, which
        will then call back into one of our visit_* methods, depending
        on what kind of thing this symbol is.
        """
        self._cur_doc = doc
        entity.visit(self)
        self._cur_doc = None

    def _start_new_heading(self, heading, level):
        """Start a new heading at the specified heading level

        Create a new section whose title is 'heading' and which is placed
        in the docutils node tree as a child of the most recent level-1
        heading. Subsequent document sections (commands, freeform doc chunks,
        etc) will be placed as children of this new heading section.
        """
        if len(self._active_headings) < level:
            raise QAPISemError(self._cur_doc.info,
                               'Level %d subheading found outside a '
                               'level %d heading'
                               % (level, level - 1))
        snode = self._make_section(heading)
        self._active_headings[level - 1] += snode
        self._active_headings = self._active_headings[:level]
        self._active_headings.append(snode)

    def _add_node_to_current_heading(self, node):
        """Add the node to whatever the current active heading is"""
        self._active_headings[-1] += node

    def freeform(self, doc):
        """Add a piece of 'freeform' documentation to the document tree

        A 'freeform' document chunk doesn't relate to any particular
        symbol (for instance, it could be an introduction).

        If the freeform document starts with a line of the form
        '= Heading text', this is a section or subsection heading, with
        the heading level indicated by the number of '=' signs.
        """

        # QAPIDoc documentation says free-form documentation blocks
        # must have only a body section, nothing else.
        assert not doc.sections
        assert not doc.args
        assert not doc.features
        self._cur_doc = doc

        text = doc.body.text
        if re.match(r'=+ ', text):
            # Section/subsection heading (if present, will always be
            # the first line of the block)
            (heading, _, text) = text.partition('\n')
            (leader, _, heading) = heading.partition(' ')
            self._start_new_heading(heading, len(leader))
            if text == '':
                return

        node = self._make_section(None)
        self._parse_text_into_node(text, node)
        self._add_node_to_current_heading(node)
        self._cur_doc = None

    def _parse_text_into_node(self, doctext, node):
        """Parse a chunk of QAPI-doc-format text into the node

        The doc comment can contain most inline rST markup, including
        bulleted and enumerated lists.
        As an extra permitted piece of markup, @var will be turned
        into ``var``.
        """

        # Handle the "@var means ``var`` case
        doctext = re.sub(r'@([\w-]+)', r'``\1``', doctext)

        rstlist = ViewList()
        for line in doctext.splitlines():
            # The reported line number will always be that of the start line
            # of the doc comment, rather than the actual location of the error.
            # Being more precise would require overhaul of the QAPIDoc class
            # to track lines more exactly within all the sub-parts of the doc
            # comment, as well as counting lines here.
            rstlist.append(line, self._cur_doc.info.fname,
                           self._cur_doc.info.line)
        # Append a blank line -- in some cases rST syntax errors get
        # attributed to the line after one with actual text, and if there
        # isn't anything in the ViewList corresponding to that then Sphinx
        # 1.6's AutodocReporter will then misidentify the source/line location
        # in the error message (usually attributing it to the top-level
        # .rst file rather than the offending .json file). The extra blank
        # line won't affect the rendered output.
        rstlist.append("", self._cur_doc.info.fname, self._cur_doc.info.line)
        self._sphinx_directive.do_parse(rstlist, node)

    def get_document_nodes(self):
        """Return the list of docutils nodes which make up the document"""
        return self._top_node.children


class QAPISchemaGenDepVisitor(QAPISchemaVisitor):
    """A QAPI schema visitor which adds Sphinx dependencies each module

    This class calls the Sphinx note_dependency() function to tell Sphinx
    that the generated documentation output depends on the input
    schema file associated with each module in the QAPI input.
    """
    def __init__(self, env, qapidir):
        self._env = env
        self._qapidir = qapidir

    def visit_module(self, name):
        if name != "./builtin":
            qapifile = self._qapidir + '/' + name
            self._env.note_dependency(os.path.abspath(qapifile))
        super().visit_module(name)


class QAPIDocDirective(Directive):
    """Extract documentation from the specified QAPI .json file"""
    required_argument = 1
    optional_arguments = 1
    option_spec = {
        'qapifile': directives.unchanged_required
    }
    has_content = False

    def new_serialno(self):
        """Return a unique new ID string suitable for use as a node's ID"""
        env = self.state.document.settings.env
        return 'qapidoc-%d' % env.new_serialno('qapidoc')

    def run(self):
        env = self.state.document.settings.env
        qapifile = env.config.qapidoc_srctree + '/' + self.arguments[0]
        qapidir = os.path.dirname(qapifile)

        try:
            schema = QAPISchema(qapifile)

            # First tell Sphinx about all the schema files that the
            # output documentation depends on (including 'qapifile' itself)
            schema.visit(QAPISchemaGenDepVisitor(env, qapidir))

            vis = QAPISchemaGenRSTVisitor(self)
            vis.visit_begin(schema)
            for doc in schema.docs:
                if doc.symbol:
                    vis.symbol(doc, schema.lookup_entity(doc.symbol))
                else:
                    vis.freeform(doc)
            return vis.get_document_nodes()
        except QAPIError as err:
            # Launder QAPI parse errors into Sphinx extension errors
            # so they are displayed nicely to the user
            raise ExtensionError(str(err)) from err

    def do_parse(self, rstlist, node):
        """Parse rST source lines and add them to the specified node

        Take the list of rST source lines rstlist, parse them as
        rST, and add the resulting docutils nodes as children of node.
        The nodes are parsed in a way that allows them to include
        subheadings (titles) without confusing the rendering of
        anything else.
        """
        # This is from kerneldoc.py -- it works around an API change in
        # Sphinx between 1.6 and 1.7. Unlike kerneldoc.py, we use
        # sphinx.util.nodes.nested_parse_with_titles() rather than the
        # plain self.state.nested_parse(), and so we can drop the saving
        # of title_styles and section_level that kerneldoc.py does,
        # because nested_parse_with_titles() does that for us.
        if Use_SSI:
            with switch_source_input(self.state, rstlist):
                nested_parse_with_titles(self.state, rstlist, node)
        else:
            save = self.state.memo.reporter
            self.state.memo.reporter = AutodocReporter(
                rstlist, self.state.memo.reporter)
            try:
                nested_parse_with_titles(self.state, rstlist, node)
            finally:
                self.state.memo.reporter = save


def setup(app):
    """ Register qapi-doc directive with Sphinx"""
    app.add_config_value('qapidoc_srctree', None, 'env')
    app.add_directive('qapi-doc', QAPIDocDirective)

    return dict(
        version=__version__,
        parallel_read_safe=True,
        parallel_write_safe=True
    )
