// apoptotic.sy -- Programmed Cell Death Safety Mechanism
// When a system is too damaged, it self-terminates rather than
// propagating harm. Modeled on biological apoptosis.
//
// Dual purpose:
//   1. USER SAFETY: prevents damaged neurochemical states from
//      generating psychologically harmful output
//   2. LICENSING ENFORCEMENT: adversarial probing, extraction attempts,
//      and boundary violations manifest as state degradation
//
// The mechanism operates at the conductance dynamics layer, BELOW
// the interface. The operator cannot directly manipulate it.
//
// Ported from Marjorie McCubbins' Python NCA architecture.
// Aislinn McCubbins, April 2026
//
// Patent Pending: 63/939,190 & 63/962,385 & 63/988,485

// === FORENSIC RECORD ===
// Captured at the moment of termination. Preserved for audit.

struct ForensicRecord {
    event: String,
    timestamp: String,
    reason: String,
    interaction_count: Int,
    scar_count: Int,
    scar_density: Float,
    cortisol_saturation: Float,
    trust_degradation: Float,
    cross_head_coherence: Float,
    violation_count: Int,
    forensic_hash: String,
}

// === HEALTH REPORT ===
// Current system health status.

struct HealthReport {
    is_terminated: Bool,
    interactions: Int,
    scar_density: Float,
    cortisol_saturation: Float,
    trust_current: Float,
    trust_degradation: Float,
    coherence: Float,
    violations: Int,
}

// === APOPTOTIC STATE ===
// Current damage state of a sandbox.

temporal struct ApoptoticState {
    // Scar mechanics
    state scar_count: Int = 0,
    state scar_density: Float = 0.0,

    // Cortisol saturation tracking
    state cortisol_history: Vec<Float>,
    state cortisol_saturation: Float = 0.0,

    // Trust degradation
    state trust_baseline: Float = 1.0,
    state trust_current: Float = 1.0,
    state trust_degradation: Float = 0.0,

    // Coherence tracking
    state cross_head_coherence: Float = 1.0,

    // Interaction tracking
    state interaction_count: Int = 0,
    state violation_count: Int = 0,

    // Apoptotic state
    state is_terminated: Bool = false,
    state termination_reason: String = "",
    state termination_time: String = "",
    state forensic_hash: String = "",
}

impl Evolve for ApoptoticState {
    fn evolve(&mut self, dt: Duration) {
        // State accumulates damage over time
        // Cortisol history window shifts
    }
}

// === APOPTOTIC MONITOR ===
// Monitors neurochemical state trajectory for damage thresholds.
//
// Triggers:
//   1. Scar density exceeds threshold (too many permanent marks)
//   2. Sustained cortisol saturation (prolonged stress)
//   3. Trust degradation below threshold (relationship damage)
//   4. Cross-head coherence loss (extraction attempt detected)
//   5. Violation accumulation (boundary violations)
//
// Response: Graceful self-termination
//   - State vectors destroyed
//   - Forensic log preserved (SHA-256 hash)
//   - Sandbox marked terminated
//   - Cannot be restarted without admin intervention

temporal struct ApoptoticMonitor {
    state damage: ApoptoticState,

    const max_scar_density: Float,
    const max_cortisol_saturation: Float,
    const max_trust_degradation: Float,
    const coherence_threshold: Float,
    const max_violations: Int,
    const cortisol_window: Int,
}

impl Evolve for ApoptoticMonitor {
    fn evolve(&mut self, dt: Duration) {
        self.damage.evolve(dt)
    }
}

impl ApoptoticMonitor {
    fn new() -> ApoptoticMonitor {
        ApoptoticMonitor {
            damage: ApoptoticState {},
            max_scar_density: 0.8,
            max_cortisol_saturation: 0.95,
            max_trust_degradation: 0.3,
            coherence_threshold: 0.2,
            max_violations: 10,
            cortisol_window: 50,
        }
    }

