//! Fieldtest c0009 #3 — degenerate-stream semantics from the docs alone.
//!
//! Axis (carrier): feed `summarize` empty / monotonic / sign-flipping HAND-BUILT
//! streams and verify the documented metric definitions hold:
//!   - total_pips        = last value of the cumulative pip curve, 0.0 if empty
//!   - max_drawdown      = max_t (running_peak(t) - equity(t)), >= 0, 0 if
//!                         monotonic-non-decreasing or empty
//!   - exposure_sign_flips = count of adjacent samples whose SIGN differs, with
//!                         zero normalizing to sign 0 (flat distinct from
//!                         long/short)
//!
//! NOTE on fixture form: `summarize(equity, exposure)` takes `&[(Timestamp, f64)]`
//! DIRECTLY as its public signature. Hand-building those slices is calling the
//! public function with literal arguments — NOT hand-authoring an intermediate
//! representation. (f64_field, the sink->slice bridge, is exercised in #1/#2/#4.)

use aura_engine::summarize;
use aura_core::Timestamp;

fn eq(samples: &[(i64, f64)]) -> Vec<(Timestamp, f64)> {
    samples.iter().map(|&(t, v)| (Timestamp(t), v)).collect()
}

fn main() {
    // --- (1) empty streams -> all zeros (documented "0.0 if empty"). ---
    let m = summarize(&[], &[]);
    println!("empty            -> {m:?}");
    assert_eq!(m.total_pips, 0.0);
    assert_eq!(m.max_drawdown, 0.0);
    assert_eq!(m.exposure_sign_flips, 0);

    // --- (2) monotonic non-decreasing curve -> drawdown 0, last value total. ---
    let equity = eq(&[(1, 0.0), (2, 1.0), (3, 3.0), (4, 6.0), (5, 10.0)]);
    let exposure = eq(&[(1, 0.5), (2, 0.5), (3, 0.5), (4, 0.5), (5, 0.5)]);
    let m = summarize(&equity, &exposure);
    println!("monotonic-up     -> {m:?}");
    assert_eq!(m.total_pips, 10.0, "last value of curve");
    assert_eq!(m.max_drawdown, 0.0, "monotonic => no drawdown");
    assert_eq!(m.exposure_sign_flips, 0, "constant-sign exposure");

    // --- (3) a dip then recovery -> worst peak-to-trough drawdown. ---
    // peak 10 at t=3, trough 4 at t=5 => max drawdown 6; recovers to 8 (final).
    let equity = eq(&[(1, 0.0), (2, 5.0), (3, 10.0), (4, 7.0), (5, 4.0), (6, 8.0)]);
    let flat = eq(&[(1, 0.0)]);
    let m = summarize(&equity, &flat);
    println!("dip-and-recover  -> {m:?}");
    assert_eq!(m.total_pips, 8.0, "final value, not the peak");
    assert_eq!(m.max_drawdown, 6.0, "peak 10 -> trough 4");

    // --- (4) sign-flipping exposure: long, short, flat, long. ---
    // signs: +,+,-,-,0,+  -> adjacent changes at (+,-), (-,0)? wait:
    //   +0.5 -> +0.5 : same (0 flips)
    //   +0.5 -> -0.5 : differ (1)
    //   -0.5 -> -0.5 : same
    //   -0.5 ->  0.0 : differ (2)   [flat distinct from short]
    //    0.0 -> +0.5 : differ (3)   [flat distinct from long]
    // => 3 sign flips.
    let exposure = eq(&[(1, 0.5), (2, 0.5), (3, -0.5), (4, -0.5), (5, 0.0), (6, 0.5)]);
    let any_eq = eq(&[(1, 0.0), (2, 0.0)]);
    let m = summarize(&any_eq, &exposure);
    println!("sign-flips long/short/flat -> {m:?}");
    assert_eq!(
        m.exposure_sign_flips, 3,
        "long->short, short->flat, flat->long all count (flat is sign 0)"
    );

    // --- (5) does the SIGN matter, not the magnitude? +0.1 vs +0.9 = no flip. ---
    let exposure = eq(&[(1, 0.1), (2, 0.9), (3, 0.3)]);
    let m = summarize(&eq(&[(1, 0.0)]), &exposure);
    println!("same-sign varying magnitude -> {m:?}");
    assert_eq!(m.exposure_sign_flips, 0, "magnitude changes are not sign flips");

    // --- (6) all-negative equity curve: total_pips can be negative (a losing run);
    // drawdown measured from the running peak (which starts at the first value). ---
    // curve: -1, -3, -2, -5  => peak is -1 (the max so far never improves above -1),
    // trough -5 => drawdown = (-1) - (-5) = 4; final = -5.
    let equity = eq(&[(1, -1.0), (2, -3.0), (3, -2.0), (4, -5.0)]);
    let m = summarize(&equity, &eq(&[(1, -1.0)]));
    println!("all-negative     -> {m:?}");
    assert_eq!(m.total_pips, -5.0, "a losing run has negative total_pips");
    assert_eq!(m.max_drawdown, 4.0, "peak -1 -> trough -5");

    println!("c0009_3 OK: empty/monotonic/dip/sign-flip/negative summarize defs all hold");
}
