#!/usr/bin/env python3

import getopt
import json
import platform
import sys

import yaml


def usage():
    print(f"Usage: {sys.argv[0]} -c|--config <config file>[-h]")
    print("")
    print("Options:")
    print("  -c, --config <file>     config file")
    print("")


def yaml_param(loader, node):
    params = loader.app_params
    default = None
    key = node.value

    assert type(key) is str, f"param name must be a string"

    if '=' in key:
        key, default = [t.strip() for t in key.split('=', maxsplit=1)]

        if key in params:
            value = params[key]
        else:
            value = yaml.safe_load(default)
    else:
        assert key in params, f"no param set for '{key}', and there is no default"
        value = params[key]

    return value


def main():
    config_file = None
    params = {}
    input_file = None

    try:
        opts, args = getopt.getopt(sys.argv[1:], 'hi:', longopts=['param='])
    except getopt.GetoptError as e:
        print (f"{sys.argv[0]}: invalid option {e.opt}: {e.msg}")
        print(sys.argv[1:])
        sys.exit(2)

    for o, a in opts:
        if o in ['-h']:
            usage()
            sys.exit(0)
        elif o in ['-i']:
            input_file = a
        elif o in ['--param']:
            k,v = a.split("=", maxsplit=1)
            params[k] = yaml.safe_load(v)
        else:
            assert False, f"unhandled option {o}"

    if input_file is None:
        f = sys.stdin
    else:
        f = open(input_file, "rt")

    yaml_loader = yaml.SafeLoader
    yaml_loader.app_params = params
    yaml.add_constructor("!param", yaml_param, Loader=yaml_loader)

    config = yaml.load(f, Loader=yaml_loader)
    if f != sys.stdin:
        f.close()

    print(json.dumps(config))


if __name__ == "__main__":
    main()
