# coding=utf-8
#
# QEMU hxtool .hx 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.
"""hxtool is a Sphinx extension that implements the hxtool-doc directive"""

# The purpose of this extension is to read fragments of rST
# from .hx files, and insert them all into the current document.
# The rST fragments are delimited by SRST/ERST lines.
# The conf.py file must set the hxtool_srctree config value to
# the root of the QEMU source tree.
# Each hxtool-doc:: directive takes one argument which is the
# path of the .hx file to process, relative to the source tree.

import os
import re
from enum import Enum

from docutils import nodes
from docutils.statemachine import ViewList
from docutils.parsers.rst import directives, Directive
from sphinx.errors import ExtensionError
from sphinx.util.docutils import switch_source_input
from sphinx.util.nodes import nested_parse_with_titles
import sphinx


__version__ = '1.0'

# We parse hx files with a state machine which may be in one of two
# states: reading the C code fragment, or inside a rST fragment.
class HxState(Enum):
    CTEXT = 1
    RST = 2

def serror(file, lnum, errtext):
    """Raise an exception giving a user-friendly syntax error message"""
    raise ExtensionError('%s line %d: syntax error: %s' % (file, lnum, errtext))

def parse_directive(line):
    """Return first word of line, if any"""
    return re.split(r'\W', line)[0]

def parse_defheading(file, lnum, line):
    """Handle a DEFHEADING directive"""
    # The input should be "DEFHEADING(some string)", though note that
    # the 'some string' could be the empty string. If the string is
    # empty we ignore the directive -- these are used only to add
    # blank lines in the plain-text content of the --help output.
    #
    # Return the heading text. We strip out any trailing ':' for
    # consistency with other headings in the rST documentation.
    match = re.match(r'DEFHEADING\((.*?):?\)', line)
    if match is None:
        serror(file, lnum, "Invalid DEFHEADING line")
    return match.group(1)

def parse_archheading(file, lnum, line):
    """Handle an ARCHHEADING directive"""
    # The input should be "ARCHHEADING(some string, other arg)",
    # though note that the 'some string' could be the empty string.
    # As with DEFHEADING, empty string ARCHHEADINGs will be ignored.
    #
    # Return the heading text. We strip out any trailing ':' for
    # consistency with other headings in the rST documentation.
    match = re.match(r'ARCHHEADING\((.*?):?,.*\)', line)
    if match is None:
        serror(file, lnum, "Invalid ARCHHEADING line")
    return match.group(1)

def parse_srst(file, lnum, line):
    """Handle an SRST directive"""
    # The input should be either "SRST", or "SRST(label)".
    match = re.match(r'SRST(\((.*?)\))?', line)
    if match is None:
        serror(file, lnum, "Invalid SRST line")
    return match.group(2)

class HxtoolDocDirective(Directive):
    """Extract rST fragments from the specified .hx file"""
    required_argument = 1
    optional_arguments = 1
    option_spec = {
        'hxfile': directives.unchanged_required
    }
    has_content = False

    def run(self):
        env = self.state.document.settings.env
        hxfile = env.config.hxtool_srctree + '/' + self.arguments[0]

        # Tell sphinx of the dependency
        env.note_dependency(os.path.abspath(hxfile))

        state = HxState.CTEXT
        # We build up lines of rST in this ViewList, which we will
        # later put into a 'section' node.
        rstlist = ViewList()
        current_node = None
        node_list = []

        with open(hxfile) as f:
            lines = (l.rstrip() for l in f)
            for lnum, line in enumerate(lines, 1):
                directive = parse_directive(line)

                if directive == 'HXCOMM':
                    pass
                elif directive == 'SRST':
                    if state == HxState.RST:
                        serror(hxfile, lnum, 'expected ERST, found SRST')
                    else:
                        state = HxState.RST
                        label = parse_srst(hxfile, lnum, line)
                        if label:
                            rstlist.append("", hxfile, lnum - 1)
                            # Build label as _DOCNAME-HXNAME-LABEL
                            hx = os.path.splitext(os.path.basename(hxfile))[0]
                            refline = ".. _" + env.docname + "-" + hx + \
                                "-" + label + ":"
                            rstlist.append(refline, hxfile, lnum - 1)
                elif directive == 'ERST':
                    if state == HxState.CTEXT:
                        serror(hxfile, lnum, 'expected SRST, found ERST')
                    else:
                        state = HxState.CTEXT
                elif directive == 'DEFHEADING' or directive == 'ARCHHEADING':
                    if directive == 'DEFHEADING':
                        heading = parse_defheading(hxfile, lnum, line)
                    else:
                        heading = parse_archheading(hxfile, lnum, line)
                    if heading == "":
                        continue
                    # Put the accumulated rST into the previous node,
                    # and then start a fresh section with this heading.
                    if len(rstlist) > 0:
                        if current_node is None:
                            # We had some rST fragments before the first
                            # DEFHEADING. We don't have a section to put
                            # these in, so rather than magicing up a section,
                            # make it a syntax error.
                            serror(hxfile, lnum,
                                   'first DEFHEADING must precede all rST text')
                        self.do_parse(rstlist, current_node)
                        rstlist = ViewList()
                    if current_node is not None:
                        node_list.append(current_node)
                    section_id = 'hxtool-%d' % env.new_serialno('hxtool')
                    current_node = nodes.section(ids=[section_id])
                    current_node += nodes.title(heading, heading)
                else:
                    # Not a directive: put in output if we are in rST fragment
                    if state == HxState.RST:
                        # Sphinx counts its lines from 0
                        rstlist.append(line, hxfile, lnum - 1)

        if current_node is None:
            # We don't have multiple sections, so just parse the rst
            # fragments into a dummy node so we can return the children.
            current_node = nodes.section()
            self.do_parse(rstlist, current_node)
            return current_node.children
        else:
            # Put the remaining accumulated rST into the last section, and
            # return all the sections.
            if len(rstlist) > 0:
                self.do_parse(rstlist, current_node)
            node_list.append(current_node)
            return node_list

    # 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.
    def do_parse(self, result, node):
        with switch_source_input(self.state, result):
            nested_parse_with_titles(self.state, result, node)


def setup(app):
    """ Register hxtool-doc directive with Sphinx"""
    app.add_config_value('hxtool_srctree', None, 'env')
    app.add_directive('hxtool-doc', HxtoolDocDirective)

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