//! Tracing subscriber initialisation with JSON output.
//!
//! Uses a custom `MsgJsonFormat` that injects `_msg` as the first field
//! for VictoriaLogs compatibility.

use crate::msg_json_fmt::MsgJsonFormat;

use once_cell::sync::Lazy;
use std::str::FromStr;
use tracing_subscriber::{
    fmt::{self, format::FmtSpan, Layer as FmtLayer},
    layer::SubscriberExt,
    util::SubscriberInitExt,
    EnvFilter,
};

/// Global instance identifier, resolved once at startup.
/// Priority: `INSTANCE_ID` env var → system hostname → `"unknown"`.
pub static INSTANCE_ID: Lazy<String> = Lazy::new(|| {
    std::env::var("INSTANCE_ID")
        .ok()
        .filter(|s| !s.is_empty())
        .or_else(|| {
            hostname::get()
                .ok()
                .and_then(|h| h.into_string().ok())
                .filter(|s| !s.is_empty())
        })
        .unwrap_or_else(|| "unknown".to_string())
});

/// Returns the platform-wide instance identifier for this process.
pub fn instance_id() -> String {
    INSTANCE_ID.clone()
}

/// Initialises the global tracing subscriber with JSON-formatted output to stderr.
///
/// Each JSON line includes `_msg` (first field), `timestamp`, `level`, `target`,
/// `file`, `line`, and structured event fields.
/// `RUST_LOG` env var controls the log level filter.
///
/// Pass `defer = true` when OTLP will be initialized afterwards via `init_otlp()`;
/// in that case this function only builds the subscriber without calling `try_init()`,
/// and the combined (fmt + OTLP) subscriber is installed by `init_otlp()` instead.
pub fn init_tracing_subscriber(level: &str, defer: bool) {
    let env_filter = EnvFilter::try_from_default_env()
        .or_else(|_| EnvFilter::from_str(level))
        .expect("invalid log level");

    let mut fmt_layer: FmtLayer<_, _, _, _> = fmt::layer()
        .event_format(MsgJsonFormat);
    fmt_layer.set_span_events(FmtSpan::CLOSE);

    let registry = tracing_subscriber::registry()
        .with(env_filter)
        .with(fmt_layer);

    if defer {
        return;
    }

    let _ = registry.try_init();
}
