#! /usr/bin/env python3

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

"""Zephyr flash/debug script

This helper script is the build system's entry point to Zephyr's
"runner" Python package. This package provides ZephyrBinaryRunner,
which is a standard interface for flashing and debugging boards
supported by Zephyr, as well as backend-specific scripts for tools
such as OpenOCD, pyOCD, etc.
"""

import argparse
import functools
import sys

from runner.core import ZephyrBinaryRunner


def print_runners_handler(args):
    for cls in ZephyrBinaryRunner.get_runners():
        print(cls.name())


def runner_handler(cls, args):
    runner = cls.create_from_args(args)
    # This relies on ZephyrBinaryRunner.add_parser() having command as
    # its single positional argument; see its docstring for details.
    runner.run(args.command)


def main():
    # Argument handling is split into a two-level structure, with
    # common options to the script first, then a sub-command (i.e.  a
    # runner name), then options and arguments for that sub-command
    # (like 'flash --some-option=value').
    #
    # For top-level help (including a list of runners), run:
    #
    # $ZEPHYR_BASE/.../SCRIPT.py -h
    #
    # For help on a particular RUNNER (like 'pyocd'), run:
    #
    # $ZEPHYR_BASE/.../SCRIPT.py RUNNER -h
    #
    # For verbose output, use:
    #
    # $ZEPHYR_BASE/.../SCRIPT.py [-v|--verbose] RUNNER [--runner-options]
    #
    # Note that --verbose comes *before* RUNNER, not after!
    #
    # Other commands (for now just the "runners" command, which prints
    # the available runners) are handled the same way:
    #
    # $ZEPHYR_BASE/.../SCRIPT.py runners
    top_parser = argparse.ArgumentParser()
    top_parser.add_argument('-v', '--verbose',
                            default=False, action='store_true',
                            help='If set, enable verbose output.')
    sub_parsers = top_parser.add_subparsers(dest='top_command')

    # Handlers for each subcommand.
    handlers = {}

    # The 'runners' command just prints the runners. It takes no arguments.
    sub_parsers.add_parser('runners')
    handlers['runners'] = print_runners_handler

    # Add a sub-command for each runner. (It's a bit hackish for runners
    # to know about argparse, but it's good enough for now.)
    for cls in ZephyrBinaryRunner.get_runners():
        if cls.name() in handlers:
            print('Runner {} name is already a top-level command'.format(
                      cls.name()),
                  file=sys.sterr)
            sys.exit(1)
        sub_parser = sub_parsers.add_parser(cls.name())
        cls.add_parser(sub_parser)
        handlers[cls.name()] = functools.partial(runner_handler, cls)

    args = top_parser.parse_args()
    if args.top_command is None:
        choices = ', '.join(handlers.keys())
        print('Missing command or runner; choices: {}'.format(choices),
              file=sys.stderr)
        sys.exit(1)
    try:
        handlers[args.top_command](args)
    except Exception as e:
        if args.verbose:
            raise
        else:
            print('Error: {}'.format(e), file=sys.stderr)
            print(('(Re-run as "{} --verbose {} ..." '
                   'or set CMAKE_VERBOSE_MAKEFILE for a stack trace.)').format(
                       sys.argv[0], args.top_command),
                  file=sys.stderr)
            sys.exit(1)


if __name__ == '__main__':
    main()
