# Copyright (c) 2013 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

#
# This is a Sphinx extension.
#

from __future__ import print_function
import codecs
from collections import namedtuple, OrderedDict
import os
import string
from docutils import nodes
from docutils.parsers.rst import Directive, directives
from sphinx.util.osutil import ensuredir
from sphinx.builders.html import StandaloneHTMLBuilder
from sphinx.writers.html import HTMLWriter
from sphinx.writers.html import SmartyPantsHTMLTranslator as HTMLTranslator
from sphinx.util.console import bold

PEPPER_VERSION = "31"

# TODO(eliben): it may be interesting to use an actual Sphinx template here at
# some point.
PAGE_TEMPLATE = string.Template(r'''
${devsite_prefix}
<html devsite>
  <head>
    ${nonprod_meta_head}
    <title>${doc_title}</title>
    <meta name="project_path" value="/native-client${folder}/_project.yaml" />
    <meta name="book_path" value="/native-client${folder}/_book.yaml" />
    <link href="/native-client/css/local_extensions.css" rel="stylesheet" type="text/css"/>
    ${nonprod_css}
    <style type="text/css">
      .nested-def {list-style-type: none; margin-bottom: 0.3em;}
      .maxheight {height: 200px;}
    </style>
  </head>
  <body>
    ${devsite_butterbar}

${doc_body}

  </body>
</html>
'''.lstrip())

DEVSITE_PREFIX = r'''
{% setvar pepperversion %}pepper''' + PEPPER_VERSION + '''{% endsetvar %}
{% include "native-client/_local_variables.html" %}'''

DEVSITE_BUTTERBAR = '{{butterbar}}'

# We want the non-production-mode HTML to resemble the real one, so this points
# to a copied version of the devsite CSS that we'll keep locally. It's for
# testing purposes only.
NONPROD_CSS = '<link href="/_static/css/local_extensions.css"'\
              'rel="stylesheet" type="text/css"/>'
NONPROD_META_HEAD = '<meta charset="utf-8" />'

# Path to the top-level YAML table-of-contents file for the devsite
BOOK_TOC_TEMPLATE = '_book_template.yaml'


