use serde::Deserialize;
use serde_json::json;

use super::{common, ToolResult};

#[derive(Debug, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct SupervisedParams {
    pub secret_name: String,
    pub env_var: String,
    pub command: Vec<String>,
    /// Optional sandbox tier: `"standard"` (default), `"hardened"`, or `"lockdown"`.
    #[serde(default)]
    pub sandbox: Option<String>,
}

pub async fn execute(params: SupervisedParams) -> ToolResult {
    common::validate_secret_name(&params.secret_name, "secret_name")?;
    common::require_trimmed_non_empty(&params.env_var, "env_var")?;
    common::validate_bounded_string(&params.env_var, "env_var", common::MAX_STRING_LENGTH)?;
    common::validate_command(&params.command)?;
    let tier = common::parse_sandbox_profile(params.sandbox.as_deref())?;

    let result = tokio::task::spawn_blocking(
        move || -> Result<envseal::supervisor::SupervisedResult, String> {
            let vault = envseal::vault::Vault::open_default().map_err(|e| e.to_string())?;
            envseal::supervisor::supervised_execute(
                &vault,
                &params.secret_name,
                &params.env_var,
                &params.command,
                tier,
            )
            .map_err(|e| e.to_string())
        },
    )
    .await
    .map_err(|e| format!("supervised task failed: {e}"))??;

    Ok(json!({
        "status": "completed",
        "mode": "supervised",
        "tier": tier.as_str(),
        "exit_code": result.exit_code,
        "leak_events": result.leak_events,
    }))
}
