from datetime import datetime

def _dt(s): return datetime.fromisoformat(s.replace('Z','+00:00'))

def evaluate(c):
    decisive=['plan_id','product_id','price_id','entitlement_id','feature_key','grant_state','limit_type','limit_value','effective_from','effective_to','override_owner','revocation_trigger','subscription_state','runtime_snapshot','evidence_ref']
    if any(c.get(k) in (None,'',[]) for k in decisive):
        return _out('HOLD','UNKNOWN','UNKNOWN','UNKNOWN','UNKNOWN','DECISIVE_EVIDENCE_MISSING')
    cref=c.get('commercial_ref')
    if not isinstance(cref,dict) or any(cref.get(k) in (None,'') for k in ['plan_id','product_id','price_id','entitlement_id','feature_key','grant_state','limit_type','limit_value']):
        return _out('HOLD','UNKNOWN','UNKNOWN','UNKNOWN','UNKNOWN','COMMERCIAL_AUTHORITY_MISSING')
    if c.get('limit_type')=='METERED' and not c.get('meter_ref'):
        return _out('HOLD','ACTIVE','UNKNOWN','NONE','UNKNOWN','METER_REFERENCE_REQUIRED')
    runtime=c.get('runtime_snapshot')
    if not isinstance(runtime,dict):
        return _out('HOLD','UNKNOWN','UNKNOWN','UNKNOWN','UNKNOWN','RUNTIME_SNAPSHOT_INVALID')
    # Commercial identity -> entitlement mapping must reconcile first.
    for k in ['plan_id','product_id','price_id','entitlement_id','feature_key','grant_state','limit_type','limit_value']:
        if cref.get(k)!=c.get(k):
            return _out('DRIFT','ACTIVE','INCONSISTENT','NONE','NOT_TRIGGERED','PRICE_ENTITLEMENT_MAPPING_STALE')
    # Revocation policy is explicit and precedes ordinary alignment.
    triggers=c.get('revocation_trigger')
    if isinstance(triggers,str): triggers=[x.strip() for x in triggers.split('|') if x.strip()]
    if c.get('subscription_state') in (triggers or []):
        if runtime.get('grant_state')=='GRANTED':
            return _out('REVOKE',str(c.get('subscription_state')).upper(),'SHOULD_REVOKE','NONE','TRIGGERED','SUBSCRIPTION_STATE_REQUIRES_REVOCATION')
    # Override validity and expiry.
    oid=c.get('override_id')
    if oid not in (None,'','NONE'):
        if c.get('override_owner') in (None,'','NONE') or c.get('override_reason') in (None,'') or c.get('current_at') in (None,''):
            return _out('HOLD','ACTIVE','UNKNOWN','UNKNOWN','UNKNOWN','OVERRIDE_AUTHORITY_INCOMPLETE')
        active=_dt(c['effective_from']) <= _dt(c['current_at']) <= _dt(c['effective_to'])
        if not active:
            if runtime.get('limit_value',c.get('limit_value'))!=c.get('limit_value') or runtime.get('grant_state')!=c.get('grant_state'):
                return _out('REVOKE','ACTIVE','EXCESS','EXPIRED','TRIGGERED','EXPIRED_OVERRIDE_STILL_ACTIVE')
        else:
            if runtime.get('grant_state')==c.get('grant_state') and runtime.get('limit_type')==c.get('limit_type') and runtime.get('meter_ref')==c.get('meter_ref'):
                return _out('OVERRIDE','ACTIVE','CONSISTENT','VALID','NOT_TRIGGERED','BOUNDED_OVERRIDE_VALID')
    # No override: runtime must match authority.
    for k in ['feature_key','grant_state','limit_type','limit_value']:
        if runtime.get(k)!=c.get(k):
            return _out('DRIFT','ACTIVE','INCONSISTENT','NONE','NOT_TRIGGERED','RUNTIME_DOES_NOT_MATCH_ENTITLEMENT')
    if c.get('limit_type')=='METERED' and runtime.get('meter_ref')!=c.get('meter_ref'):
        return _out('DRIFT','ACTIVE','INCONSISTENT','NONE','NOT_TRIGGERED','RUNTIME_METER_MISMATCH')
    return _out('ALIGNED','ACTIVE','CONSISTENT','NONE','NOT_TRIGGERED','PLAN_AND_RUNTIME_ALIGNED')

def _out(decision,commercial,grant,override,revocation,reason):
    return {'decision_state':decision,'commercial_state':commercial,'grant_state_eval':grant,'override_state':override,'revocation_state':revocation,'reason_code':reason}
