#!/usr/bin/env python3
"""Reference validator for Veydrin Open Data Standard (VODS) documents.

Checks a VODS JSON document against the published VODS v1.0 schema, with format
assertions turned on so that date-time and UUID formats are checked, not just
annotated. Domain specializations that build on VODS (such as OHDS) also carry the
VODS envelope, so this validator checks the envelope of any VODS-family document.

Usage:
    python3 validate.py path/to/export.json
    cat export.json | python3 validate.py

Requires the jsonschema package: pip install jsonschema
Exits 0 if the document conforms, 1 if it does not, 2 on a usage or setup error.
"""
import json
import os
import sys

try:
    from jsonschema import Draft202012Validator, FormatChecker
except ImportError:
    sys.stderr.write("This validator needs the jsonschema package: pip install jsonschema\n")
    sys.exit(2)

HERE = os.path.dirname(os.path.abspath(__file__))
SCHEMA_PATH = os.path.join(HERE, "vods-v1.0.schema.json")


def load_document():
    if len(sys.argv) > 2:
        sys.stderr.write("Usage: validate.py [document.json]  (or pipe the document on stdin)\n")
        sys.exit(2)
    source = open(sys.argv[1]) if len(sys.argv) == 2 else sys.stdin
    return json.load(source)


def main():
    with open(SCHEMA_PATH) as f:
        schema = json.load(f)
    document = load_document()
    validator = Draft202012Validator(schema, format_checker=FormatChecker())
    errors = sorted(validator.iter_errors(document), key=lambda e: list(e.path))
    if not errors:
        print("VALID: the document conforms to VODS v1.0.")
        return 0
    print("INVALID: {0} problem(s) found.".format(len(errors)))
    for error in errors:
        location = "/".join(str(p) for p in error.path) or "(root)"
        print("  at {0}: {1}".format(location, error.message))
    return 1


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