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

use super::{common, ToolResult};

#[derive(Debug, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct StoreParams {
    pub name: String,
    pub value: String,
    #[serde(default)]
    pub force: bool,
}

pub async fn execute(params: StoreParams) -> ToolResult {
    common::validate_secret_name(&params.name, "name")?;
    common::require_trimmed_non_empty(&params.value, "value")?;
    common::validate_bounded_string(&params.value, "value", common::MAX_STRING_LENGTH)?;
    if crate::settings::plaintext_store_disabled() {
        return Err(crate::settings::STORE_DISABLED_MESSAGE.to_string());
    }

    let signals = envseal::ops::store_secret(&params.name, params.value.as_bytes(), params.force)
        .map_err(|e| e.to_string())?;

    // Surface signals as structured JSON so the MCP client can render
    // them in its own UI rather than scraping the stderr stream that
    // `store_secret` emits in parallel.
    let entropy_warnings: Vec<_> = signals
        .iter()
        .map(|s| {
            json!({
                "id": s.id.as_str(),
                "category": s.category.as_str(),
                "severity": s.severity.as_str(),
                "label": s.label,
                "detail": s.detail,
                "mitigation": s.mitigation,
            })
        })
        .collect();

    Ok(json!({
        "stored": true,
        "name": params.name,
        "entropy_warnings": entropy_warnings,
    }))
}
