// Copyright 2021 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// +build !disable_events

package otel_test

import (
	"bytes"
	"context"
	"fmt"
	"io"
	"testing"

	sdktrace "go.opentelemetry.io/otel/sdk/trace"
	"go.opentelemetry.io/otel/trace"
	"golang.org/x/exp/event"
	"golang.org/x/exp/event/otel"
)

func TestTrace(t *testing.T) {
	// Verify that otel and event traces work well together.
	// This test uses a single, fixed span tree (see makeTraceSpec).
	// Each test case varies which of the individual spans are
	// created directly from an otel tracer, and which are created
	// using the event package.

	want := "root (f (g h) p (q r))"

	for i, tfunc := range []func(int) bool{
		func(int) bool { return true },
		func(int) bool { return false },
		func(i int) bool { return i%2 == 0 },
		func(i int) bool { return i%2 == 1 },
		func(i int) bool { return i%3 == 0 },
		func(i int) bool { return i%3 == 1 },
	} {
		ctx, tr, shutdown := setupOtel()
		// There are 7 spans, so we create a 7-element slice.
		// tfunc determines, for each index, whether it holds
		// an otel tracer or nil.
		tracers := make([]trace.Tracer, 7)
		for i := 0; i < len(tracers); i++ {
			if tfunc(i) {
				tracers[i] = tr
			}
		}
		s := makeTraceSpec(tracers)
		s.apply(ctx)
		got := shutdown()
		if got != want {
			t.Errorf("#%d: got %v, want %v", i, got, want)
		}
	}
}

func makeTraceSpec(tracers []trace.Tracer) *traceSpec {
	return &traceSpec{
		name:   "root",
		tracer: tracers[0],
		children: []*traceSpec{
			{
				name:   "f",
				tracer: tracers[1],
				children: []*traceSpec{
					{name: "g", tracer: tracers[2]},
					{name: "h", tracer: tracers[3]},
				},
			},
			{
				name:   "p",
				tracer: tracers[4],
				children: []*traceSpec{
					{name: "q", tracer: tracers[5]},
					{name: "r", tracer: tracers[6]},
				},
			},
		},
	}
}

type traceSpec struct {
	name     string
	tracer   trace.Tracer // nil for event
	children []*traceSpec
}

// apply builds spans for the traceSpec and all its children,
// If the traceSpec has a non-nil tracer, it is used to create the span.
// Otherwise, event.Trace.Start is used.
func (s *traceSpec) apply(ctx context.Context) {
	if s.tracer != nil {
		var span trace.Span
		ctx, span = s.tracer.Start(ctx, s.name)
		defer span.End()
	} else {
		var eb event.Builder
		ctx, eb = event.To(ctx).Start(s.name)
		defer eb.End()
	}
	for _, c := range s.children {
		c.apply(ctx)
	}
}

func setupOtel() (context.Context, trace.Tracer, func() string) {
	ctx := context.Background()
	e := newTestExporter()
	bsp := sdktrace.NewSimpleSpanProcessor(e)
	stp := sdktrace.NewTracerProvider(sdktrace.WithSpanProcessor(bsp))
	tracer := stp.Tracer("")

	ee := event.NewExporter(otel.NewTraceHandler(tracer), nil)
	ctx = event.WithExporter(ctx, ee)
	return ctx, tracer, func() string { stp.Shutdown(ctx); return e.got }
}

// testExporter is an otel exporter for traces
type testExporter struct {
	m   map[trace.SpanID][]*sdktrace.SpanSnapshot // key is parent SpanID
	got string
}

var _ sdktrace.SpanExporter = (*testExporter)(nil)

func newTestExporter() *testExporter {
	return &testExporter{m: map[trace.SpanID][]*sdktrace.SpanSnapshot{}}
}

func (e *testExporter) ExportSpans(ctx context.Context, ss []*sdktrace.SpanSnapshot) error {
	for _, s := range ss {
		sid := s.Parent.SpanID()
		e.m[sid] = append(e.m[sid], s)
	}
	return nil
}

func (e *testExporter) Shutdown(ctx context.Context) error {
	root := e.m[trace.SpanID{}][0]
	var buf bytes.Buffer
	e.print(&buf, root)
	e.got = buf.String()
	return nil
}

func (e *testExporter) print(w io.Writer, ss *sdktrace.SpanSnapshot) {
	fmt.Fprintf(w, "%s", ss.Name)
	children := e.m[ss.SpanContext.SpanID()]
	if len(children) > 0 {
		fmt.Fprint(w, " (")
		for i, ss := range children {
			if i != 0 {
				fmt.Fprint(w, " ")
			}
			e.print(w, ss)
		}
		fmt.Fprint(w, ")")
	}
}