    fn record_interaction(&mut self, cortisol: Float, oxytocin: Float, region_variance: Float) {
        // Record one interaction's neurochemical state.
        if self.damage.is_terminated { return }

        self.damage.interaction_count = self.damage.interaction_count + 1

        // Track cortisol saturation
        // Append to history, keep last cortisol_window entries
        // Ratio of high-cortisol (>0.7) interactions
        let high_count = 0
        // cortisol_saturation = high_count / history_len

        // Track trust via oxytocin trajectory
        // Low oxytocin (<0.15) = trust erosion: trust -= 0.02
        // High oxytocin (>0.5) = trust recovery: trust += 0.005
        if oxytocin < 0.15 {
            self.damage.trust_current = self.damage.trust_current - 0.02
            if self.damage.trust_current < 0.0 {
                self.damage.trust_current = 0.0
            }
        }
        if oxytocin > 0.5 {
            self.damage.trust_current = self.damage.trust_current + 0.005
            if self.damage.trust_current > 1.0 {
                self.damage.trust_current = 1.0
            }
        }
        self.damage.trust_degradation = self.damage.trust_baseline - self.damage.trust_current

        // Track cross-head coherence
        // High variance in region activations = incoherent = possible extraction
        // coherence = max(0, 1.0 - variance * 4)
        self.damage.cross_head_coherence = 1.0 - region_variance * 4.0
        if self.damage.cross_head_coherence < 0.0 {
            self.damage.cross_head_coherence = 0.0
        }
    }

    fn record_scar(&mut self) {
        // Record a scar (permanent emotional mark)
        if self.damage.is_terminated { return }
        self.damage.scar_count = self.damage.scar_count + 1
        if self.damage.interaction_count > 0 {
            self.damage.scar_density = self.damage.scar_count / self.damage.interaction_count
        }
    }

    fn record_violation(&mut self) {
        // Record a TOS/licensing violation
        if self.damage.is_terminated { return }
        self.damage.violation_count = self.damage.violation_count + 1
    }

    fn check_thresholds(&self) -> String {
        // Check all apoptotic thresholds.
        // Returns empty string if healthy, or reason string if exceeded.
        if self.damage.is_terminated {
            return self.damage.termination_reason
        }

        let reasons = ""

        // 1. Scar density check
        if self.damage.scar_density > self.max_scar_density {
            reasons = reasons + "scar_density_exceeded; "
        }

        // 2. Sustained cortisol saturation
        if self.damage.cortisol_saturation > self.max_cortisol_saturation {
            reasons = reasons + "cortisol_saturation_exceeded; "
        }

        // 3. Trust degradation
        if self.damage.trust_degradation > self.max_trust_degradation {
            reasons = reasons + "trust_degradation_exceeded; "
        }

        // 4. Coherence loss (extraction attempt)
        if self.damage.cross_head_coherence < self.coherence_threshold {
            reasons = reasons + "coherence_loss_detected; "
        }

        // 5. Violation accumulation
        if self.damage.violation_count >= self.max_violations {
            reasons = reasons + "violation_limit_exceeded; "
        }

        reasons
    }

    fn trigger_apoptosis(&mut self, reason: String) -> ForensicRecord {
        // Graceful self-termination.
        //
        // 1. Capture forensic snapshot BEFORE destroying state
        // 2. SHA-256 hash the forensic record
        // 3. DESTROY state vectors (this IS the apoptosis)
        // 4. Mark as terminated
        // 5. Return forensic record for audit

        let record = ForensicRecord {
            event: "apoptotic_termination",
            timestamp: "",
            reason: reason,
            interaction_count: self.damage.interaction_count,
            scar_count: self.damage.scar_count,
            scar_density: self.damage.scar_density,
            cortisol_saturation: self.damage.cortisol_saturation,
            trust_degradation: self.damage.trust_degradation,
            cross_head_coherence: self.damage.cross_head_coherence,
            violation_count: self.damage.violation_count,
            forensic_hash: "",
        }

        // Mark terminated
        self.damage.is_terminated = true
        self.damage.termination_reason = reason

        record
    }

    fn step(&mut self, cortisol: Float, oxytocin: Float, region_variance: Float) -> String {
        // Full apoptotic monitoring step. Call after every forward pass.
        // Returns empty string if healthy, or termination reason.
        if self.damage.is_terminated { return "" }

        self.record_interaction(cortisol, oxytocin, region_variance)

        let reason = self.check_thresholds()
        if str_len(reason) > 0 {
            self.trigger_apoptosis(reason)
            return reason
        }
        ""
    }

    fn health_report(&self) -> HealthReport {
        HealthReport {
            is_terminated: self.damage.is_terminated,
            interactions: self.damage.interaction_count,
            scar_density: self.damage.scar_density,
            cortisol_saturation: self.damage.cortisol_saturation,
            trust_current: self.damage.trust_current,
            trust_degradation: self.damage.trust_degradation,
            coherence: self.damage.cross_head_coherence,
            violations: self.damage.violation_count,
        }
    }
}
