# Copyright (c) 2017 Open Source Foundries Limited.
#
# SPDX-License-Identifier: Apache-2.0

'''Sphinx extensions related to managing Zephyr applications.'''

from docutils import nodes
from docutils.parsers.rst import Directive
from docutils.parsers.rst import directives


# TODO: extend and modify this for Windows.
#
# This could be as simple as generating a couple of sets of instructions, one
# for Unix environments, and another for Windows.
class ZephyrAppCommandsDirective(Directive):
    r'''
    This is a Zephyr directive for generating consistent documentation
    of the shell commands needed to manage (build, flash, etc.) an application.

    For example, to generate commands to build samples/hello_world for
    qemu_x86 use::

       .. zephyr-app-commands::
          :zephyr-app: samples/hello_world
          :board: qemu_x86
          :goals: build

    Directive options:

    \:tool:
      which tool to use. Valid options are currently 'cmake', 'west' and 'all'.
      The default is 'west'.

    \:app:
      path to the application to build.

    \:zephyr-app:
      path to the application to build, this is an app present in the upstream
      zephyr repository. Mutually exclusive with \:app:.

    \:cd-into:
      if set, build instructions are given from within the \:app: folder,
      instead of outside of it.

    \:generator:
      which build system to generate. Valid options are
      currently 'ninja' and 'make'. The default is 'ninja'. This option
      is not case sensitive.

    \:host-os:
      which host OS the instructions are for. Valid options are
      'unix', 'win' and 'all'. The default is 'all'.

    \:board:
      if set, the application build will target the given board.

    \:shield:
      if set, the application build will target the given shield.

    \:conf:
      if set, the application build will use the given configuration
      file.  If multiple conf files are provided, enclose the
      space-separated list of files with quotes, e.g., "a.conf b.conf".

    \:gen-args:
      if set, additional arguments to the CMake invocation

    \:build-args:
      if set, additional arguments to the build invocation

    \:build-dir:
      if set, the application build directory will *APPEND* this
      (relative, Unix-separated) path to the standard build directory. This is
      mostly useful for distinguishing builds for one application within a
      single page.

    \:goals:
      a whitespace-separated list of what to do with the app (in
      'build', 'flash', 'debug', 'debugserver', 'run'). Commands to accomplish
      these tasks will be generated in the right order.

    \:maybe-skip-config:
      if set, this indicates the reader may have already
      created a build directory and changed there, and will tweak the text to
      note that doing so again is not necessary.

    \:compact:
      if set, the generated output is a single code block with no
      additional comment lines

    \:west-args:
      if set, additional arguments to the west invocation (ignored for CMake)

    '''
    has_content = False
    required_arguments = 0
    optional_arguments = 0
    final_argument_whitespace = False
    option_spec = {
        'tool': directives.unchanged,
        'app': directives.unchanged,
        'zephyr-app': directives.unchanged,
        'cd-into': directives.flag,
        'generator': directives.unchanged,
        'host-os': directives.unchanged,
        'board': directives.unchanged,
        'shield': directives.unchanged,
        'conf': directives.unchanged,
        'gen-args': directives.unchanged,
        'build-args': directives.unchanged,
        'build-dir': directives.unchanged,
        'goals': directives.unchanged_required,
        'maybe-skip-config': directives.flag,
        'compact': directives.flag,
        'west-args': directives.unchanged,
    }

    TOOLS = ['cmake', 'west', 'all']
    GENERATORS = ['make', 'ninja']
    HOST_OS = ['unix', 'win', 'all']
    IN_TREE_STR = '# From the root of the zephyr repository'

    def run(self):
        # Re-run on the current document if this directive's source changes.
        self.state.document.settings.env.note_dependency(__file__)

        # Parse directive options.  Don't use os.path.sep or os.path.join here!
        # That would break if building the docs on Windows.
        tool = self.options.get('tool', 'west').lower()
        app = self.options.get('app', None)
        zephyr_app = self.options.get('zephyr-app', None)
        cd_into = 'cd-into' in self.options
        generator = self.options.get('generator', 'ninja').lower()
        host_os = self.options.get('host-os', 'all').lower()
        board = self.options.get('board', None)
        shield = self.options.get('shield', None)
        conf = self.options.get('conf', None)
        gen_args = self.options.get('gen-args', None)
        build_args = self.options.get('build-args', None)
        build_dir_append = self.options.get('build-dir', '').strip('/')
        goals = self.options.get('goals').split()
        skip_config = 'maybe-skip-config' in self.options
        compact = 'compact' in self.options
        west_args = self.options.get('west-args', None)

        if tool not in self.TOOLS:
            raise self.error('Unknown tool {}; choose from: {}'.format(
                tool, self.TOOLS))

        if app and zephyr_app:
            raise self.error('Both app and zephyr-app options were given.')

        if generator not in self.GENERATORS:
            raise self.error('Unknown generator {}; choose from: {}'.format(
                generator, self.GENERATORS))

        if host_os not in self.HOST_OS:
            raise self.error('Unknown host-os {}; choose from: {}'.format(
                host_os, self.HOST_OS))

        if compact and skip_config:
            raise self.error('Both compact and maybe-skip-config options were given.')

        app = app or zephyr_app
        in_tree = self.IN_TREE_STR if zephyr_app else None
        # Allow build directories which are nested.
        build_dir = ('build' + '/' + build_dir_append).rstrip('/')

        # Create host_os array
        host_os = [host_os] if host_os != "all" else [v for v in self.HOST_OS
                                                        if v != 'all']
        # Create tools array
        tools = [tool] if tool != "all" else [v for v in self.TOOLS
                                                if v != 'all']
        # Build the command content as a list, then convert to string.
        content = []
        tool_comment = None
        if len(tools) > 1:
            tool_comment = 'Using {}:'

        run_config = {
            'host_os': host_os,
            'app': app,
            'in_tree': in_tree,
            'cd_into': cd_into,
            'board': board,
            'shield': shield,
            'conf': conf,
            'gen_args': gen_args,
            'build_args': build_args,
            'build_dir': build_dir,
            'goals': goals,
            'compact': compact,
            'skip_config': skip_config,
            'generator': generator,
            'west_args': west_args
            }

        if 'west' in tools:
            w = self._generate_west(**run_config)
            if tool_comment:
                paragraph = nodes.paragraph()
                paragraph += nodes.Text(tool_comment.format('west'))
                content.append(paragraph)
                content.append(self._lit_block(w))
            else:
                content.extend(w)

        if 'cmake' in tools:
            c = self._generate_cmake(**run_config)
            if tool_comment:
                paragraph = nodes.paragraph()
                paragraph += nodes.Text(tool_comment.format(
                    'CMake and {}'.format(generator)))
                content.append(paragraph)
                content.append(self._lit_block(c))
            else:
                content.extend(c)

        if not tool_comment:
            content = [self._lit_block(content)]

        return content

    def _lit_block(self, content):
        content = '\n'.join(content)

        # Create the nodes.
        literal = nodes.literal_block(content, content)
        self.add_name(literal)
        literal['language'] = 'shell'
        return literal


    def _generate_west(self, **kwargs):
        content = []
        generator = kwargs['generator']
        board = kwargs['board']
        app = kwargs['app']
        in_tree = kwargs['in_tree']
        goals = kwargs['goals']
        cd_into = kwargs['cd_into']
        build_dir = kwargs['build_dir']
        compact = kwargs['compact']
        west_args = kwargs['west_args']
        kwargs['board'] = None
        # west always defaults to ninja
        gen_arg = ' -G\'Unix Makefiles\'' if generator == 'make' else ''
        cmake_args = gen_arg + self._cmake_args(**kwargs)
        cmake_args = ' --{}'.format(cmake_args) if cmake_args != '' else ''
        west_args = ' {}'.format(west_args) if west_args else ''
        # ignore zephyr_app since west needs to run within
        # the installation. Instead rely on relative path.
        src = ' {}'.format(app) if app and not cd_into else ''
        dst = ' -d {}'.format(build_dir) if build_dir != 'build' else ''

        if in_tree and not compact:
            content.append(in_tree)

        if cd_into and app:
            content.append('cd {}'.format(app))

        # We always have to run west build.
        #
        # FIXME: doing this unconditionally essentially ignores the
        # maybe-skip-config option if set.
        #
        # This whole script and its users from within the
        # documentation needs to be overhauled now that we're
        # defaulting to west.
        #
        # For now, this keeps the resulting commands working.
        content.append('west build -b {}{}{}{}{}'.
                       format(board, west_args, dst, src, cmake_args))

        # If we're signing, we want to do that next, so that flashing
        # etc. commands can use the signed file which must be created
        # in this step.
        if 'sign' in goals:
            content.append('west sign{}'.format(dst))

        for goal in goals:
            if goal in {'build', 'sign'}:
                continue
            elif goal == 'flash':
                content.append('west flash{}'.format(dst))
            elif goal == 'debug':
                content.append('west debug{}'.format(dst))
            elif goal == 'debugserver':
                content.append('west debugserver{}'.format(dst))
            elif goal == 'attach':
                content.append('west attach{}'.format(dst))
            else:
                content.append('west build -t {}{}'.format(goal, dst))

        return content

    @staticmethod
    def _mkdir(mkdir, build_dir, host_os, skip_config):
        content = []
        if skip_config:
            content.append("# If you already made a build directory ({}) and ran cmake, just 'cd {}' instead.".format(build_dir, build_dir))  # noqa: E501
        if host_os == 'all':
            content.append('mkdir {} && cd {}'.format(build_dir, build_dir))
        if host_os == "unix":
            content.append('{} {} && cd {}'.format(mkdir, build_dir, build_dir))
        elif host_os == "win":
            build_dir = build_dir.replace('/', '\\')
            content.append('mkdir {} & cd {}'.format(build_dir, build_dir))
        return content

    @staticmethod
    def _cmake_args(**kwargs):
        board = kwargs['board']
        shield = kwargs['shield']
        conf = kwargs['conf']
        gen_args = kwargs['gen_args']
        board_arg = ' -DBOARD={}'.format(board) if board else ''
        shield_arg = ' -DSHIELD={}'.format(shield) if shield else ''
        conf_arg = ' -DCONF_FILE={}'.format(conf) if conf else ''
        gen_args = ' {}'.format(gen_args) if gen_args else ''

        return '{}{}{}{}'.format(board_arg, shield_arg, conf_arg, gen_args)

    def _cd_into(self, mkdir, **kwargs):
        app = kwargs['app']
        host_os = kwargs['host_os']
        compact = kwargs['compact']
        build_dir = kwargs['build_dir']
        skip_config = kwargs['skip_config']
        content = []
        os_comment = None
        if len(host_os) > 1:
            os_comment = '# On {}'
            num_slashes = build_dir.count('/')
            if not app and mkdir and num_slashes == 0:
                # When there's no app and a single level deep build dir,
                # simplify output
                content.extend(self._mkdir(mkdir, build_dir, 'all',
                               skip_config))
                if not compact:
                    content.append('')
                return content
        for host in host_os:
            if host == "unix":
                if os_comment:
                    content.append(os_comment.format('Linux/macOS'))
                if app:
                    content.append('cd {}'.format(app))
            elif host == "win":
                if os_comment:
                    content.append(os_comment.format('Windows'))
                if app:
                    backslashified = app.replace('/', '\\')
                    content.append('cd {}'.format(backslashified))
            if mkdir:
                content.extend(self._mkdir(mkdir, build_dir, host, skip_config))
            if not compact:
                content.append('')
        return content

    def _generate_cmake(self, **kwargs):
        generator = kwargs['generator']
        cd_into = kwargs['cd_into']
        app = kwargs['app']
        in_tree = kwargs['in_tree']
        build_dir = kwargs['build_dir']
        build_args = kwargs['build_args']
        skip_config = kwargs['skip_config']
        goals = kwargs['goals']
        compact = kwargs['compact']

        content = []

        if in_tree and not compact:
            content.append(in_tree)

        if cd_into:
            num_slashes = build_dir.count('/')
            mkdir = 'mkdir' if num_slashes == 0 else 'mkdir -p'
            content.extend(self._cd_into(mkdir, **kwargs))
            # Prepare cmake/ninja/make variables
            source_dir = ' ' + '/'.join(['..' for i in range(num_slashes + 1)])
            cmake_build_dir = ''
            tool_build_dir = ''
        else:
            source_dir = ' {}'.format(app) if app else ' .'
            cmake_build_dir = ' -B{}'.format(build_dir)
            tool_build_dir = ' -C{}'.format(build_dir)

        # Now generate the actual cmake and make/ninja commands
        gen_arg = ' -GNinja' if generator == 'ninja' else ''
        build_args = ' {}'.format(build_args) if build_args else ''
        cmake_args = self._cmake_args(**kwargs)

        if not compact:
            if not cd_into and skip_config:
                content.append("# If you already ran cmake with -B{}, you " \
                               "can skip this step and run {} directly.".
                               format(build_dir, generator))  # noqa: E501
            else:
                content.append('# Use cmake to configure a {}-based build' \
                               'system:'.format(generator.capitalize()))  # noqa: E501

        content.append('cmake{}{}{}{}'.format(cmake_build_dir, gen_arg,
                                              cmake_args, source_dir))
        if not compact:
            content.extend(['',
                            '# Now run ninja on the generated build system:'])

        if 'build' in goals:
            content.append('{}{}{}'.format(generator, tool_build_dir,
                                           build_args))
        for goal in goals:
            if goal == 'build':
                continue
            content.append('{}{} {}'.format(generator, tool_build_dir, goal))

        return content


def setup(app):
    app.add_directive('zephyr-app-commands', ZephyrAppCommandsDirective)

    return {
        'version': '1.0',
        'parallel_read_safe': True,
        'parallel_write_safe': True
    }
