using OpenTelemetry.Metrics;
using OpenTelemetry.Resources;
using OpenTelemetry.Trace;
using Tiku.Infrastructure.Observability;

namespace Tiku.Api.Configuration;

internal static class ObservabilityExtensions
{
    internal static IServiceCollection AddApiObservability(
        this IServiceCollection services,
        IConfiguration configuration,
        IHostEnvironment environment)
    {
        var endpoint = configuration["OpenTelemetry:OtlpEndpoint"];
        var hasOtlpEndpoint = Uri.TryCreate(endpoint, UriKind.Absolute, out var endpointUri);

        services.AddOpenTelemetry()
            .ConfigureResource(resource => resource.AddService(
                serviceName: environment.ApplicationName,
                serviceVersion: typeof(ObservabilityExtensions).Assembly.GetName().Version?.ToString()))
            .WithTracing(tracing => tracing
                .AddAspNetCoreInstrumentation(options =>
                    options.Filter = context => !context.Request.Path.StartsWithSegments("/api/health"))
                .AddHttpClientInstrumentation()
                .AddSource("Npgsql")
                .ApplyIf(hasOtlpEndpoint, builder => builder.AddOtlpExporter(options => options.Endpoint = endpointUri!)))
            .WithMetrics(metrics => metrics
                .AddAspNetCoreInstrumentation()
                .AddHttpClientInstrumentation()
                .AddMeter(DatabasePerformanceTelemetry.MeterName, "Tiku.Security.Redis", "Npgsql")
                .ApplyIf(hasOtlpEndpoint, builder => builder.AddOtlpExporter(options => options.Endpoint = endpointUri!)));

        return services;
    }

    private static TBuilder ApplyIf<TBuilder>(this TBuilder builder, bool condition, Action<TBuilder> configure)
    {
        if (condition)
        {
            configure(builder);
        }

        return builder;
    }
}
