#!/usr/local/bin/python2.7
# @(#) $Id: arduino-boards.py 47 2017-11-29 03:55:32Z leres $ (XSE)
"""Parse the Arduino boards.txt file
    http://code.google.com/p/arduino/wiki/Platforms"""

from __future__ import print_function

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, '%s:%d: malformed line (1)' % (fn, n))
	line2 = tup[0]
	val = tup[1]
	tup2 = line2.split('.', 1)
	if len(tup2) != 2:
	    return (boards, '%s:%d: malformed line (2)' % (fn, n))
	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: 47 $'.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('# %s=%s' % (key, getattr(OPTS, key)), file=sys.stderr)

    # Interactive debugging
    if OPTS.debugger:
	import pdb
	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('%s: %s: %s' % (PROG, OPTS.boards, e.strerror), file=sys.stderr)
	return 1
    if errmsg:
	print('%s: %s' % (PROG, errmsg), file=sys.stderr)
	return 1
    board = boards.get(OPTS.variant)
    if not board:
	print("%s: Can't find %s" % (PROG, OPTS.variant), file=sys.stderr)
	return 1

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

# XXX add dump()
#    keys = board.keys()
#    keys.sort()
#    for key in keys:
#	display = [OPTS.variant, key]
#	val = board.get(key)
#	print('%s=%s' % ('.'.join(display), val))

    return 0

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