//! `POST /lic/web/api/plugin-sign` — signs a plugin's status/heartbeat
//! payload with the server's Ed25519 secret. The client (plugin runtime,
//! src/plugin/callback_msg.rs:282-296) sends:
//!
//!   `{ "plugin_id": "...", "version": "...", "msg": [u8, u8, ...] }`
//!
//! and expects:
//!
//!   `{ "signed_msg": [u8, u8, ...] }`
//!
//! No Authorization header — the client opens this without a token. Auth
//! is implicit via the licence-key shared secret on the rest of the
//! deployment; we just sign whatever is asked. (Pro can additionally
//! validate the plugin against an allowlist; OSS just signs.)

use crate::api::error::ApiError;
use axum::Json;
use serde::{Deserialize, Serialize};
use sodiumoxide::crypto::sign;
use std::sync::Arc;

#[derive(Debug, Deserialize)]
pub struct PluginSignReq {
    #[serde(default)]
    pub plugin_id: String,
    #[serde(default)]
    pub version: String,
    pub msg: Vec<u8>,
}

#[derive(Debug, Serialize)]
pub struct PluginSignResp {
    pub signed_msg: Vec<u8>,
}

/// The signing key is the same Ed25519 secret hbbs already uses for
/// rendezvous KeyExchange (`id_ed25519`). We pull it from the shared
/// `RendezvousServer.inner.sk` via the AppState — but `AppState` doesn't
/// hold it today, so this handler reads it directly from a process-wide
/// `OnceCell` populated at startup. (See `set_signing_key` below.)
pub async fn plugin_sign(
    Json(req): Json<PluginSignReq>,
) -> Result<Json<PluginSignResp>, ApiError> {
    let sk = SIGNING_KEY
        .get()
        .ok_or_else(|| ApiError::Internal("plugin signing not configured".into()))?;
    let signed = sign::sign(&req.msg, sk);
    Ok(Json(PluginSignResp { signed_msg: signed }))
}

use once_cell::sync::OnceCell;

static SIGNING_KEY: OnceCell<Arc<sign::SecretKey>> = OnceCell::new();

/// Called once from `RendezvousServer::start` after the keypair is loaded.
/// A no-op if already set; the server will only ever have one Ed25519 key.
pub fn set_signing_key(sk: sign::SecretKey) {
    let _ = SIGNING_KEY.set(Arc::new(sk));
}
