"""
SAE-1.4 reference implementation.
Canonical form:
  Awareness_raw(t) = Belief_total(t) * [ C - Blockers(t) + Purity(t) + Shakti_effective(t) ] + grace(t)
with all strict constraints from the spec:
 - C = 1.0 (humans), invariant
 - Purity = weighted sum of 6 dharma dimensions, in [0,1]
 - Shakti_effective = strength * stability * Capacity, Capacity = max(0, 1 - phys - mental)
 - Blockers = weighted sum, in [0,1]
 - Belief_total = min(B1, B2)  (weak-link coherence gate, in [-1,1]); stage gate for stage 0/1
 - grace additive
 - OverdriveRisk = strength * (1 - Purity)   [control metric, not in core eq]
 - AwarenessIndex = 50 + 50*tanh(raw/k)  [display transform only]
"""
import numpy as np

C_HUMAN = 1.0

def purity(P, w=None):
    P = np.asarray(P, float)
    if w is None:
        w = np.ones(P.shape[-1]) / P.shape[-1]
    w = np.asarray(w, float)
    return np.clip(P, 0, 1) @ w

def blockers(B, v=None):
    B = np.asarray(B, float)
    if v is None:
        v = np.ones(B.shape[-1]) / B.shape[-1]
    v = np.asarray(v, float)
    return np.clip(B, 0, 1) @ v

def shakti_effective(strength, stability, phys, mental):
    capacity = np.maximum(0.0, 1.0 - phys - mental)
    return strength * stability * capacity

def belief_total(B1, B2, stage=2):
    # weak-link coherence gate
    bt = np.minimum(B1, B2)
    # developmental stage gate: stage 0 -> +0.5, stage 1 -> +0.4
    bt = np.where(stage == 0, 0.5, np.where(stage == 1, 0.4, bt))
    return np.clip(bt, -1, 1)

def overdrive_risk(strength, pur):
    return strength * (1.0 - pur)

def awareness_raw(bt, pur, blk, sh_eff, grace=0.0, C=C_HUMAN):
    return bt * (C - blk + pur + sh_eff) + grace

def awareness_index(raw, k=1.5):
    return 50 + 50 * np.tanh(raw / k)
