"""Run from this directory, with AIL 0.3.4 src on PYTHONPATH.
No AI service is called. JSON checks implement this example's small profile,
not a general JSON Schema validator. See schema.json for an equivalent schema.
"""
import json
from ail_ref.parser import parse
from ail_ref.validator import validate
from ail_ref.canonical import canonicalize

KNOWN = ['ail:earth', 'ail:orbits', 'ail:sun']

def json_profile_errors(m):
    errors = []
    if not isinstance(m, dict): return ['expected object']
    required = {'id','act','registry','body'}
    if not required <= m.keys(): errors.append('missing required fields')
    if set(m) - (required | {'conf'}): errors.append('unexpected fields')
    if not isinstance(m.get('id'),str) or not m.get('id'): errors.append('id must be a nonempty string')
    if m.get('act') != 'A01': errors.append('act must be A01 for this demo')
    if m.get('registry') != 'ail-core:0.2': errors.append('unexpected registry')
    b=m.get('body')
    if not isinstance(b,list) or len(b)!=3 or any(x not in KNOWN for x in b): errors.append('body must contain three registered identifiers')
    if 'conf' in m:
        c=m['conf']
        if isinstance(c,bool) or not isinstance(c,(int,float)) or not 0<=c<=1: errors.append('confidence outside 0..1')
    return errors

def main():
    rows=[]
    for title,subject,relation,obj,conf,expected in [
        ('Valid structure','ail:earth','ail:orbits','ail:sun',1,True),
        ('Misspelled relationship','ail:earth','ail:orbitts','ail:sun',1,False),
        ('Confidence outside range','ail:earth','ail:orbits','ail:sun',1.2,False),
        ('False claim with valid structure','ail:sun','ail:orbits','ail:earth',1,True),
    ]:
        ail=f'AIL/0.2 M{{id=demo1;act=A01;registry=ail-core:0.2;body=P({subject},{relation},{obj});conf={conf};}}'
        m={'id':'demo1','act':'A01','registry':'ail-core:0.2','body':[subject,relation,obj],'conf':conf}
        ae=[{'code':i.code,'message':i.message} for i in validate(parse(ail),strict_registry=True)]
        je=json_profile_errors(json.loads(json.dumps(m)))
        assert (not ae)==expected and (not je)==expected, title
        rows.append({'case':title,'ail':ail,'json':m,'json_syntax_valid':True,'ail_issues':ae,'json_profile_issues':je,'accepted':expected})
    bare='AIL/0.2 M{id=alias1;act=A01;registry=ail-core:0.2;body=P(ail:earth,ail:orbits,ail:sun);}'
    labeled=bare.replace('ail:earth,','ail:earth~tierra,').replace('ail:orbits,','ail:orbits~orbita,').replace('ail:sun)','ail:sun~sol)')
    assert not validate(parse(labeled),strict_registry=True)
    assert canonicalize(parse(bare))==canonicalize(parse(labeled))
    print(json.dumps({'cases':rows,'aliases':{'bare':bare,'labeled':labeled,'same_canonical_output':True,'output':canonicalize(parse(bare))}},indent=2))

if __name__=='__main__': main()
