package telemetry

import (
	"context"
	"testing"
)

// TestConfigValidate covers the supported and rejected exporter selections.
func TestConfigValidate(t *testing.T) {
	if err := DefaultConfig().Validate(); err != nil {
		t.Fatalf("default config must be valid: %v", err)
	}

	otlp := DefaultConfig()
	otlp.TracesExporter = ExporterOTLP
	if err := otlp.Validate(); err != nil {
		t.Errorf("otlp exporter must be accepted: %v", err)
	}

	bad := DefaultConfig()
	bad.MetricsExporter = "prometheus"
	if err := bad.Validate(); err == nil {
		t.Error("unsupported exporter must be rejected")
	}

	noName := DefaultConfig()
	noName.ServiceName = ""
	if err := noName.Validate(); err == nil {
		t.Error("empty service name must be rejected")
	}
}

// TestNewNoneAndShutdown builds the providers with the none exporter and shuts
// them down.
func TestNewNoneAndShutdown(t *testing.T) {
	rt, err := New(context.Background(), DefaultConfig())
	if err != nil {
		t.Fatalf("New: %v", err)
	}
	if rt.TracerProvider() == nil {
		t.Error("TracerProvider must not be nil")
	}
	if rt.MeterProvider() == nil {
		t.Error("MeterProvider must not be nil")
	}
	if err := rt.Shutdown(context.Background()); err != nil {
		t.Errorf("Shutdown: %v", err)
	}
}

// TestNewStdoutTraces builds the providers with the stdout trace exporter; no
// spans are recorded, so shutdown flushes nothing to stdout.
func TestNewStdoutTraces(t *testing.T) {
	cfg := DefaultConfig()
	cfg.TracesExporter = ExporterStdout
	rt, err := New(context.Background(), cfg)
	if err != nil {
		t.Fatalf("New: %v", err)
	}
	if err := rt.Shutdown(context.Background()); err != nil {
		t.Errorf("Shutdown: %v", err)
	}
}

// TestTraceFieldsFromContextEmpty returns no fields without an active span.
func TestTraceFieldsFromContextEmpty(t *testing.T) {
	if TraceFieldsFromContext(context.Background()) != nil {
		t.Error("expected nil fields without an active span")
	}
	var nilCtx context.Context
	if TraceFieldsFromContext(nilCtx) != nil {
		t.Error("expected nil fields for a nil context")
	}
}

// TestNilRuntime checks the nil-receiver fallbacks used before initialisation.
func TestNilRuntime(t *testing.T) {
	var rt *Runtime
	if rt.TracerProvider() == nil {
		t.Error("nil runtime must fall back to the global tracer provider")
	}
	if rt.MeterProvider() == nil {
		t.Error("nil runtime must fall back to the global meter provider")
	}
	if err := rt.Shutdown(context.Background()); err != nil {
		t.Errorf("nil runtime Shutdown: %v", err)
	}
}