class DevsiteHTMLTranslator(HTMLTranslator):
  """ Custom HTML translator for devsite output.

      Hooked into the HTML builder by setting the html_translator_class
      option in conf.py

      HTMLTranslator is provided by Sphinx. We're actually using
      SmartyPantsHTMLTranslator to use its quote and dash-formatting
      capabilities. It's a subclass of the HTMLTranslator provided by docutils,
      with Sphinx-specific features added. Here we provide devsite-specific
      behavior by overriding some of the visiting methods.
  """
  def __init__(self, builder, *args, **kwds):
    # HTMLTranslator is an old-style Python class, so 'super' doesn't work: use
    # direct parent invocation.
    HTMLTranslator.__init__(self, builder, *args, **kwds)

    self.within_ignored_h1 = False
    self.within_toc = False

  def visit_bullet_list(self, node):
    if self.within_toc:
      # Within a TOC, devsite wants <ol>
      self.body.append(self.starttag(node, 'ol'))
    else:
      # Use our own class attribute for <ul>. Don't care about compacted lists.
      self.body.append(self.starttag(node, 'ul', **{'class': 'small-gap'}))

  def depart_bullet_list(self, node):
    if self.within_toc:
      self.body.append('</ol>\n')
    else:
      # Override to not pop anything from context
      self.body.append('</ul>\n')

  def visit_literal(self, node):
    # Don't insert "smart" quotes here
    self.no_smarty += 1
    # Sphinx emits <tt></tt> for literals (``like this``), with <span> per word
    # to protect against wrapping, etc. We're required to emit plain <code>
    # tags for them.
    # Emit a simple <code> tag without enabling "protect_literal_text" mode,
    # so Sphinx's visit_Text doesn't mess with the contents.
    self.body.append(self.starttag(node, 'code', suffix=''))

  def depart_literal(self, node):
    self.no_smarty -= 1
    self.body.append('</code>')

  def visit_literal_block(self, node):
    # Don't insert "smart" quotes here
    self.no_smarty += 1
    # We don't use Sphinx's buildin pygments integration for code highlighting,
    # because the devsite requires special <pre> tags for that and handles the
    # highlighting on its own.
    attrs = {'class': 'prettyprint'} if node.get('prettyprint', 1) else {}
    self.body.append(self.starttag(node, 'pre', **attrs))

  def depart_literal_block(self, node):
    self.no_smarty -= 1
    self.body.append('\n</pre>\n')

  def visit_paragraph(self, node):
    # Don't generate <p>s within the table of contents
    if not self.within_toc:
      HTMLTranslator.visit_paragraph(self, node)

  def depart_paragraph(self, node):
    if not self.within_toc:
      HTMLTranslator.depart_paragraph(self, node)

  def visit_section(self, node):
    # devsite needs <section> instead of <div class='section'>
    self.section_level += 1
    self.body.append(self.starttag(node, 'section'))

  def depart_section(self, node):
    self.section_level -= 1
    self.body.append('</section>')

  def visit_image(self, node):
    # Paths to images in .rst sources should be absolute. This visitor does the
    # required transformation for the path to be correct in the final HTML.
    if self.builder.devsite_production_mode:
      node['uri'] = self.builder.get_production_url(node['uri'])
    HTMLTranslator.visit_image(self, node)

  def visit_reference(self, node):
    # In "kill_internal_links" mode, we don't emit the actual links for internal
    # nodes.
    if self.builder.kill_internal_links and node.get('internal'):
      pass
    else:
      HTMLTranslator.visit_reference(self, node)

  def depart_reference(self, node):
    if self.builder.kill_internal_links and node.get('internal'):
      pass
    else:
      HTMLTranslator.depart_reference(self, node)

  def visit_title(self, node):
    # Why this?
    #
    # Sphinx insists on inserting a <h1>Page Title</h1> into the page, but this
    # is not how the devsite wants it. The devsite inserts the page title on
    # its own, the the extra h1 is duplication.
    #
    # Killing the doctree title node in a custom transform doesn't work, because
    # Sphinx explicitly looks for it when writing a document. So instead we rig
    # the HTML produced.
    #
    # When a title node is visited, and this is the h1-to-be, we ignore it and
    # also set a flag that tells visit_Text not to print the actual text of the
    # header.

    # The h1 node is in the section whose parent is the document itself. Other
    # sections have this top-section as their parent.
    if (node.parent and node.parent.parent and
        isinstance(node.parent.parent, nodes.document)):
      # Internal flag. Also, nothing is pushed to the context. Our depart_title
      # doesn't pop anything when this flag is set.
      self.within_ignored_h1 = True
    else:
      HTMLTranslator.visit_title(self, node)

  def depart_title(self, node):
    if not self.within_ignored_h1:
      HTMLTranslator.depart_title(self, node)
    self.within_ignored_h1 = False

  def visit_Text(self, node):
    if not self.within_ignored_h1:
      HTMLTranslator.visit_Text(self, node)

  def visit_topic(self, node):
    if 'contents' in node['classes']:
      # Detect a TOC: this requires special treatment for devsite.
      self.within_toc = True
      # Emit <nav> manually and not through starttage because we don't want
      # additional class components to be added
      self.body.append('\n<nav class="inline-toc">')

  def depart_topic(self, node):
    if self.within_toc:
      self.within_toc = False
      self.body.append('</nav>\n')

  def write_colspecs(self):
    # Override this method from docutils to do nothing. We don't need those
    # pesky <col width=NN /> tags in our markup.
    pass

  def visit_admonition(self, node, name=''):
    self.body.append(self.starttag(node, 'aside', CLASS=node.get('class', '')))

  def depart_admonition(self, node=''):
    self.body.append('\n</aside>\n')

  def unknown_visit(self, node):
    raise NotImplementedError('Unknown node: ' + node.__class__.__name__)


