using System.Diagnostics;
using Serilog.Core;
using Serilog.Events;

namespace ZB.MOM.WW.Telemetry.Serilog;

/// <summary>
/// Stamps <c>trace_id</c> and <c>span_id</c> from <see cref="Activity.Current"/> onto every Serilog
/// log event, enabling a log line to be correlated back to its originating trace in a backend.
/// When <see cref="Activity.Current"/> is null (no active span — background services, startup,
/// non-traced paths) the enricher emits nothing; it does NOT inject empty strings or zero values.
/// </summary>
public sealed class TraceContextEnricher : ILogEventEnricher
{
    /// <summary>Serilog property name carrying the W3C trace id.</summary>
    public const string TraceIdPropertyName = "trace_id";

    /// <summary>Serilog property name carrying the W3C span id.</summary>
    public const string SpanIdPropertyName = "span_id";

    /// <summary>
    /// Adds <c>trace_id</c>/<c>span_id</c> properties from <see cref="Activity.Current"/> when an
    /// activity is active; otherwise leaves the event untouched.
    /// </summary>
    /// <param name="logEvent">The log event to enrich.</param>
    /// <param name="propertyFactory">Factory used to create the trace-context properties.</param>
    public void Enrich(LogEvent logEvent, ILogEventPropertyFactory propertyFactory)
    {
        ArgumentNullException.ThrowIfNull(logEvent);
        ArgumentNullException.ThrowIfNull(propertyFactory);

        var activity = Activity.Current;
        if (activity is null)
        {
            return;
        }

        logEvent.AddPropertyIfAbsent(
            propertyFactory.CreateProperty(TraceIdPropertyName, activity.TraceId.ToString()));
        logEvent.AddPropertyIfAbsent(
            propertyFactory.CreateProperty(SpanIdPropertyName, activity.SpanId.ToString()));
    }
}
