//! Integration test for neural bot ONNX inference.
//!
//! Requires a test model at ~/.essence-wars/agents/test_ppo_agent.onnx
//! Generate with:
//!   uv run python -c "
//!     from essence_wars.agents.ppo import PPOTrainer, PPOConfig
//!     config = PPOConfig(num_envs=4, total_timesteps=512, num_steps=64,
//!                        eval_interval=999999, log_interval=999999)
//!     trainer = PPOTrainer(config)
//!     trainer.train()
//!     trainer.save('/tmp/test_ppo.pt')
//!     from essence_wars.agents.export_onnx import export_checkpoint
//!     export_checkpoint('/tmp/test_ppo.pt', '~/.essence-wars/agents/test_ppo_agent.onnx')
//!   "

#[cfg(feature = "neural")]
mod neural_tests {
    use std::path::PathBuf;

    use cardgame::bots::{BotType, NeuralBot};

    fn test_model_path() -> PathBuf {
        dirs::home_dir()
            .expect("No home dir")
            .join(".essence-wars/agents/test_ppo_agent.onnx")
    }

    fn has_test_model() -> bool {
        test_model_path().exists()
    }

    #[test]
    fn test_neural_bot_type_parsing() {
        let bot_type: BotType = "neural:/tmp/test.onnx".parse().unwrap();
        assert_eq!(bot_type.name(), "NeuralBot");
        assert!(bot_type.is_competitive());
        assert!(!bot_type.uses_mcts());
    }

    #[test]
    fn test_neural_bot_type_invalid() {
        assert!("neural_invalid".parse::<BotType>().is_err());
    }

    #[test]
    fn test_neural_bot_loads_and_infers() {
        if !has_test_model() {
            eprintln!("SKIP: No test model at {:?}", test_model_path());
            return;
        }

        let mut bot = NeuralBot::new(&test_model_path(), true, 42)
            .expect("Failed to load neural bot");

        assert!(bot.name().contains("Neural"));

        // Test inference with dummy inputs
        use cardgame::actions::Action;
        use cardgame::bots::Bot;
        use cardgame::tensor::STATE_TENSOR_SIZE;

        let state_tensor = [0.0f32; STATE_TENSOR_SIZE];
        let mut legal_mask = [0.0f32; Action::ACTION_SPACE_SIZE];
        // Mark EndTurn (421) as legal
        legal_mask[421] = 1.0;
        let legal_actions = vec![Action::EndTurn];

        let action = bot.select_action(&state_tensor, &legal_mask, &legal_actions);
        assert_eq!(action, Action::EndTurn);
    }
}
