#!/usr/local/bin/python3.11
# @(#) $Id: arduino-boards.py 86 2021-01-09 22:29:27Z leres $ (XSE)
"""Parse the Arduino boards.txt file
    http://code.google.com/p/arduino/wiki/Platforms"""

import argparse
import os
import sys

OPTS = None
PROG = '?'

DEFAULT_BOARDS = '/usr/local/arduino/hardware/arduino/boards.txt'

def parse(f, fn):
    """Parse the boards.txt file, return a dictonary and an optional
       error message"""
    target = None
    board = None
    boards = {}
    n = 0
    for line in f.readlines():
        n += 1
        line = line.strip()
        if not line:
            continue
        if line.startswith('#'):
            continue
        tup = line.split('=', 1)
        if len(tup) != 2:
            return (boards, f'{fn}:{n}: malformed line (1)')
        line2 = tup[0]
        val = tup[1]
        tup2 = line2.split('.', 1)
        if len(tup2) != 2:
            return (boards, f'{fn}:{n}: malformed line (2)')
        if target != tup2[0]:
            if target:
                boards[target] = board
            target = tup2[0]
            board = {}
        board[tup2[1]] = val

    if target:
        boards[target] = board
    return (boards, None)

def main(argv=None):
    """Parse options and execute"""
    global OPTS
    global PROG

    if not argv:
        argv = sys.argv

    PROG = os.path.basename(argv[0])
    version = '$Revision: 86 $'.strip('$').rstrip()

    parser = argparse.ArgumentParser()
    parser.add_argument('--version', action='version', version=version)
    parser.add_argument('-d', dest='debug', action='count', default=0,
        help='turn on debugging')
    parser.add_argument('-v', dest='verbose', action='count', default=0,
        help='verbose messages')
    parser.add_argument('-e', dest='emptyok', action='store_true',
        help='empty result is ok')
    parser.add_argument('-f', dest='boards',
        default=DEFAULT_BOARDS,
        help='boards.txt (default: %(default)s)')
    parser.add_argument('--debugger', action='store_true',
        help=argparse.SUPPRESS)

    parser.add_argument('variant', metavar='VARIANT',
        help='variant')
    parser.add_argument('what', metavar='WHAT',
        help='what')

    OPTS = parser.parse_args()

    # argparse debugging
    if OPTS.debug > 1:
        for key in dir(OPTS):
            if not key.startswith('_'):
                print(f'# {key}={getattr(OPTS, key)}', file=sys.stderr)

    # Interactive debugging
    if OPTS.debugger:
        # pylint: disable=C0415
        import pdb
        # pylint: enable=C0415
        pdb.set_trace()

    boards = None
    errmsg = None
    try:
        with open(OPTS.boards) as f:
            boards, errmsg = parse(f, OPTS.boards)
    except (IOError, OSError) as e:
        print(f'{PROG}: {OPTS.boards}: {e.strerror}', file=sys.stderr)
        return 1
    if errmsg:
        print(f'{PROG}: {errmsg}', file=sys.stderr)
        return 1
    board = boards.get(OPTS.variant)
    if not board:
        print(f"{PROG}: Can't find {OPTS.variant}", file=sys.stderr)
        return 1

    val = board.get(OPTS.what)
    if not val:
        if OPTS.emptyok:
            return 0
        print(f"{PROG}: Can't find {OPTS.variant}.{OPTS.what}",
            file=sys.stderr)
        return 1
    print(f'{val}')

# XXX add dump()
#    keys = list(board.keys())
#    keys.sort()
#    for key in keys:
#       display = [OPTS.variant, key]
#       val = board.get(key)
#       print(f"{'.'.join(display)}={val}")

    return 0

if __name__ == "__main__":
    sys.exit(main())
