package loggingtracer

import (
	"context"
	"fmt"
	"regexp"
	"testing"
	"time"

	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/require"
	"go.opencensus.io/trace"
	"go.skia.org/infra/go/now"
)

func TestLoggingTracer(t *testing.T) {
	fakeNow := time.Date(2023, time.January, 1, 0, 0, 0, 0, time.UTC)

	// Initialize logging tracer.
	originalTracer := trace.DefaultTracer
	Initialize()
	defer func() { trace.DefaultTracer = originalTracer }()

	// Capture logs.
	var logs []string
	originalLogf := Logf
	Logf = func(format string, v ...interface{}) {
		logs = append(logs, fmt.Sprintf(format, v...))
	}
	defer func() { Logf = originalLogf }()

	ctx := now.TimeTravelingContext(t.Context(), fakeNow)
	a(ctx)

	// These patterns make this test case fragile (i.e. inserting/deleting lines in this file might
	// break this test case), but it is important to test that we are reporting the correct line
	// numbers.
	expectedLogPatterns := []string{
		`^Starting span: a \[.*/loggingtracer_test.go:69]$`,
		`^Starting span: b \[.*/loggingtracer_test.go:77]$`,
		`^Starting span: c \[.*/loggingtracer_test.go:85]$`,
		`^Starting span: d \[.*/loggingtracer_test.go:92]$`,
		`^Ending span: d \[.*/loggingtracer_test.go:94] \(1s\)$`,
		`^Ending span: c \[.*/loggingtracer_test.go:88] \(3s\)$`,
		`^Starting span: c \[.*/loggingtracer_test.go:85]$`,
		`^Starting span: d \[.*/loggingtracer_test.go:92]$`,
		`^Ending span: d \[.*/loggingtracer_test.go:94] \(1s\)$`,
		`^Ending span: c \[.*/loggingtracer_test.go:88] \(3s\)$`,
		`^Ending span: b \[.*/loggingtracer_test.go:81] \(11s\)$`,
		`^Starting span: e \[.*/loggingtracer_test.go:98]$`,
		`^Ending span: e \[.*/loggingtracer_test.go:100] \(500ms\)$`,
		`^Ending span: a \[.*/loggingtracer_test.go:73] \(21.5s\)$`,
	}

	require.Len(t, logs, len(expectedLogPatterns))
	for i, pattern := range expectedLogPatterns {
		match, err := regexp.MatchString(pattern, logs[i])
		require.NoError(t, err)
		assert.Truef(
			t,
			match,
			"Log message does not match the expected pattern.\nActual message: %q.\nExpected pattern: %q.",
			logs[i],
			pattern)
	}
}

func a(ctx context.Context) context.Context {
	ctx, span := trace.StartSpan(ctx, "a")
	defer span.End()
	ctx = b(ctx)
	ctx = e(ctx)
	return fakeSpanDelay(ctx, span, 10*time.Second)
}

func b(ctx context.Context) context.Context {
	ctx, span := trace.StartSpan(ctx, "b")
	defer span.End()
	ctx = c(ctx)
	ctx = c(ctx)
	return fakeSpanDelay(ctx, span, 5*time.Second)
}

func c(ctx context.Context) context.Context {
	ctx, span := trace.StartSpan(ctx, "c")
	defer span.End()
	ctx = d(ctx)
	return fakeSpanDelay(ctx, span, 2*time.Second)
}

func d(ctx context.Context) context.Context {
	ctx, span := trace.StartSpan(ctx, "d")
	defer span.End()
	return fakeSpanDelay(ctx, span, time.Second)
}

func e(ctx context.Context) context.Context {
	ctx, span := trace.StartSpan(ctx, "e")
	defer span.End()
	return fakeSpanDelay(ctx, span, 500*time.Millisecond)
}

func fakeSpanDelay(ctx context.Context, span *trace.Span, duration time.Duration) context.Context {
	ctxGetterSetter := span.Internal().(spanCtxGetterSetter)
	ctx = context.WithValue(ctxGetterSetter.GetCtx(), now.ContextKey, now.Now(ctx).Add(duration))
	ctxGetterSetter.SetCtx(ctx)
	return ctx
}
