package tracing_test

import (
	"context"
	"fmt"
	"io"
	"net/http"
	"os/exec"
	"time"

	log "github.com/sirupsen/logrus"
	"gitlab.com/gitlab-org/labkit/tracing"
)

// This example shows how to initialize tracing
// and then wrap all incoming calls
func Example() {
	// Tell the tracer to initialize as service "gitlab-wombat"
	tracing.Initialize(tracing.WithServiceName("gitlab-wombat"))

	tr := &http.Transport{
		MaxIdleConns:       10,
		IdleConnTimeout:    30 * time.Second,
		DisableCompression: true,
	}

	client := &http.Client{
		Transport: tracing.NewRoundTripper(tr),
	}

	// Listen and propagate traces
	http.Handle("/foo",
		// Add the tracing middleware in
		tracing.Handler(
			http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
				req, err := http.NewRequest(http.MethodGet, "http://localhost:8080/bar", nil)
				if err != nil {
					w.WriteHeader(500)
					return
				}

				req = req.WithContext(r.Context())

				resp, err := client.Do(req)
				if err != nil {
					w.WriteHeader(500)
					return
				}
				defer resp.Body.Close()
				io.Copy(w, resp.Body)
			}),
			// Use this route identifier with the tracing middleware
			tracing.WithRouteIdentifier("/foo"),
		))

	// Listen and propagate traces
	http.Handle("/bar",
		// Add the tracing middleware in
		tracing.Handler(
			http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
				fmt.Fprintf(w, "bar")
			}),
			// Use this route identifier with the tracing middleware
			tracing.WithRouteIdentifier("/bar"),
		))

	log.Fatal(http.ListenAndServe(":0", nil))
}

func ExampleNewEnvInjector() {
	envInjector := tracing.NewEnvInjector()

	cmd := exec.Command("ls")
	env := []string{
		"FOO=bar",
	}

	// envInjector will inject any required values
	cmd.Env = envInjector(context.Background(), env)

	if err := cmd.Run(); err != nil {
		log.WithError(err).Fatal("Command failed")
	}
}

func ExampleExtractFromEnv() {
	// Tell the tracer to initialize as service "gitlab-child-process"
	tracing.Initialize(tracing.WithServiceName("gitlab-child-process"))

	ctx, finished := tracing.ExtractFromEnv(context.Background())
	defer finished()

	// Program execution happens here...
	func(_ context.Context) {}(ctx)
}
