//! WASM device key management -- private keys never cross to JS.

use std::sync::Mutex;

use once_cell::sync::Lazy;
use zeroize::Zeroizing;

use relicario_core::device as core_device;

/// In-memory device key storage (private keys held in WASM linear memory).
static DEVICE_STATE: Lazy<Mutex<Option<DeviceState>>> = Lazy::new(|| Mutex::new(None));

struct DeviceState {
    name: String,
    signing_private: Zeroizing<String>,
    signing_public: String,
    /// Deploy key stored for future SSH git operations; not yet used for signing.
    #[allow(dead_code)]
    deploy_private: Zeroizing<String>,
    deploy_public: String,
}

/// Register a new device, storing the keypairs internally and returning
/// only the public keys. Private keys never leave WASM memory.
pub fn register_device(name: &str) -> Result<(String, String), String> {
    let (signing_priv, signing_pub) =
        core_device::generate_keypair().map_err(|e| e.to_string())?;
    let (deploy_priv, deploy_pub) =
        core_device::generate_keypair().map_err(|e| e.to_string())?;

    let state = DeviceState {
        name: name.to_string(),
        signing_private: signing_priv,
        signing_public: signing_pub.clone(),
        deploy_private: deploy_priv,
        deploy_public: deploy_pub.clone(),
    };

    *DEVICE_STATE.lock().unwrap() = Some(state);

    Ok((signing_pub, deploy_pub))
}

/// Sign `data` using the registered device's signing key.
/// Returns a base64-encoded signature.
pub fn sign_for_git(data: &[u8]) -> Result<String, String> {
    let guard = DEVICE_STATE.lock().unwrap();
    let state = guard
        .as_ref()
        .ok_or_else(|| "no device registered".to_string())?;

    core_device::sign(&state.signing_private, data).map_err(|e| e.to_string())
}

/// Return current device info: (name, signing_public_key, deploy_public_key).
/// Returns None if no device has been registered in this session.
pub fn get_device_info() -> Option<(String, String, String)> {
    let guard = DEVICE_STATE.lock().unwrap();
    guard.as_ref().map(|s| {
        (
            s.name.clone(),
            s.signing_public.clone(),
            s.deploy_public.clone(),
        )
    })
}

/// Clear device state (call on logout or before re-registration).
pub fn clear_device() {
    *DEVICE_STATE.lock().unwrap() = None;
}
