#!/usr/bin/env python3
"""Deterministic routing policy: hard constraints first, soft preferences second."""
import argparse
BACKENDS=[
 {"id":"local-small","local":True,"quality":1,"cost":1},
 {"id":"local-strong","local":True,"quality":3,"cost":2},
 {"id":"cloud-fast","local":False,"quality":2,"cost":2},
 {"id":"cloud-strong","local":False,"quality":3,"cost":3},
]
def route(sensitivity,complexity,prefer,local_down=False,cloud_down=False):
    candidates=[]
    for b in BACKENDS:
        reason='eligible'
        if (b['local'] and local_down) or ((not b['local']) and cloud_down): reason='unhealthy'
        elif sensitivity=='restricted' and not b['local']: reason='residency_policy'
        elif complexity=='high' and b['quality']<3: reason='capability_too_low'
        ok=reason=='eligible'
        print(f"backend={b['id']} eligible={str(ok).lower()} reason={reason}")
        if ok: candidates.append(b)
    if not candidates:
        print('decision=no_eligible_backend')
        return 'no_eligible_backend'
    if prefer=='quality': candidates.sort(key=lambda x:(-x['quality'],x['cost']))
    else: candidates.sort(key=lambda x:(x['cost'] if prefer=='cost' else (1 if x['local'] else 2),-x['quality']))
    print(f"decision={candidates[0]['id']}")
    return candidates[0]['id']
def main():
    ap=argparse.ArgumentParser(); ap.add_argument('--sensitivity',choices=['public','internal','restricted'],default='public'); ap.add_argument('--complexity',choices=['low','high'],default='low'); ap.add_argument('--prefer',choices=['cost','latency','quality'],default='cost'); ap.add_argument('--local-down',action='store_true'); ap.add_argument('--cloud-down',action='store_true'); ap.add_argument('--self-test',action='store_true'); a=ap.parse_args()
    if a.self_test:
        assert route('public','low','cost')!='no_eligible_backend'
        assert route('restricted','high','quality')=='local-strong'
        assert route('restricted','high','quality',local_down=True)=='no_eligible_backend'
        print('PASS hard_constraints_survive_fallback')
    else: route(a.sensitivity,a.complexity,a.prefer,a.local_down,a.cloud_down)
if __name__=='__main__': main()
