// Copyright 2018-2026 the Deno authors. MIT license.

//! TLS key logging support for debugging encrypted traffic.
//!
//! When the `SSLKEYLOGFILE` environment variable is set, TLS session keys
//! are written to the specified file in NSS Key Log format, which can be
//! used by tools like Wireshark to decrypt TLS traffic.

use std::env;
use std::fs::OpenOptions;
use std::sync::Arc;
use std::sync::OnceLock;

use rustls::KeyLog;
use rustls::KeyLogFile;

static SSL_KEY_LOG: OnceLock<Arc<dyn KeyLog + Send + Sync>> = OnceLock::new();

/// Eagerly initializes the global TLS key logger.
///
/// `KeyLogFile::new()` reads `SSLKEYLOGFILE` from the process environment.
/// Callers can use this to snapshot that value early, instead of on first TLS
/// config construction.
pub(super) fn init_ssl_key_log() {
  let _ = get_ssl_key_log();
}

pub fn get_ssl_key_log() -> Arc<dyn KeyLog> {
  SSL_KEY_LOG
    .get_or_init(|| {
      if let Some(path) = env::var_os("SSLKEYLOGFILE")
        && let Err(e) = {
          #[allow(
            clippy::disallowed_methods,
            reason = "keylog file uses direct fs access"
          )]
          let result = OpenOptions::new().append(true).create(true).open(&path);
          result
        }
      {
        log::warn!(
          "SSLKEYLOGFILE is set but '{}' could not be opened: {e}",
          path.to_string_lossy()
        );
      }
      Arc::new(KeyLogFile::new())
    })
    .clone()
}