class DevsiteBuilder(StandaloneHTMLBuilder):
  """ Builder for the NaCl devsite HTML output.

      Loosely based on the code of Sphinx's standard SerializingHTMLBuilder.
  """
  name = 'devsite'
  out_suffix = '.html'
  link_suffix = '.html'

  # Disable the addition of "pi"-permalinks to each section header
  add_permalinks = False

  def init(self):
    self.devsite_production_mode = int(self.config.devsite_production_mode) == 1
    self.kill_internal_links = int(self.config.kill_internal_links) == 1
    self.info("----> Devsite builder with production mode = %d" % (
        self.devsite_production_mode,))
    self.config_hash = ''
    self.tags_hash = ''
    self.theme = None       # no theme necessary
    self.templates = None   # no template bridge necessary
    self.init_translator_class()
    self.init_highlighter()

  def finish(self):
    super(DevsiteBuilder, self).finish()
    if self.devsite_production_mode:
      # We decided to keep the manual _book.yaml for now;
      # The code for auto-generating YAML TOCs from index.rst was removed in
      # https://codereview.chromium.org/57923006/
      self.info(bold('generating YAML table-of-contents... '))
      subs = {
        'version': PEPPER_VERSION,
        'folder': self.config.devsite_foldername or ''}
      with open(os.path.join(self.env.srcdir, '_book.yaml')) as in_f:
        with open(os.path.join(self.outdir, '_book.yaml'), 'w') as out_f:
          out_f.write(string.Template(in_f.read()).substitute(subs))
    self.info()

  def dump_inventory(self):
    # We don't want an inventory file when building for devsite
    if not self.devsite_production_mode:
      super(DevsiteBuilder, self).dump_inventory()

  def get_production_url(self, url):
    if not self.devsite_production_mode:
      return url

    if self.config.devsite_foldername:
      return '/native-client/%s/%s' % (self.config.devsite_foldername, url)

    return '/native-client/%s' % url

  def get_target_uri(self, docname, typ=None):
    if self.devsite_production_mode:
      return self.get_production_url(docname)
    else:
      return docname + self.link_suffix

  def handle_page(self, pagename, ctx, templatename='page.html',
                  outfilename=None, event_arg=None):
    ctx['current_page_name'] = pagename

    if not outfilename:
      outfilename = os.path.join(self.outdir,
                                 pagename + self.out_suffix)

    # Emit an event to Sphinx
    self.app.emit('html-page-context', pagename, templatename,
                  ctx, event_arg)

    ensuredir(os.path.dirname(outfilename))
    self._dump_context(ctx, outfilename)

  def _dump_context(self, context, filename):
    """ Do the actual dumping of the page to the file. context is a dict. Some
        important fields:
          body - document contents
          title
          current_page_name
        Some special pages (genindex, etc.) may not have some of the fields, so
        fetch them conservatively.
    """
    if not 'body' in context:
      return

    folder = ''
    if self.devsite_production_mode and self.config.devsite_foldername:
      folder = "/" + self.config.devsite_foldername

    # codecs.open is the fast Python 2.x way of emulating the encoding= argument
    # in Python 3's builtin open.
    with codecs.open(filename, 'w', encoding='utf-8') as f:
      f.write(PAGE_TEMPLATE.substitute(
        doc_title=context.get('title', ''),
        doc_body=context.get('body'),
        folder=folder,
        nonprod_css=self._conditional_nonprod(NONPROD_CSS),
        nonprod_meta_head=self._conditional_nonprod(NONPROD_META_HEAD),
        devsite_prefix=self._conditional_devsite(DEVSITE_PREFIX),
        devsite_butterbar=self._conditional_devsite(DEVSITE_BUTTERBAR)))

  def _conditional_devsite(self, s):
    return s if self.devsite_production_mode else ''

  def _conditional_nonprod(self, s):
    return s if not self.devsite_production_mode else ''


class NaclCodeDirective(Directive):
  """ Custom "naclcode" directive for code snippets. To keep it under our
      control.
  """
  has_content = True
  required_arguments = 0
  optional_arguments = 1
  option_spec = {
      'prettyprint': int,
  }

  def run(self):
    code = u'\n'.join(self.content)
    literal = nodes.literal_block(code, code)
    literal['prettyprint'] = self.options.get('prettyprint', 1)
    return [literal]

def setup(app):
  """ Extension registration hook.
  """
  # linkcheck issues HEAD requests to save time, but some Google properties
  # reject them and we get spurious 405 responses. Monkey-patch sphinx to
  # just use normal GET requests.
  # See: https://bitbucket.org/birkenfeld/sphinx/issue/1292/
  from sphinx.builders import linkcheck
  import urllib2
  linkcheck.HeadRequest = urllib2.Request

  app.add_directive('naclcode', NaclCodeDirective)
  app.add_builder(DevsiteBuilder)

  # "Production mode" for local testing vs. on-server documentation.
  app.add_config_value('devsite_production_mode', default='1', rebuild='html')
  app.add_config_value('kill_internal_links', default='0', rebuild='html')
  app.add_config_value('devsite_foldername', default=None, rebuild='html')
