# inspired by code by Hans-Martin von Gaudecker, 2012

"""Support for Sphinx documentation"""

import os
from waflib import Node, Task, TaskGen, Utils


class sphinx_build(Task.Task):
    color = 'BLUE'
    run_str = '${SPHINX_BUILD} -D ${VERSION} -D ${RELEASE} -q -b ${BUILDERNAME} -d ${DOCTREEDIR} ${SRCDIR} ${OUTDIR}'

    def __str__(self):
        env = self.env
        src_str = ' '.join([a.path_from(a.ctx.launch_node()) for a in self.inputs])
        tgt_str = ' '.join([a.path_from(a.ctx.launch_node()) for a in self.outputs])
        if self.outputs: sep = ' -> '
        else: sep = ''
        return'%s [%s]: %s%s%s\n'%(self.__class__.__name__.replace('_task',''),
                                   self.env['BUILDERNAME'], src_str, sep, tgt_str)


# from https://docs.python.org/3.12/whatsnew/3.12.html#imp
def load_source(modname, filename):
    import importlib.util
    from importlib.machinery import SourceFileLoader
    loader = SourceFileLoader(modname, filename)
    spec = importlib.util.spec_from_file_location(modname, filename, loader=loader)
    module = importlib.util.module_from_spec(spec)
    loader.exec_module(module)
    return module


@TaskGen.extension('.py', '.rst')
def sig_hook(self, node):
    node.sig=Utils.h_file(node.abspath())


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

    inputs = []
    for i in Utils.to_list(self.source):
        if not isinstance(i, Node.Node):
            node = self.path.find_node(node)
        else:
            node = i
        if not node:
            raise ValueError('[%s] file not found' % i)
        inputs.append(node)

    task = self.create_task('sphinx_build', inputs)

    conf = self.path.find_node(self.config)
    task.inputs.append(conf)

    confdir = conf.parent.abspath()
    buildername = getattr(self, 'builder', 'html')
    srcdir = getattr(self, 'srcdir', confdir)
    outdir = self.path.find_or_declare(getattr(self, 'outdir', buildername)).get_bld()
    doctreedir = getattr(self, 'doctreedir', os.path.join(outdir.abspath(), '.doctrees'))

    task.env['BUILDERNAME'] = buildername
    task.env['SRCDIR'] = srcdir
    task.env['OUTDIR'] = outdir.abspath()
    task.env['DOCTREEDIR'] = doctreedir
    task.env['VERSION'] = 'version=%s' % self.version
    task.env['RELEASE'] = 'release=%s' % getattr(self, 'release', self.version)

    if buildername == 'man':
        confdata = load_source('sphinx_conf', conf.abspath())
        for i in confdata.man_pages:
            target = outdir.find_or_declare('%s.%d' % (i[1], i[4]))
            task.outputs.append(target)

            if self.install_path:
                self.bld.install_files('%s/man%d/' % (self.install_path, i[4]), target)
    else:
        task.outputs.append(outdir)


def configure(conf):
    """Check if sphinx-build program is available."""
    conf.find_program('sphinx-build', var='SPHINX_BUILD', mandatory=False)


# sphinx command
from waflib.Build import BuildContext
class sphinx(BuildContext):
    cmd = 'sphinx'
    fun = 'sphinx'
