package titracing

import (
	"context"
	"fmt"
	"os"

	"go.opentelemetry.io/contrib/propagators/b3"
	"go.opentelemetry.io/contrib/samplers/jaegerremote"
	"go.opentelemetry.io/otel"
	"go.opentelemetry.io/otel/exporters/jaeger"
	"go.opentelemetry.io/otel/sdk/resource"
	tracesdk "go.opentelemetry.io/otel/sdk/trace"
	semconv "go.opentelemetry.io/otel/semconv/v1.12.0"
)

// Environment variable names.
const (
	// Hostname for the Jaeger agent, part of address where exporter sends spans
	// i.e.	"localhost".
	envAgentHost = "OTEL_EXPORTER_JAEGER_AGENT_HOST"
)

// envOr returns an env variable's value if it is exists or the default if not.
func envOr(key, defaultValue string) string {
	if v, ok := os.LookupEnv(key); ok && v != "" {
		return v
	}
	return defaultValue
}

func InitJaeger(serviceName string) (func(context.Context) error, error) {
	exporter, err := jaeger.New(jaeger.WithAgentEndpoint())
	if err != nil {
		return nil, err
	}

	sampler := jaegerremote.New(
		serviceName,
		jaegerremote.WithSamplingServerURL(fmt.Sprintf("http://%s:5778", envOr(envAgentHost, "localhost"))),
	)

	tp := tracesdk.NewTracerProvider(
		tracesdk.WithBatcher(exporter),
		tracesdk.WithResource(resource.NewWithAttributes(
			semconv.SchemaURL,
			semconv.ServiceNameKey.String(serviceName),
		)),
		tracesdk.WithSampler(tracesdk.ParentBased(sampler)),
	)
	otel.SetTracerProvider(tp)

	p := b3.New()
	otel.SetTextMapPropagator(p)

	return tp.Shutdown, nil
}
