#!/usr/bin/env python
# encoding: utf-8
# Hans-Martin von Gaudecker, 2012

"""
Create Sphinx documentation. Currently only LaTeX and HTML are supported.

The source file **must** be the conf.py file used by Sphinx. Everything
else has defaults, passing in the parameters is optional.

Usage for getting both html and pdf docs:

    def build(ctx):
        ctx(features='sphinx', source='docs/conf.py')
        ctx(features='sphinx', source='docs/conf.py', buildername='latex')

    def sphinx(ctx):
        ctx(features='sphinx', source='docs/conf.py')
        ctx(features='sphinx', source='docs/conf.py', buildername='latex')

Optional parameters and their defaults:

    * buildername: html
    * srcdir: confdir (the directory where conf.py lives)
    * outdir: confdir/buildername (in the build directory tree)
    * doctreedir: outdir/.doctrees
    * type: pdflatex (only applies to 'latex' builder)

"""


import os
from waflib import Task, TaskGen, Errors, Logs, Build

class RunSphinxBuild(Task.Task):
	def scan(self):
		"""Use Sphinx' internal environment to find the dependencies."""
		s = self.sphinx_instance
		msg, dummy, iterator = s.env.update(s.config, s.srcdir, s.doctreedir, s)
		s.info(msg)
		dep_nodes = []
		for docname in s.builder.status_iterator(iterator, "reading sources... "):
			filename = docname + s.config.source_suffix
			dep_nodes.append(self.srcdir.find_node(filename))
		for dep in s.env.dependencies.values():
			# Need the 'str' call because Sphinx might return Unicode strings.
			[dep_nodes.append(self.srcdir.find_node(str(d))) for d in dep]
		return (dep_nodes, [])

	def run(self):
		"""Run the Sphinx build."""
		self.sphinx_instance.build(force_all=False, filenames=None)
		return None

	def post_run(self):
		"""Add everything found in the output directory tree as an output.
		Not elegant, but pragmatic."""
		for n in self.outdir.ant_glob("**", quiet=True, remove=False):
			if n not in self.outputs: self.set_outputs(n)
		super(RunSphinxBuild, self).post_run()


def _get_main_targets(tg, s):
	"""Return some easy targets known from the Sphinx build environment **s.env**."""
	out_dir = tg.bld.root.find_node(s.outdir)
	tgt_nodes = []
	if s.builder.name == "latex":
		for tgt_info in s.env.config.latex_documents:
			tgt_nodes.append(out_dir.find_or_declare(tgt_info[1]))
	elif s.builder.name == "html":
		suffix = getattr(s.env.config, "html_file_suffix", ".html")
		tgt_name = s.env.config.master_doc + suffix
		tgt_nodes.append(out_dir.find_or_declare(tgt_name))
	else:
		raise Errors.WafError("Sphinx builder not implemented: %s" % s.builder.name)
	return tgt_nodes


@TaskGen.feature("sphinx")
@TaskGen.before_method("process_source")
def apply_sphinx(tg):
	"""Set up the task generator with a Sphinx instance and create a task."""

        from sphinx.application import Sphinx

	# Put together the configuration based on defaults and tg attributes.
	conf = tg.path.find_node(tg.source)
	confdir = conf.parent.abspath()
	buildername = getattr(tg, "buildername", "html")
	srcdir = getattr(tg, "srcdir", confdir)
	outdir = tg.path.find_or_declare (getattr(tg, "outdir", os.path.join(conf.parent.get_bld().abspath(), buildername))).abspath ()

	doctreedir = getattr(tg, "doctreedir", os.path.join(outdir, ".doctrees"))

	# Set up the Sphinx instance.
	s = Sphinx (srcdir, confdir, outdir, doctreedir, buildername, status=None)

	# Get the main targets of the Sphinx build.
	tgt_nodes = _get_main_targets(tg, s)

	# Create the task and set the required attributes.
	task = tg.create_task("RunSphinxBuild", src=conf, tgt=tgt_nodes)
	task.srcdir = tg.bld.root.find_node(s.srcdir)
	task.outdir = tg.bld.root.find_node(s.outdir)
	task.sphinx_instance = s

	# Build pdf if we have the LaTeX builder, allow for building with xelatex.
	if s.builder.name == "latex":
		compile_type = getattr(tg, "type", "pdflatex")
		tg.bld(features="tex", type=compile_type, source=tgt_nodes, name="sphinx_pdf", prompt=0)

	# Bypass the execution of process_source by setting the source to an empty list
	tg.source = []

# sphinx docs
from waflib.Build import BuildContext
class sphinx (BuildContext):
    cmd = "sphinx"
    fun = "sphinx"
