//! Drive the codegen-emitted `fixture_client` crate against a live
//! FastAPI fixture. Validates not just the kernel wire (which
//! `drive_kernel.rs` already covers) but that the codegen actually
//! produces typed-functions that round-trip cleanly through the same
//! kernel.

use std::env;
use std::process::ExitCode;

use mizan_rust::{MizanClient, MizanConfig};

use fixture_client::contexts::user::{fetch_user_context, UserContextParams};
use fixture_client::functions::echo::call_echo;
use fixture_client::functions::find_user::call_find_user;
use fixture_client::functions::rename_user::call_rename_user;
use fixture_client::functions::whoami::call_whoami;
use fixture_client::mutations::update_profile::call_update_profile;
use fixture_client::types::{
    EchoInput, FindUserInput, RenameUserInput, UpdateProfileInput,
};


#[tokio::main]
async fn main() -> ExitCode {
    let base_url = env::args().nth(1)
        .unwrap_or_else(|| "http://127.0.0.1:8765/api/mizan".to_string());
    let client = MizanClient::new(MizanConfig {
        base_url,
        session: false,
        ..Default::default()
    });

    let mut failures = 0usize;

    match call_echo(&client, &EchoInput { text: "hello".to_string() }).await {
        Ok(out) => println!("call_echo -> message={:?}", out.message),
        Err(e) => { eprintln!("call_echo ERR {e}"); failures += 1; }
    }

    match call_whoami(&client).await {
        Ok(out) => println!("call_whoami -> authenticated={} email={:?}", out.authenticated, out.email),
        Err(e) => { eprintln!("call_whoami ERR {e}"); failures += 1; }
    }

    match call_find_user(&client, &FindUserInput { user_id: 99999 }).await {
        Ok(None) => println!("call_find_user(99999) -> None"),
        Ok(Some(out)) => println!("call_find_user(99999) -> user_id={} name={:?}", out.user_id, out.name),
        Err(e) => { eprintln!("call_find_user ERR {e}"); failures += 1; }
    }

    match call_update_profile(&client, &UpdateProfileInput { user_id: 5, name: "Ryth".to_string() }).await {
        Ok(out) => println!("call_update_profile -> ok={}", out.ok),
        Err(e) => { eprintln!("call_update_profile ERR {e}"); failures += 1; }
    }

    match call_rename_user(&client, &RenameUserInput { user_id: 5, name: "RythR".to_string() }).await {
        Ok(out) => println!("call_rename_user -> user_id={} name={:?}", out.user_id, out.name),
        Err(e) => { eprintln!("call_rename_user ERR {e}"); failures += 1; }
    }

    match fetch_user_context(&client, &UserContextParams { user_id: 5 }).await {
        Ok(out) => println!(
            "fetch_user_context(5) -> user_profile={{ user_id:{}, name:{:?} }} user_orders.len={}",
            out.user_profile.user_id, out.user_profile.name, out.user_orders.len(),
        ),
        Err(e) => { eprintln!("fetch_user_context ERR {e}"); failures += 1; }
    }

    if failures > 0 {
        eprintln!("[drive_emitted] {failures} probe(s) failed");
        ExitCode::FAILURE
    } else {
        ExitCode::SUCCESS
    }
}
