//! `llm-judge` matcher evaluation on the live run path.
//!
//! Split out of [`super`] (the executor) to keep that module under the
//! production-line guard. The judge is a provider-backed, async matcher: it
//! asks a model to grade a candidate value against a rubric and folds the
//! verdict into the executor's `Result<(), String>` failure type, mirroring
//! [`super::check_similar`] and [`super::check_llm_jury`].

use serde_json::Value;

use crate::eval::provider::LlmProvider;
use crate::matchers::llm_judge;

use super::matcher_result::from_assertion;

/// Evaluate an `llm-judge` assertion through the LLM provider.
///
/// It needs a provider and runs on the async path. The judge model is the
/// block's `model:` when set, otherwise `default_model` (the agent's model,
/// installed via [`super::McpExecutor::with_judge_model`]); without either it
/// fails with a clear message rather than guessing. The model must be one the
/// installed provider can serve. A provider error renders as a failure string
/// so the runner reports it like any other assertion failure.
pub(super) async fn check_llm_judge(
    actual: &Value,
    raw: &Value,
    provider: Option<&dyn LlmProvider>,
    default_model: Option<&str>,
    subject_model: Option<&str>,
) -> Result<(), String> {
    let Some(provider) = provider else {
        return Err(
            "matcher `llm-judge` requires an LlmProvider; build McpExecutor with `with_provider`"
                .to_string(),
        );
    };
    let block = llm_judge::parse_block(raw).map_err(|e| e.to_string())?;
    let model = block
        .config
        .model
        .as_deref()
        .or(default_model)
        .ok_or_else(|| {
            "matcher `llm-judge` needs a model: set `model:` in the block, or run it against an \
         agent whose model the judge can reuse"
                .to_string()
        })?;
    let outcome = llm_judge::evaluate_block(&block, subject_model, actual, provider, model)
        .await
        .map_err(|e| format!("llm-judge provider error: {e}"))?;
    from_assertion(outcome)
}
