//! HTTPS endpoints for credential retrieval by lease ID.
//!
//! Orchestrator calls GET /api/v1/leases/{lease_id}/credential after
//! receiving a `vault.lease.issued` NATS event. The actual credential
//! value never travels over NATS.

use std::sync::Arc;

use axum::{
    extract::{Path, State},
    http::StatusCode,
    response::{IntoResponse, Json},
};
use serde::Serialize;
use tracing::{info, warn};

use crate::leases::LeaseStore;

#[derive(Debug, Serialize)]
pub struct CredentialResponse {
    pub lease_id: String,
    pub value: String,
}

#[derive(Debug, Serialize)]
struct ErrorResponse {
    pub error: String,
}

/// GET /api/v1/leases/{lease_id}/credential
///
/// Returns the plaintext credential for a valid, non-expired lease.
/// Authentication of the caller is handled by the middleware layer.
pub async fn get_credential(
    State(store): State<Arc<LeaseStore>>,
    Path(lease_id): Path<String>,
) -> impl IntoResponse {
    match store.get_credential(&lease_id) {
        Some(value) => {
            info!(lease_id = %lease_id, "Credential retrieved for lease");
            (StatusCode::OK, Json(CredentialResponse { lease_id, value })).into_response()
        }
        None => {
            warn!(lease_id = %lease_id, "Credential request for unknown/expired lease");
            (
                StatusCode::NOT_FOUND,
                Json(ErrorResponse {
                    error: format!("Lease {} not found or expired", lease_id),
                }),
            )
                .into_response()
        }
    }
}

/// DELETE /api/v1/leases/{lease_id}
///
/// Revokes a lease, zeroing its credential in-memory.
pub async fn revoke_lease(
    State(store): State<Arc<LeaseStore>>,
    Path(lease_id): Path<String>,
) -> StatusCode {
    store.revoke(&lease_id);
    info!(lease_id = %lease_id, "Lease revoked");
    StatusCode::NO_CONTENT
}
