// Copyright 2023 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.

// Code generated by "gen.bash" from internal/trace; DO NOT EDIT.

//go:build go1.21

package trace_test

import (
	"bytes"
	"flag"
	"fmt"
	"io"
	"os"
	"path/filepath"
	"strings"
	"testing"

	"golang.org/x/exp/trace"
	"golang.org/x/exp/trace/internal/raw"
	"golang.org/x/exp/trace/internal/testtrace"
	"golang.org/x/exp/trace/internal/version"
)

var (
	logEvents  = flag.Bool("log-events", false, "whether to log high-level events; significantly slows down tests")
	dumpTraces = flag.Bool("dump-traces", false, "dump traces even on success")
)

func TestReaderGolden(t *testing.T) {
	matches, err := filepath.Glob("./testdata/tests/*.test")
	if err != nil {
		t.Fatalf("failed to glob for tests: %v", err)
	}
	for _, testPath := range matches {
		testPath := testPath
		testName, err := filepath.Rel("./testdata", testPath)
		if err != nil {
			t.Fatalf("failed to relativize testdata path: %v", err)
		}
		t.Run(testName, func(t *testing.T) {
			tr, exp, err := testtrace.ParseFile(testPath)
			if err != nil {
				t.Fatalf("failed to parse test file at %s: %v", testPath, err)
			}
			testReader(t, tr, exp)
		})
	}
}

func FuzzReader(f *testing.F) {
	// Currently disabled because the parser doesn't do much validation and most
	// getters can be made to panic. Turn this on once the parser is meant to
	// reject invalid traces.
	const testGetters = false

	f.Fuzz(func(t *testing.T, b []byte) {
		r, err := trace.NewReader(bytes.NewReader(b))
		if err != nil {
			return
		}
		for {
			ev, err := r.ReadEvent()
			if err != nil {
				break
			}

			if !testGetters {
				continue
			}
			// Make sure getters don't do anything that panics
			switch ev.Kind() {
			case trace.EventLabel:
				ev.Label()
			case trace.EventLog:
				ev.Log()
			case trace.EventMetric:
				ev.Metric()
			case trace.EventRangeActive, trace.EventRangeBegin:
				ev.Range()
			case trace.EventRangeEnd:
				ev.Range()
				ev.RangeAttributes()
			case trace.EventStateTransition:
				ev.StateTransition()
			case trace.EventRegionBegin, trace.EventRegionEnd:
				ev.Region()
			case trace.EventTaskBegin, trace.EventTaskEnd:
				ev.Task()
			case trace.EventSync:
			case trace.EventStackSample:
			case trace.EventBad:
			}
		}
	})
}

func testReader(t *testing.T, tr io.Reader, exp *testtrace.Expectation) {
	r, err := trace.NewReader(tr)
	if err != nil {
		if err := exp.Check(err); err != nil {
			t.Error(err)
		}
		return
	}
	v := testtrace.NewValidator()
	for {
		ev, err := r.ReadEvent()
		if err == io.EOF {
			break
		}
		if err != nil {
			if err := exp.Check(err); err != nil {
				t.Error(err)
			}
			return
		}
		if *logEvents {
			t.Log(ev.String())
		}
		if err := v.Event(ev); err != nil {
			t.Error(err)
		}
	}
	if err := exp.Check(nil); err != nil {
		t.Error(err)
	}
}

func dumpTraceToText(t *testing.T, b []byte) string {
	t.Helper()

	br, err := raw.NewReader(bytes.NewReader(b))
	if err != nil {
		t.Fatalf("dumping trace: %v", err)
	}
	var sb strings.Builder
	tw, err := raw.NewTextWriter(&sb, version.Current)
	if err != nil {
		t.Fatalf("dumping trace: %v", err)
	}
	for {
		ev, err := br.ReadEvent()
		if err == io.EOF {
			break
		}
		if err != nil {
			t.Fatalf("dumping trace: %v", err)
		}
		if err := tw.WriteEvent(ev); err != nil {
			t.Fatalf("dumping trace: %v", err)
		}
	}
	return sb.String()
}

func dumpTraceToFile(t *testing.T, testName string, stress bool, b []byte) string {
	t.Helper()

	desc := "default"
	if stress {
		desc = "stress"
	}
	name := fmt.Sprintf("%s.%s.trace.", testName, desc)
	f, err := os.CreateTemp("", name)
	if err != nil {
		t.Fatalf("creating temp file: %v", err)
	}
	defer f.Close()
	if _, err := io.Copy(f, bytes.NewReader(b)); err != nil {
		t.Fatalf("writing trace dump to %q: %v", f.Name(), err)
	}
	return f.Name()
}
