from __future__ import absolute_import

"""Sphinx Bulma theme.

Based on https://github.com/rtfd/sphinx_rtd_theme

"""
from docutils.nodes import Admonition
from docutils.nodes import attention
from docutils.nodes import caution
from docutils.nodes import danger
from docutils.nodes import error
from docutils.nodes import hint
from docutils.nodes import important
from docutils.nodes import note
from docutils.nodes import tip
from docutils.nodes import title
from docutils.nodes import warning
from sphinx.addnodes import seealso

from six import string_types
from .fs import module_path
from .version import version

"""
maps :py:class:`docutils.nodes.Admonition` subclasses to `bulma message color classes <https://bulma.io/documentation/components/message/#colors>`_
"""
admonition_map = {
    seealso: 'is-success',
    tip: 'is-primary',
    note: 'is-warning',
    warning: 'is-danger',
    attention: 'is-warning',
    caution: 'is-warning',
    danger: 'is-danger',
    error: 'is-danger',
    hint: 'is-info',
    important: 'is-link',
}


def get_html_theme_path():
    """For use inside Sphinx's ``conf.py`` file:


    .. code:: python

       import sphinx_bulma_theme

       html_theme = "bulma"
       html_theme_path = [sphinx_bulma_theme.get_html_theme_path()]

       html_theme_options = {
           'show_topbar': False,
           'sidebar_right': True,
       }

    """
    return str(module_path)


def add_classes_to_node(class_names, node):
    """sets a list of class names in the node. Used for injecting `bulma modifiers <https://bulma.io/documentation/modifiers/color-helpers/>`_ in the final HTML generated by Sphinx.

    :param class_names: a list of strings
    :param node: the target node
    """
    if isinstance(class_names, string_types):
        class_names = class_names.split()

    return list(map(node.set_class, class_names))


def process_admonition_node(node, admonition_type, color, size):
    """applies the given color and size modifiers to admonition nodes

    :param node: the target :py:class:`docutils.nodes.Admonition` (subclass) node
    :param admonition_type: see :py:data:`sphinx_bulma_theme.admonition_map`
    :param color: a string, such as ``is-danger``
    :param size: a string, such as ``is-small`` or **None**
    """
    add_classes_to_node(['message', size, color], node)

    for child in node.traverse(title):
        add_classes_to_node('message-header', child)

    # for child in node.traverse(admonition_type):
    #     add_classes_to_node('message-body', child)
    #     break


def bulmanize_documentation(app, doctree, fromdocname):
    """applies necessary internal node transformations before HTML rendering:

    - Loads the ``admonition_class`` from :ref:`theme options`
    - Iterate over :py:data:`sphinx_bulma_theme.admonition_map`


    """
    theme_options = app.config.html_theme_options
    message_size = theme_options.get('default_admonition_class', '')

    # size = app.env.conf.get('')
    # nodes = list(filter(lambda n: 'also' in str(n).lower(), doctree.traverse(Element)))
    # for node in nodes:
    #     print(node)
    #     import ipdb; ipdb.set_trace()

    #     atts = dict(node.attlist())
    #     names = " ".join(atts.get('names') or [])
    #     for ad_type, color in admonition_map.items():
    #         ad_name = ad_type.__name__
    #         if ad_name in names:
    #             process_admonition_node(node, ad_type, color)

    for node in doctree.traverse(Admonition):
        message_color = admonition_map.get(node.__class__, 'is-dark')
        process_admonition_node(node, node.__class__, message_color, message_size)


# def handle_page_context(app, pagename, templatename, context, doctree):
#     pass


def setup(app):
    app.add_html_theme('bulma', get_html_theme_path())
    app.connect('doctree-resolved', bulmanize_documentation)
    # app.connect('html-page-context', handle_page_context)


__all__ = (
    'get_html_theme_path',
    'version',
    'setup',
    'admonition_map',
)
