
import sys
import importlib

from six import iteritems
from docutils import nodes

import sphinx
from docutils.parsers.rst import Directive

from sphinx.writers.html import HTMLTranslator
from sphinx.errors import SphinxError


class bibtex_node(nodes.Element):
    pass


def visit_bibtex_node(self, node):
    pass


def depart_bibtex_node(self, node):
    """
    This function creates the formatting that sets up the look of the blocks.
    The look of the formatting is controlled by _theme/static/style.css
    """
    if not isinstance(self, HTMLTranslator):
        self.body.append("output only available for HTML\n")
        return

    html = """
    <div class="cell border-box-sizing code_cell rendered">
       <div class="output_area"><pre>{}</pre></div>
    </div>""".format(node["text"])

    self.body.append(html)


class EmbedBibtexDirective(Directive):
    """
    EmbedBibtexDirective is a custom directive to allow a Bibtex citation to be embedded.

    .. embed-bibtex::
        openmdao.solvers.linear.petsc_ksp
        PETScKrylov


    The 2 arguments are the module path and the class name.

    What the above will do is replace the directive and its args with the Bibtex citation
    for the class.

    """

    required_arguments = 2
    optional_arguments = 0
    has_content = True

    def run(self):
        module_path, class_name = self.arguments
        mod = importlib.import_module(module_path)
        obj = getattr(mod, class_name)()

        if not hasattr(obj, 'cite') or not obj.cite:
            raise SphinxError("Couldn't find 'cite' in class '%s'" % class_name)

        return [bibtex_node(text=obj.cite)]


def setup(app):
    """add custom directive into Sphinx so that it is found during document parsing"""
    app.add_directive('embed-bibtex', EmbedBibtexDirective)
    app.add_node(bibtex_node, html=(visit_bibtex_node, depart_bibtex_node))

    return {'version': sphinx.__display_version__, 'parallel_read_safe': True}
