# Copyright (c) 2019 Nordic Semiconductor ASA
#
# SPDX-License-Identifier: Apache-2.0

import argparse
import collections
import re
import textwrap

from west import log
from west.commands import WestCommand

from zcmake import run_cmake
from zephyr_ext_common import ZEPHYR_CMAKE

class Boards(WestCommand):

    def __init__(self):
        super().__init__(
            'boards',
            # Keep this in sync with the string in west-commands.yml.
            'display information about supported boards',
            'Display information about boards',
            accepts_unknown_args=False)

    def do_add_parser(self, parser_adder):
        default_fmt = '{name}'
        parser = parser_adder.add_parser(
            self.name,
            help=self.help,
            formatter_class=argparse.RawDescriptionHelpFormatter,
            description=self.description,
            epilog=textwrap.dedent('''\
            FORMAT STRINGS

            Boards are listed using a Python 3 format string. Arguments
            to the format string are accessed by name.

            The default format string is:

            "{}"

            The following arguments are available:

            - name: board name
            - arch: board architecture
            '''.format(default_fmt)))

        # Remember to update scripts/west-completion.bash if you add or remove
        # flags
        parser.add_argument('-f', '--format', default=default_fmt,
                            help='''Format string to use to list each board;
                                    see FORMAT STRINGS below.''')

        return parser

    def do_run(self, args, unknown_args):
        cmake_args = ['-P', f'{ZEPHYR_CMAKE}/boards.cmake']
        lines = run_cmake(cmake_args, capture_output=True)
        arch_re = re.compile(r'\s*([\w-]+)\:')
        board_re = re.compile(r'\s*([\w-]+)\s*')
        arch = None
        boards = collections.OrderedDict()
        for line in lines:
            match = arch_re.match(line)
            if match:
                arch = match.group(1)
                boards[arch] = []
                continue
            match = board_re.match(line)
            if match:
                if not arch:
                    log.die('Invalid board output from CMake: {}'.
                            format(lines))
                board = match.group(1)
                boards[arch].append(board)

        for arch in boards:
            for board in boards[arch]:
                try:
                    result = args.format.format(
                        name=board,
                        arch=arch)
                    print(result)
                except KeyError as e:
                    # The raised KeyError seems to just put the first
                    # invalid argument in the args tuple, regardless of
                    # how many unrecognizable keys there were.
                    log.die('unknown key "{}" in format string "{}"'.
                            format(e.args[0], args.format))
