//! Gated integration test for the M1-window upper-bound contract (Gitea #23).
//!
//! Property under protection: an *unbounded* upper bound is expressible through
//! `load_m1_window` and is non-panicking — it must yield exactly the bars a
//! finite sane bound covering the same data would. The underlying
//! `data_server::stream_m1_windowed` already takes `Option<i64>` per bound
//! (`None` = unbounded, skipping the coarse `unix_ms_to_year_month` file
//! filter). The aura wrapper must thread that `Option` through so callers can
//! express "to the end of history" without reaching for a sentinel — the
//! natural `i64::MAX` sentinel panics in chrono's `from_timestamp_millis`
//! inside the data-server file filter (`records.rs:28`).
//!
//! Skips with a note where the local Pepperstone archive is absent, so
//! `cargo test --workspace` stays green anywhere; it exercises the real
//! ingestion path where data exists. The trigger is minimized to the latest
//! single AAPL.US month so the unbounded read stays a few thousand bars.

use std::sync::Arc;

use aura_ingest::load_m1_window;
use data_server::{DataServer, DEFAULT_DATA_PATH};

#[test]
fn unbounded_upper_bound_matches_finite_sane_bound() {
    let server = Arc::new(DataServer::new(DEFAULT_DATA_PATH));
    if !server.has_symbol("AAPL.US") {
        eprintln!("skip: no local data at {DEFAULT_DATA_PATH} (symbol AAPL.US absent)");
        return; // hermetic elsewhere; exercises the real path where files exist
    }

    // Minimal trigger: start at the latest archived month so "to the end of
    // history" resolves to one small tail file, not the full multi-year set.
    // 2026-05-01 00:00:00 UTC in inclusive Unix-ms.
    let from_ms = 1_777_996_800_000_i64;
    // A finite sane upper bound far past any real bar (2035-01-01), the
    // workaround the #23 reporter used in place of the panicking i64::MAX.
    let sane_upper = 2_051_222_400_000_i64;

    // The reference: a finite bound that covers all remaining bars.
    let bounded = load_m1_window(&server, "AAPL.US", Some(from_ms), Some(sane_upper))
        .expect("AAPL.US has data from 2026-05 onward");
    assert!(!bounded.ts.is_empty(), "tail window resolved to zero bars");

    // The behaviour #23 asks for: an unbounded upper bound (`None`) must be
    // expressible and must NOT panic — today the wrapper hardcodes `Some(..)`,
    // so this is unrepresentable, and the only sentinel a caller can pass
    // (`i64::MAX`) panics upstream in `unix_ms_to_year_month`.
    let unbounded = load_m1_window(&server, "AAPL.US", Some(from_ms), None)
        .expect("unbounded upper bound yields the same data as the sane finite bound");

    // Same data, bar-for-bar: an open upper bound is exactly "no upper filter".
    assert_eq!(
        unbounded, bounded,
        "unbounded upper bound must equal the finite sane bound covering the same tail"
    );
}
