//! PPO model integration test
//!
//! Verifies: create model -> forward pass -> valid output with padding
//! Uses lightweight config for fast execution (<10s)

use ml::ensemble::adapters::PpoInferenceAdapter;
use ml::ensemble::inference_adapter::{FeatureVector, ModelInferenceAdapter};
use ml::ppo::ppo::PPOConfig;

fn small_ppo_config() -> PPOConfig {
    PPOConfig {
        state_dim: 64,
        num_actions: 45,
        policy_hidden_dims: vec![32, 32],
        value_hidden_dims: vec![32, 32],
        ..Default::default()
    }
}

#[test]
fn test_ppo_adapter_produces_valid_prediction() {
    let adapter =
        PpoInferenceAdapter::new(small_ppo_config()).expect("PpoInferenceAdapter::new should succeed");

    assert_eq!(adapter.model_name(), "PPO");
    assert!(adapter.is_ready());

    // 51-dim input gets zero-padded to state_dim=64
    let fv = FeatureVector {
        values: vec![0.1; 51],
        timestamp: 1_700_000_000_000_000,
    };

    let pred = adapter.predict(&fv).expect("PPO predict should succeed");

    assert!(
        pred.direction >= -1.0 && pred.direction <= 1.0,
        "direction {} out of [-1,1]",
        pred.direction
    );
    assert!(
        pred.confidence >= 0.0 && pred.confidence <= 1.0,
        "confidence {} out of [0,1]",
        pred.confidence
    );
    assert!(pred.direction.is_finite(), "direction must not be NaN/Inf");
    assert!(
        pred.confidence.is_finite(),
        "confidence must not be NaN/Inf"
    );
}

#[test]
fn test_ppo_deterministic_inference() {
    let adapter =
        PpoInferenceAdapter::new(small_ppo_config()).expect("PpoInferenceAdapter::new should succeed");

    let fv = FeatureVector {
        values: vec![0.3; 51],
        timestamp: 1_700_000_000_000_000,
    };

    let pred1 = adapter.predict(&fv).expect("predict 1");
    let pred2 = adapter.predict(&fv).expect("predict 2");

    assert_eq!(
        pred1.direction, pred2.direction,
        "PPO inference should be deterministic"
    );
}

#[test]
fn test_ppo_handles_short_input() {
    let adapter =
        PpoInferenceAdapter::new(small_ppo_config()).expect("PpoInferenceAdapter::new should succeed");

    // 10-dim input (much shorter than state_dim=64) should still work via padding
    let fv = FeatureVector {
        values: vec![0.5; 10],
        timestamp: 1_700_000_000_000_000,
    };

    let pred = adapter
        .predict(&fv)
        .expect("PPO should handle short input via padding");
    assert!(pred.direction.is_finite());
    assert!(pred.confidence.is_finite());
}
