#!/usr/bin/env python3
# SPDX-License-Identifier: BSD-2-Clause
# Copyright 2018 Linaro Ltd.
# Copyright 2018 Arm Ltd.

import os
import sys
import argparse
import glob

from ruamel import yaml

def eprint(filename, *args, **kwargs):
    print(filename + ": warning:", *args, file=sys.stderr, **kwargs)

def yaml_format(file, in_place):
    yml = yaml.YAML()
    # Setup formatting settings
    yml.indent(mapping=2, sequence=4, offset=2)
    yml.explicit_start=True
    yml.explicit_end=True
    yml.preserve_quotes=True
    yml.version=(1,2)
    yml.width=70

    rawfile = open(file, encoding='utf-8').read()
    top_comment = rawfile.partition('%YAML')[0]
    print(top_comment, file=sys.stderr)

    try:
        yamldata = yml.load(rawfile)
    except yaml.YAMLError as exc:
        print(file + ":", exc)
        exit(-1)

    yamldata['description'] = yaml.scalarstring.PreservedScalarString(yamldata['description'])

    # Check that keys are in a defined order
    key_order = [ "$id", "$schema", "title", "maintainers",
        "description", "allOf", "properties", "required", "patternProperties" "examples" ];
    last_idx = 0
    yaml_keys = list(yamldata.keys())
    for k in key_order:
        try:
            if yaml_keys.index(k) < last_idx:
                eprint(file, "Expected " + key_order[i] + " for key {0}, found ".format(i) + k)
            last_idx = yaml_keys.index(k)
        except:
            continue

    if in_place:
        f = open(file, 'w', encoding='utf-8')
    else:
        f = sys.stdout

    print(top_comment, file=f, end="")
    yml.dump(yamldata, f)

if __name__ == "__main__":
    ap = argparse.ArgumentParser()
    ap.add_argument("-i", "--in-place", help="operate in place on <file>",
                    action="store_true")

    ap.add_argument("file", type=str,
                    help="Filename of YAML encoded devicetree input file")
    args = ap.parse_args()

    if os.path.isdir(args.file):
        for filename in glob.iglob(args.file + "/**/*.yaml", recursive=True):
            yaml_format(filename, args.in_place)
    else:
        yaml_format(args.file, args.in_place)
