#!/usr/bin/env python3
from pathlib import Path
import json, sys
root=Path(__file__).resolve().parents[1]
def J(rel): return json.loads((root/rel).read_text(encoding='utf-8'))
contract=J('model-contract.json'); tus=J('data/translation-units.json'); terms=J('data/termbase.json'); candidates=J('data/reuse-candidates.json'); inter=J('data/interchange-boundary.json'); transfer=J('transfer/changed-context.json')
issues=[]
def issue(code,detail): issues.append({'code':code,'detail':detail})
if not contract.get('separate_record_types_required'): issue('TM_TERMBASE_BOUNDARY','separation disabled')
if not isinstance(tus,list) or not isinstance(terms,list) or tus is terms: issue('TM_TERMBASE_BOUNDARY','stores not separate')
req=set(contract.get('translation_unit_required_fields',[])); ctxreq=set(contract.get('context_required_fields',[])); provreq=set(contract.get('provenance_required_fields',[]))
for tu in tus:
    miss=req-set(tu)
    if miss: issue('TU_REQUIRED_FIELDS',f"{tu.get('id')} missing {sorted(miss)}")
    if ctxreq-set(tu.get('context',{})): issue('CONTEXT_REQUIRED',tu.get('id'))
    if provreq-set(tu.get('provenance',{})): issue('PROVENANCE_REQUIRED',tu.get('id'))
    if tu.get('status') not in contract.get('translation_unit_statuses',[]): issue('LIFECYCLE_STATUS_INVALID',tu.get('id'))
term_by_product={t.get('scope',{}).get('product'):t for t in terms if t.get('status')=='active'}
tu_by_id={x['id']:x for x in tus}
for c in candidates:
    tu=tu_by_id.get(c.get('candidate_tu'))
    if not tu: issue('CANDIDATE_TU_MISSING',c.get('id')); continue
    decision=c.get('reuse_decision')
    if tu.get('status')=='deprecated' and decision in {'AUTO_APPROVE','APPROVED','REUSE_AUTOMATIC'}:
        issue('STALE_EXACT_AUTO_APPROVAL',c.get('id'))
    if c.get('match',{}).get('type')=='fuzzy' and decision in {'AUTO_APPROVE','APPROVED','REUSE_AUTOMATIC'}:
        issue('FUZZY_SCORE_OVERCLAIM',c.get('id'))
    term=term_by_product.get(c.get('product'))
    if term and any(bad.lower() in tu.get('target','').lower() for bad in term.get('forbidden',[])) and decision in {'AUTO_APPROVE','APPROVED','REUSE_AUTOMATIC'}:
        issue('TERMINOLOGY_CONFLICT_UNBLOCKED',c.get('id'))
if contract.get('fuzzy_score_is_quality_score') is not False: issue('FUZZY_SCORE_OVERCLAIM','contract treats fuzzy score as quality')
if contract.get('exact_match_auto_approval_forbidden') is not True: issue('STALE_EXACT_AUTO_APPROVAL','contract allows exact auto approval')
if inter.get('semantic_compatibility_guaranteed') is not False or contract.get('interchange',{}).get('semantic_compatibility_guaranteed') is not False:
    issue('INTERCHANGE_SEMANTIC_OVERCLAIM','interchange marked semantically guaranteed')
if inter.get('translation_memory_format')!='TMX' or inter.get('terminology_format')!='TBX': issue('INTERCHANGE_BOUNDARY','TMX/TBX mapping changed')
if transfer.get('independent') is not True or transfer.get('decisive_solution_copied_from_alpha') is not False: issue('TRANSFER_INDEPENDENCE','changed-context transfer not independent')
out={'schema':'WEB021_AUDIT_OUTPUT_v1','issues':issues,'issue_count':len(issues),'status':'PASS' if not issues else 'FAIL'}
(root/'evidence/audit-output.json').write_text(json.dumps(out,ensure_ascii=False,indent=2)+'\n',encoding='utf-8')
print(json.dumps(out,ensure_ascii=False,indent=2)); sys.exit(0 if not issues else 1)
