import os

from docutils.nodes import Text, paragraph
from sphinxcontrib.autoprogram import AutoprogramDirective

from .client import CLI
from .resource import is_control_resource, CustomCommand


class CustomAutoprogramDirective(AutoprogramDirective):
    def run(self):
        nodes = super(CustomAutoprogramDirective, self).run()

        # By default, the document generated by sphinxcontrib.autoprogram
        # just has a page title which is the program name ("awx")
        # The code here changes this slightly so the reference guide starts
        # with a human-friendly title and preamble

        # configure a custom page heading (not `awx`)
        heading = Text('Reference Guide')
        heading.parent = nodes[0][0]
        nodes[0][0].children = [heading]

        # add a descriptive top synopsis of the reference guide
        nodes[0].children.insert(1, paragraph(text=('This is an exhaustive guide of every available command in ' 'the awx CLI tool.')))
        disclaimer = (
            'The commands and parameters documented here can (and will) '
            'vary based on a variety of factors, such as the AWX API '
            'version, AWX settings, and access level of the authenticated '
            'user.  For the most accurate view of available commands, '
            'invoke the awx CLI using the --help flag.'
        )
        nodes[0].children.insert(2, paragraph(text=disclaimer))
        return nodes


def render():
    # This function is called by Sphinx when making the docs.
    #
    # It loops over every resource at `/api/v2/` and performs an HTTP OPTIONS
    # request to determine all of the supported actions and their arguments.
    #
    # The return value of this function is an argparse.ArgumentParser, which
    # the sphinxcontrib.autoprogram plugin crawls and generates an indexed
    # Sphinx document from.
    for e in (
        ('CONTROLLER_HOST', 'TOWER_HOST'),
        ('CONTROLLER_USERNAME', 'TOWER_USERNAME'),
        ('CONTROLLER_PASSWORD', 'TOWER_PASSWORD'),
    ):
        if not os.environ.get(e[0]) and not os.environ.get(e[1]):
            raise SystemExit('Please specify a valid {} for a real (running) installation.'.format(e[0]))  # noqa
    cli = CLI()
    cli.parse_args(['awx', '--help'])
    cli.connect()
    cli.authenticate()
    try:
        cli.parse_resource(skip_deprecated=True)
    except SystemExit:
        pass
    for resource in cli.subparsers.keys():
        cli.argv = [resource, '--help']
        cli.resource = resource
        if resource in CustomCommand.registry or is_control_resource(resource):
            pass
        else:
            page = getattr(cli.v2, resource, None)
            if page:
                try:
                    cli.parse_action(page, from_sphinx=True)
                except SystemExit:
                    pass
    return cli.parser


def setup(app):
    app.add_directive('autoprogram', CustomAutoprogramDirective)


parser = render()
