"""Read-only JSON syntax gate; does not repair the input.
python json-syntax-gate.py input.json
"""
import hashlib, json, sys
from pathlib import Path

class NumberToken(str):
    pass

def unique_object(pairs):
    result = {}
    for key, value in pairs:
        if key in result:
            raise ValueError('duplicate key: ' + repr(key))
        result[key] = value
    return result

def reject_constant(value):
    raise ValueError('non-JSON numeric constant: ' + value)

def check(source):
    source = Path(source)
    if source.stat().st_size > 2_000_000:
        raise ValueError('this small example caps input at 2,000,000 bytes')
    raw = source.read_bytes()
    report = {'filename': source.name, 'sha256': hashlib.sha256(raw).hexdigest()}
    try:
        text = raw.decode('utf-8')
        data = json.loads(text, object_pairs_hook=unique_object,
                          parse_constant=reject_constant,
                          parse_float=NumberToken, parse_int=NumberToken)
    except (UnicodeDecodeError, ValueError) as error:
        report.update(accepted=False, error_type=type(error).__name__, error=str(error))
        if isinstance(error, json.JSONDecodeError):
            report.update(line=error.lineno, column=error.colno)
        return report, None
    report['accepted'] = True
    return report, data

if __name__ == '__main__':
    report, data = check(sys.argv[1])
    print(json.dumps(report, indent=2))
    sys.exit(0 if report['accepted'] else 1)
