# -*- coding: utf-8 -*-
"""
    sphinx.builders.devhelp
    ~~~~~~~~~~~~~~~~~~~~~~~

    Build HTML documentation and Devhelp_ support files.

    .. _Devhelp: http://live.gnome.org/devhelp

    :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS.
    :license: BSD, see LICENSE for details.
"""

import gzip
import re
import os

from docutils import nodes

from sphinx import addnodes
from sphinx.builders.html import StandaloneHTMLBuilder

import xml.etree.ElementTree as etree


class Devhelp2Builder(StandaloneHTMLBuilder):
    """
    Builder that also outputs GNOME Devhelp file.
    """
    name = 'devhelp2'

    # don't copy the reST source
    copysource = False
    supported_image_types = ['image/png', 'image/gif', 'image/jpeg']

    # don't add links
    add_permalinks = False
    # don't add sidebar etc.
    embedded = True

    def init(self):
        StandaloneHTMLBuilder.init(self)
        self.out_suffix = '.html'

    def handle_finish(self):
        self.build_devhelp(self.outdir, self.config.devhelp_basename)

    def build_devhelp(self, outdir, outname):
        self.info('dumping devhelp index...')

        # Basic info
        root = etree.Element('book',
                             title=self.config.html_title,
                             name=self.config.project,
                             link="index.html",
                             xmlns="http://www.devhelp.net/book",
                             version="2",
                             language="python")
        tree = etree.ElementTree(root)

        # TOC
        chapters = etree.SubElement(root, 'chapters')

        tocdoc = self.env.get_and_resolve_doctree(
            self.config.master_doc, self, prune_toctrees=False)

        def write_toc(node, parent):
            if isinstance(node, addnodes.compact_paragraph) or \
                   isinstance(node, nodes.bullet_list):
                for subnode in node:
                    write_toc(subnode, parent)
            elif isinstance(node, nodes.list_item):
                item = etree.SubElement(parent, 'sub')
                for subnode in node:
                    write_toc(subnode, item)
            elif isinstance(node, nodes.reference):
                parent.attrib['link'] = node['refuri']
                parent.attrib['name'] = node.astext().encode('utf-8')

        def istoctree(node):
            return isinstance(node, addnodes.compact_paragraph) and \
                   'toctree' in node

        for node in tocdoc.traverse(istoctree):
            write_toc(node, chapters)

        # Index
        functions = etree.SubElement(root, 'functions')
        index = self.env.create_index(self)

        def write_index(title, refs, subitems):
            if len(refs) == 0:
                pass
            elif len(refs) == 1:
                name = title
                xml_type = "function"
                if ' ' in title:
                    func, rest = title.split(' ', 1)
                    if rest.endswith('method)') and func.endswith('()'):
                        complete_class_name = rest.rsplit(' ', 1)[0]
                        canonical_class_name = complete_class_name.rsplit('.', 1)[1]
                        name = canonical_class_name + '.' + func
                    elif rest.endswith('attribute)'):
                        complete_class_name = rest.rsplit(' ', 1)[0]
                        canonical_class_name = complete_class_name.rsplit('.', 1)[1]
                        name = canonical_class_name + '.' + func
                        xml_type = "constant"
                etree.SubElement(functions, 'keyword',
                                 type=xml_type,
                                 name=name, link=refs[0][1])
            else:
                for i, ref in enumerate(refs):
                    etree.SubElement(functions, 'keyword',
                                     type="function",
                                     name="[%d] %s" % (i, title),
                                     link=ref[1])

            if subitems:
                parent_title = re.sub(r'\s*\(.*\)\s*$', '', title)
                for subitem in subitems:
                    write_index("%s %s" % (parent_title, subitem[0]),
                                subitem[1], [])

        for (key, group) in index:
            for title, (refs, subitems) in group:
                write_index(title, refs, subitems)

        # Dump the XML file
        f = gzip.open(os.path.join(outdir, outname + '.devhelp2.gz'), 'w')
        try:
            tree.write(f)
        finally:
            f.close()
