#[path = "support/utils.rs"]
mod _utils;

use _utils::{
    boxed_error, cleanup_run, create_client, is_permission_denied_like, new_run_id, print_summary,
    require, ScenarioConfig,
};
use mubit_sdk::{Client, TransportMode};
use serde_json::{json, Value};
use std::error::Error;
use std::time::Instant;

async fn run_lane(
    client: &Client,
    run_id: &str,
    query: &str,
    expect_enabled: bool,
) -> Result<Value, Box<dyn Error>> {
    let payload = client
        .control
        .query(json!({
            "run_id": run_id,
            "query": query,
            "schema": "",
            "mode": "direct_bypass",
            "direct_lane": "semantic_search",
            "include_linked_runs": false,
            "limit": 5,
            "embedding": [],
        }))
        .await;

    match payload {
        Ok(payload) => {
            require(
                expect_enabled,
                format!("direct bypass semantic lane unexpectedly succeeded: {payload}"),
            )?;
            require(
                payload.get("mode").and_then(Value::as_str) == Some("direct_bypass"),
                format!("unexpected mode payload: {payload}"),
            )?;

            Ok(json!({
                "enabled": true,
                "status": "ok",
                "mode": payload.get("mode").cloned().unwrap_or(Value::Null),
                "final_answer": payload.get("final_answer").and_then(Value::as_str).unwrap_or_default(),
            }))
        }
        Err(err) => {
            if expect_enabled {
                return Err(boxed_error(format!(
                    "direct bypass semantic lane expected enabled but failed: {err}"
                )));
            }
            let message = err.to_string();
            require(
                is_permission_denied_like(&message),
                format!("direct bypass semantic lane should fail with permission denied: {message}"),
            )?;
            Ok(json!({
                "enabled": false,
                "status": "denied",
                "message": message,
            }))
        }
    }
}

#[tokio::main(flavor = "current_thread")]
async fn main() -> Result<(), Box<dyn Error>> {
    let name = "control_query_direct_bypass_matrix";
    let started = Instant::now();
    let config = ScenarioConfig::from_env();
    let client = create_client().await?;
    let run_id = new_run_id("control_query_direct_bypass");
    client.set_run_id(Some(run_id.clone()));
    client.set_transport(TransportMode::Http);

    let mut passed = true;
    let mut detail = "validated control query direct bypass semantic lane".to_string();
    let mut metrics = json!({});

    let scenario = async {
        let semantic = run_lane(
            &client,
            &run_id,
            "semantic direct bypass probe",
            config.expect_direct_search_enabled,
        )
        .await?;

        metrics = json!({
            "run_id": run_id,
            "expect_direct_search_enabled": config.expect_direct_search_enabled,
            "semantic": semantic,
        });

        Ok::<(), Box<dyn Error>>(())
    }
    .await;

    if let Err(err) = scenario {
        passed = false;
        detail = err.to_string();
    }

    let cleanup_ok = cleanup_run(&client, &run_id).await;
    if !cleanup_ok {
        passed = false;
        detail = format!("{detail} | cleanup failures");
    }

    print_summary(
        name,
        passed,
        &detail,
        &metrics,
        started.elapsed().as_secs_f64(),
        cleanup_ok,
    );

    if passed { Ok(()) } else { Err(boxed_error(detail)) }
}
