#! /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
import os

from west.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 "VERBOSE" in os.environ:
        args.verbose = 1

    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()
