import argparse, hashlib, json
from pathlib import Path

def inspect(source):
    path = Path(source)
    if path.stat().st_size > 1_000_000:
        raise ValueError("Demo input cap exceeded")
    raw = path.read_bytes()
    if raw.startswith(b"\xef\xbb\xbf"):
        raise ValueError("This mapping requires UTF-8 without a BOM")
    text = raw.decode("utf-8", errors="strict")
    report = {"source_sha256": hashlib.sha256(raw).hexdigest(),
              "source_bytes": len(raw)}
    try:
        json.loads(text)
    except json.JSONDecodeError as error:
        byte_offset = len(text[:error.pos].encode("utf-8"))
        assert raw[:byte_offset] == text[:error.pos].encode("utf-8")
        report.update(syntax_parsed=False, message=error.msg,
                      character_index=error.pos, utf8_byte_offset=byte_offset,
                      line=error.lineno, column=error.colno,
                      at_end=error.pos == len(text))
        return report, 1
    report.update(syntax_parsed=True)
    return report, 0

if __name__ == "__main__":
    p = argparse.ArgumentParser()
    p.add_argument("source")
    args = p.parse_args()
    try:
        report, status = inspect(args.source)
        print(json.dumps(report, ensure_ascii=True, sort_keys=True))
        raise SystemExit(status)
    except (ValueError, OSError, RecursionError) as error:
        p.exit(2, str(error) + "\n")
