use everruns_core::capabilities::TestMathCapability;
use everruns_core::llm_driver_registry::DriverRegistry;
use everruns_core::llmsim_driver::LlmSimConfig;
use everruns_core::{CapabilityRegistry, LlmProviderType, ModelWithProvider, PlatformDefinition};
use everruns_runtime::{AgentBuilder, HarnessBuilder, InProcessRuntimeBuilder, SessionBuilder};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let mut capabilities = CapabilityRegistry::new();
    capabilities.register(TestMathCapability);

    let platform = PlatformDefinition::new(capabilities, DriverRegistry::new());

    // Per-type builders are useful when an embedder needs stable ids or
    // separate construction. IDs are generated unless `.id(...)` is called.
    let harness_builder = HarnessBuilder::new("math", "You are a math assistant.")
        .display_name("Math")
        .description("Minimal embedded harness")
        .capability("test_math");
    let harness_id = harness_builder.harness_id();
    let agent_builder = AgentBuilder::new("math-agent", "Use tools when they help.")
        .display_name("Math Agent")
        .max_iterations(8);
    let agent_id = agent_builder.agent_id();
    let session_builder = SessionBuilder::new(harness_id)
        .agent(agent_id)
        .title("Embedded Math Session");
    let _per_type_builders = (
        harness_builder.build(),
        agent_builder.build(),
        session_builder.build(),
    );

    // The runtime below uses the compact convenience.
    let runtime = InProcessRuntimeBuilder::new()
        .platform_definition(platform)
        .llm_sim(
            LlmSimConfig::fixed("Let me calculate that.").with_tool_call_sequence(vec![
                vec![everruns_core::ToolCall {
                    id: "call_mul_1".into(),
                    name: "multiply".into(),
                    arguments: serde_json::json!({"a": 6, "b": 7}),
                }],
                vec![],
            ]),
        )
        .default_model(ModelWithProvider {
            model: "llmsim-model".into(),
            provider_type: LlmProviderType::LlmSim,
            api_key: Some("fake-key".into()),
            base_url: None,
        })
        .single_session(|s| {
            s.harness("math", "You are a math assistant.")
                .harness_display_name("Math")
                .harness_description("Minimal embedded harness")
                .with_capability("test_math")
                .agent("math-agent", "Use tools when they help.")
                .agent_display_name("Math Agent")
                .agent_max_iterations(8)
                .session_title("Embedded Math Session")
        })
        .build()
        .await?;

    let session_id = runtime.default_session_id().expect("single_session id");
    let result = runtime.run_text_turn(session_id, "What is 6 * 7?").await?;

    println!("success: {}", result.success);
    println!("iterations: {}", result.iterations);
    println!("response: {}", result.response);

    Ok(())
}
