import pathlib,json,sys,copy
LAB=pathlib.Path(__file__).resolve().parents[1]; sys.path.insert(0,str(LAB/'src'))
from key_boundary import *
policy=json.loads((LAB/'fixture/golden-policy.json').read_text()); objects=json.loads((LAB/'fixture/baseline-data.json').read_text())['objects']; checks=[]
def c(n,x): checks.append((n,bool(x)))
c('primary_boundary',evaluate_boundary('primary_database',policy)['decision']=='BOUNDARY_OK')
c('backup_boundary',evaluate_boundary('backup_archive',policy)['decision']=='BOUNDARY_OK')
c('decrypt_allow_primary',evaluate_decrypt('primary_database','service:primary-api',policy)['decision']=='ALLOW_DECRYPT_AUTHORIZED')
c('decrypt_deny_other',evaluate_decrypt('primary_database','service:other',policy)['decision']=='DENY_DECRYPT_AUTHORITY')
mut=copy.deepcopy(policy); mut['contexts']['primary_database']['kek_authority']=mut['contexts']['primary_database']['storage_boundary']; c('collapse_detected',evaluate_boundary('primary_database',mut)['decision']=='BOUNDARY_WEAKENED_KEY_AUTHORITY_COLLAPSED')
mut=copy.deepcopy(policy); mut['contexts']['primary_database']['key_storage_model']='application_source'; c('hardcode_detected',evaluate_boundary('primary_database',mut)['decision']=='DENY_KEY_STORAGE_BOUNDARY')
mut=copy.deepcopy(policy); mut['contexts']['primary_database']['recovery_metadata']=''; c('recovery_missing',evaluate_boundary('primary_database',mut)['decision']=='DENY_RECOVERY_METADATA_MISSING')
rot={'old_key_id':'dek-primary-v1','new_key_id':'dek-primary-v2','historical_key_ids_accounted':['dek-primary-v1'],'recovery_metadata':'plan:primary-recovery'}; c('rotation_ok',evaluate_rotation('primary_database',rot,objects,policy)['decision']=='ROTATION_ACCOUNTED')
bad=dict(rot); bad['historical_key_ids_accounted']=[]; c('rotation_missing_hist',evaluate_rotation('primary_database',bad,objects,policy)['decision']=='DENY_ROTATION_HISTORICAL_PATH_UNACCOUNTED')
bad=dict(rot); bad['recovery_metadata']=''; c('rotation_missing_recovery',evaluate_rotation('primary_database',bad,objects,policy)['decision']=='DENY_RECOVERY_METADATA_MISSING')
row=build_evidence_row('primary_database','service:primary-api',policy); c('row_complete',evidence_row_complete(row)); badrow=dict(row); badrow['residual_risk']=''; c('row_missing_detected',not evidence_row_complete(badrow))
c('transfer_backup',classify_transfer('backup_archive')['status']=='REBUILD_KEY_BOUNDARY'); c('transfer_no_copy',classify_transfer('backup_archive')['copy_primary_boundary'] is False)
c('primary_key_v2',policy['contexts']['primary_database']['current_key_id']=='dek-primary-v2'); c('historical_v1',policy['contexts']['primary_database']['historical_key_ids']==['dek-primary-v1']); c('backup_independent',policy['contexts']['backup_archive']['kek_authority']!=policy['contexts']['primary_database']['kek_authority']); c('prod_false',policy['production_proof'] is False); c('realkey_false',policy['real_key_material'] is False); c('customcrypto_false',policy['custom_crypto'] is False); c('universal_false',policy['rotation']['universal_cryptoperiod'] is False)
for n,ok in checks: print(('PASS' if ok else 'FAIL'),n)
print(f'SUMMARY {sum(ok for _,ok in checks)}/{len(checks)} PASS'); raise SystemExit(0 if all(ok for _,ok in checks) else 1)
