#!/usr/bin/env python

## Note: to launch test, you can use:
##   python -m doctest -d shyaml.py
## or
##   nosetests

import sys
import yaml
import os.path

EXNAME = os.path.basename(sys.argv[0])


def mget(dct, key, default=None):
    """Allow to get values deep in a dict with doted keys.

    >>> mget({'a': {'x': 1, 'b': {'c': 2}}}, "a.x")
    1
    >>> mget({'a': {'x': 1, 'b': {'c': 2}}}, "a.b.c")
    2
    >>> mget({'a': {'x': 1, 'b': {'c': 2}}}, "a.b")
    {'c': 2}
    >>> mget({'a': {'x': [1, 5], 'b': {'c': 2}}}, "a.x.-1")
    5
    >>> mget({'a': {'x': 1, 'b': [{'c': 2}]}}, "a.b.0.c")
    2

    >>> mget({'a': {'x': 1, 'b': {'c': 2}}}, "a.y", default='N/A')
    'N/A'

    """
    if key == "":
        return dct
    if not "." in key:
        if isinstance(dct, list):
            return dct[int(key)]
        return dct.get(key, default)
    else:
        head, tail = key.split(".", 1)
        value = dct[int(head)] if isinstance(dct, list) else dct.get(head, {})
        return mget(value, tail, default)


def stderr(msg):
    sys.stderr.write(msg + "\n")


def die(msg, errlvl=1):
    stderr(msg)
    sys.exit(errlvl)


def main(args):
    usage = """usage:
    %(exname)s get-value KEY
    %(exname)s get-type KEY
    %(exname)s keys
    """ % {"exname": EXNAME}
    if len(args) == 0:
        die(usage, errlvl=0)
    action = args[0]
    if action in ["get-value", "get-type"]:
        key_value = "" if len(args) == 1 else args[1]
        default = args[2] if len(args) > 2 else ""
        contents = yaml.load(sys.stdin)
        try:
            value = mget(contents, key_value, default)
        except IndexError:
            die("Error: list index error in path %r." % key_value)
        except KeyError, TypeError:
            die("Error: invalid path %r." % key_value)
        if action == "get-value":
            if not isinstance(value, (basestring, int, float)):
                value = yaml.dump(value, default_flow_style=False)
            print value,
            return 0
        else:  ## action == "get-type"
            print "struct" if isinstance(value, dict) else \
                  "sequence" if isinstance(value, (tuple, list)) else \
                  type(value).__name__
            return 0
    if action == "keys":
        for k in yaml.load(sys.stdin).keys():
            print k
        return 0
    die("Error: Invalid argument.\n%s" % usage)


if __name__ == "__main__":
    sys.exit(main(sys.argv[1:]))
