// Copyright 2024 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/v2; DO NOT EDIT.

//go:build go1.21

// This file implements conversion from old (Go 1.11–Go 1.21) traces to the Go
// 1.22 format.
//
// Most events have direct equivalents in 1.22, at worst requiring arguments to
// be reordered. Some events, such as GoWaiting need to look ahead for follow-up
// events to determine the correct translation. GoSyscall, which is an
// instantaneous event, gets turned into a 1 ns long pair of
// GoSyscallStart+GoSyscallEnd, unless we observe a GoSysBlock, in which case we
// emit a GoSyscallStart+GoSyscallEndBlocked pair with the correct duration
// (i.e. starting at the original GoSyscall).
//
// The resulting trace treats the old trace as a single, large generation,
// sharing a single evTable for all events.
//
// We use a new (compared to what was used for 'go tool trace' in earlier
// versions of Go) parser for old traces that is optimized for speed, low memory
// usage, and minimal GC pressure. It allocates events in batches so that even
// though we have to load the entire trace into memory, the conversion process
// shouldn't result in a doubling of memory usage, even if all converted events
// are kept alive, as we free batches once we're done with them.
//
// The conversion process is lossless.

package trace

import (
	"errors"
	"fmt"
	"golang.org/x/exp/trace/internal/event"
	"golang.org/x/exp/trace/internal/event/go122"
	"golang.org/x/exp/trace/internal/oldtrace"
	"io"
)

type oldTraceConverter struct {
	trace          oldtrace.Trace
	evt            *evTable
	preInit        bool
	createdPreInit map[GoID]struct{}
	events         oldtrace.Events
	extra          []Event
	extraArr       [3]Event
	tasks          map[TaskID]taskState
	seenProcs      map[ProcID]struct{}
	lastTs         Time
	procMs         map[ProcID]ThreadID
	lastStwReason  uint64

	inlineToStringID  []uint64
	builtinToStringID []uint64
}

const (
	// Block reasons
	sForever = iota
	sPreempted
	sGosched
	sSleep
	sChanSend
	sChanRecv
	sNetwork
	sSync
	sSyncCond
	sSelect
	sEmpty
	sMarkAssistWait

	// STW kinds
	sSTWUnknown
	sSTWGCMarkTermination
	sSTWGCSweepTermination
	sSTWWriteHeapDump
	sSTWGoroutineProfile
	sSTWGoroutineProfileCleanup
	sSTWAllGoroutinesStackTrace
	sSTWReadMemStats
	sSTWAllThreadsSyscall
	sSTWGOMAXPROCS
	sSTWStartTrace
	sSTWStopTrace
	sSTWCountPagesInUse
	sSTWReadMetricsSlow
	sSTWReadMemStatsSlow
	sSTWPageCachePagesLeaked
	sSTWResetDebugLog

	sLast
)

func (it *oldTraceConverter) init(pr oldtrace.Trace) error {
	it.trace = pr
	it.preInit = true
	it.createdPreInit = make(map[GoID]struct{})
	it.evt = &evTable{pcs: make(map[uint64]frame)}
	it.events = pr.Events
	it.extra = it.extraArr[:0]
	it.tasks = make(map[TaskID]taskState)
	it.seenProcs = make(map[ProcID]struct{})
	it.procMs = make(map[ProcID]ThreadID)
	it.lastTs = -1

	evt := it.evt

	// Convert from oldtracer's Strings map to our dataTable.
	var max uint64
	for id, s := range pr.Strings {
		evt.strings.insert(stringID(id), s)
		if id > max {
			max = id
		}
	}
	pr.Strings = nil

	// Add all strings used for UserLog. In the old trace format, these were
	// stored inline and didn't have IDs. We generate IDs for them.
	if max+uint64(len(pr.InlineStrings)) < max {
		return errors.New("trace contains too many strings")
	}
	var addErr error
	add := func(id stringID, s string) {
		if err := evt.strings.insert(id, s); err != nil && addErr == nil {
			addErr = err
		}
	}
	for id, s := range pr.InlineStrings {
		nid := max + 1 + uint64(id)
		it.inlineToStringID = append(it.inlineToStringID, nid)
		add(stringID(nid), s)
	}
	max += uint64(len(pr.InlineStrings))
	pr.InlineStrings = nil

	// Add strings that the converter emits explicitly.
	if max+uint64(sLast) < max {
		return errors.New("trace contains too many strings")
	}
	it.builtinToStringID = make([]uint64, sLast)
	addBuiltin := func(c int, s string) {
		nid := max + 1 + uint64(c)
		it.builtinToStringID[c] = nid
		add(stringID(nid), s)
	}
	addBuiltin(sForever, "forever")
	addBuiltin(sPreempted, "preempted")
	addBuiltin(sGosched, "runtime.Gosched")
	addBuiltin(sSleep, "sleep")
	addBuiltin(sChanSend, "chan send")
	addBuiltin(sChanRecv, "chan receive")
	addBuiltin(sNetwork, "network")
	addBuiltin(sSync, "sync")
	addBuiltin(sSyncCond, "sync.(*Cond).Wait")
	addBuiltin(sSelect, "select")
	addBuiltin(sEmpty, "")
	addBuiltin(sMarkAssistWait, "GC mark assist wait for work")
	addBuiltin(sSTWUnknown, "")
	addBuiltin(sSTWGCMarkTermination, "GC mark termination")
	addBuiltin(sSTWGCSweepTermination, "GC sweep termination")
	addBuiltin(sSTWWriteHeapDump, "write heap dump")
	addBuiltin(sSTWGoroutineProfile, "goroutine profile")
	addBuiltin(sSTWGoroutineProfileCleanup, "goroutine profile cleanup")
	addBuiltin(sSTWAllGoroutinesStackTrace, "all goroutine stack trace")
	addBuiltin(sSTWReadMemStats, "read mem stats")
	addBuiltin(sSTWAllThreadsSyscall, "AllThreadsSyscall")
	addBuiltin(sSTWGOMAXPROCS, "GOMAXPROCS")
	addBuiltin(sSTWStartTrace, "start trace")
	addBuiltin(sSTWStopTrace, "stop trace")
	addBuiltin(sSTWCountPagesInUse, "CountPagesInUse (test)")
	addBuiltin(sSTWReadMetricsSlow, "ReadMetricsSlow (test)")
	addBuiltin(sSTWReadMemStatsSlow, "ReadMemStatsSlow (test)")
	addBuiltin(sSTWPageCachePagesLeaked, "PageCachePagesLeaked (test)")
	addBuiltin(sSTWResetDebugLog, "ResetDebugLog (test)")

	if addErr != nil {
		// This should be impossible but let's be safe.
		return fmt.Errorf("couldn't add strings: %w", addErr)
	}

	it.evt.strings.compactify()

	// Convert stacks.
	for id, stk := range pr.Stacks {
		evt.stacks.insert(stackID(id), stack{pcs: stk})
	}

	// OPT(dh): if we could share the frame type between this package and
	// oldtrace we wouldn't have to copy the map.
	for pc, f := range pr.PCs {
		evt.pcs[pc] = frame{
			pc:     pc,
			funcID: stringID(f.Fn),
			fileID: stringID(f.File),
			line:   uint64(f.Line),
		}
	}
	pr.Stacks = nil
	pr.PCs = nil
	evt.stacks.compactify()
	return nil
}

// next returns the next event, io.EOF if there are no more events, or a
// descriptive error for invalid events.
func (it *oldTraceConverter) next() (Event, error) {
	if len(it.extra) > 0 {
		ev := it.extra[0]
		it.extra = it.extra[1:]

		if len(it.extra) == 0 {
			it.extra = it.extraArr[:0]
		}
		// Two events aren't allowed to fall on the same timestamp in the new API,
		// but this may happen when we produce EvGoStatus events
		if ev.base.time <= it.lastTs {
			ev.base.time = it.lastTs + 1
		}
		it.lastTs = ev.base.time
		return ev, nil
	}

	oev, ok := it.events.Pop()
	if !ok {
		return Event{}, io.EOF
	}

	ev, err := it.convertEvent(oev)

	if err == errSkip {
		return it.next()
	} else if err != nil {
		return Event{}, err
	}

	// Two events aren't allowed to fall on the same timestamp in the new API,
	// but this may happen when we produce EvGoStatus events
	if ev.base.time <= it.lastTs {
		ev.base.time = it.lastTs + 1
	}
	it.lastTs = ev.base.time
	return ev, nil
}

var errSkip = errors.New("skip event")

// convertEvent converts an event from the old trace format to zero or more
// events in the new format. Most events translate 1 to 1. Some events don't
// result in an event right away, in which case convertEvent returns errSkip.
// Some events result in more than one new event; in this case, convertEvent
// returns the first event and stores additional events in it.extra. When
// encountering events that oldtrace shouldn't be able to emit, ocnvertEvent
// returns a descriptive error.
func (it *oldTraceConverter) convertEvent(ev *oldtrace.Event) (OUT Event, ERR error) {
	var mappedType event.Type
	mappedArgs := ev.Args

	switch ev.Type {
	case oldtrace.EvGomaxprocs:
		mappedType = go122.EvProcsChange
		if it.preInit {
			// The first EvGomaxprocs signals the end of trace initialization. At this point we've seen
			// all goroutines that already existed at trace begin.
			it.preInit = false
			for gid := range it.createdPreInit {
				// These are goroutines that already existed when tracing started but for which we
				// received neither GoWaiting, GoInSyscall, or GoStart. These are goroutines that are in
				// the states _Gidle or _Grunnable.
				it.extra = append(it.extra, Event{
					ctx: schedCtx{
						// G: GoID(gid),
						G: NoGoroutine,
						P: NoProc,
						M: NoThread,
					},
					table: it.evt,
					base: baseEvent{
						typ:  go122.EvGoStatus,
						time: Time(ev.Ts),
						args: [4]uint64{uint64(gid), ^uint64(0), uint64(go122.GoRunnable)},
					},
				})
			}
			it.createdPreInit = nil
			return Event{}, errSkip
		}
	case oldtrace.EvProcStart:
		it.procMs[ProcID(ev.P)] = ThreadID(ev.Args[0])
		if _, ok := it.seenProcs[ProcID(ev.P)]; ok {
			mappedType = go122.EvProcStart
			mappedArgs = [4]uint64{uint64(ev.P)}
		} else {
			it.seenProcs[ProcID(ev.P)] = struct{}{}
			mappedType = go122.EvProcStatus
			mappedArgs = [4]uint64{uint64(ev.P), uint64(go122.ProcRunning)}
		}
	case oldtrace.EvProcStop:
		if _, ok := it.seenProcs[ProcID(ev.P)]; ok {
			mappedType = go122.EvProcStop
			mappedArgs = [4]uint64{uint64(ev.P)}
		} else {
			it.seenProcs[ProcID(ev.P)] = struct{}{}
			mappedType = go122.EvProcStatus
			mappedArgs = [4]uint64{uint64(ev.P), uint64(go122.ProcIdle)}
		}
	case oldtrace.EvGCStart:
		mappedType = go122.EvGCBegin
	case oldtrace.EvGCDone:
		mappedType = go122.EvGCEnd
	case oldtrace.EvSTWStart:
		sid := it.builtinToStringID[sSTWUnknown+it.trace.STWReason(ev.Args[0])]
		it.lastStwReason = sid
		mappedType = go122.EvSTWBegin
		mappedArgs = [4]uint64{uint64(sid)}
	case oldtrace.EvSTWDone:
		mappedType = go122.EvSTWEnd
		mappedArgs = [4]uint64{it.lastStwReason}
	case oldtrace.EvGCSweepStart:
		mappedType = go122.EvGCSweepBegin
	case oldtrace.EvGCSweepDone:
		mappedType = go122.EvGCSweepEnd
	case oldtrace.EvGoCreate:
		if it.preInit {
			it.createdPreInit[GoID(ev.Args[0])] = struct{}{}
			return Event{}, errSkip
		}
		mappedType = go122.EvGoCreate
	case oldtrace.EvGoStart:
		if it.preInit {
			mappedType = go122.EvGoStatus
			mappedArgs = [4]uint64{ev.Args[0], ^uint64(0), uint64(go122.GoRunning)}
			delete(it.createdPreInit, GoID(ev.Args[0]))
		} else {
			mappedType = go122.EvGoStart
		}
	case oldtrace.EvGoStartLabel:
		it.extra = []Event{{
			ctx: schedCtx{
				G: GoID(ev.G),
				P: ProcID(ev.P),
				M: it.procMs[ProcID(ev.P)],
			},
			table: it.evt,
			base: baseEvent{
				typ:  go122.EvGoLabel,
				time: Time(ev.Ts),
				args: [4]uint64{ev.Args[2]},
			},
		}}
		return Event{
			ctx: schedCtx{
				G: GoID(ev.G),
				P: ProcID(ev.P),
				M: it.procMs[ProcID(ev.P)],
			},
			table: it.evt,
			base: baseEvent{
				typ:  go122.EvGoStart,
				time: Time(ev.Ts),
				args: ev.Args,
			},
		}, nil
	case oldtrace.EvGoEnd:
		mappedType = go122.EvGoDestroy
	case oldtrace.EvGoStop:
		mappedType = go122.EvGoBlock
		mappedArgs = [4]uint64{uint64(it.builtinToStringID[sForever]), uint64(ev.StkID)}
	case oldtrace.EvGoSched:
		mappedType = go122.EvGoStop
		mappedArgs = [4]uint64{uint64(it.builtinToStringID[sGosched]), uint64(ev.StkID)}
	case oldtrace.EvGoPreempt:
		mappedType = go122.EvGoStop
		mappedArgs = [4]uint64{uint64(it.builtinToStringID[sPreempted]), uint64(ev.StkID)}
	case oldtrace.EvGoSleep:
		mappedType = go122.EvGoBlock
		mappedArgs = [4]uint64{uint64(it.builtinToStringID[sSleep]), uint64(ev.StkID)}
	case oldtrace.EvGoBlock:
		mappedType = go122.EvGoBlock
		mappedArgs = [4]uint64{uint64(it.builtinToStringID[sEmpty]), uint64(ev.StkID)}
	case oldtrace.EvGoUnblock:
		mappedType = go122.EvGoUnblock
	case oldtrace.EvGoBlockSend:
		mappedType = go122.EvGoBlock
		mappedArgs = [4]uint64{uint64(it.builtinToStringID[sChanSend]), uint64(ev.StkID)}
	case oldtrace.EvGoBlockRecv:
		mappedType = go122.EvGoBlock
		mappedArgs = [4]uint64{uint64(it.builtinToStringID[sChanRecv]), uint64(ev.StkID)}
	case oldtrace.EvGoBlockSelect:
		mappedType = go122.EvGoBlock
		mappedArgs = [4]uint64{uint64(it.builtinToStringID[sSelect]), uint64(ev.StkID)}
	case oldtrace.EvGoBlockSync:
		mappedType = go122.EvGoBlock
		mappedArgs = [4]uint64{uint64(it.builtinToStringID[sSync]), uint64(ev.StkID)}
	case oldtrace.EvGoBlockCond:
		mappedType = go122.EvGoBlock
		mappedArgs = [4]uint64{uint64(it.builtinToStringID[sSyncCond]), uint64(ev.StkID)}
	case oldtrace.EvGoBlockNet:
		mappedType = go122.EvGoBlock
		mappedArgs = [4]uint64{uint64(it.builtinToStringID[sNetwork]), uint64(ev.StkID)}
	case oldtrace.EvGoBlockGC:
		mappedType = go122.EvGoBlock
		mappedArgs = [4]uint64{uint64(it.builtinToStringID[sMarkAssistWait]), uint64(ev.StkID)}
	case oldtrace.EvGoSysCall:
		// Look for the next event for the same G to determine if the syscall
		// blocked.
		blocked := false
		it.events.All()(func(nev *oldtrace.Event) bool {
			if nev.G != ev.G {
				return true
			}
			// After an EvGoSysCall, the next event on the same G will either be
			// EvGoSysBlock to denote a blocking syscall, or some other event
			// (or the end of the trace) if the syscall didn't block.
			if nev.Type == oldtrace.EvGoSysBlock {
				blocked = true
			}
			return false
		})
		if blocked {
			mappedType = go122.EvGoSyscallBegin
			mappedArgs = [4]uint64{1: uint64(ev.StkID)}
		} else {
			// Convert the old instantaneous syscall event to a pair of syscall
			// begin and syscall end and give it the shortest possible duration,
			// 1ns.
			out1 := Event{
				ctx: schedCtx{
					G: GoID(ev.G),
					P: ProcID(ev.P),
					M: it.procMs[ProcID(ev.P)],
				},
				table: it.evt,
				base: baseEvent{
					typ:  go122.EvGoSyscallBegin,
					time: Time(ev.Ts),
					args: [4]uint64{1: uint64(ev.StkID)},
				},
			}

			out2 := Event{
				ctx:   out1.ctx,
				table: it.evt,
				base: baseEvent{
					typ:  go122.EvGoSyscallEnd,
					time: Time(ev.Ts + 1),
					args: [4]uint64{},
				},
			}

			it.extra = append(it.extra, out2)
			return out1, nil
		}

	case oldtrace.EvGoSysExit:
		mappedType = go122.EvGoSyscallEndBlocked
	case oldtrace.EvGoSysBlock:
		return Event{}, errSkip
	case oldtrace.EvGoWaiting:
		mappedType = go122.EvGoStatus
		mappedArgs = [4]uint64{ev.Args[0], ^uint64(0), uint64(go122.GoWaiting)}
		delete(it.createdPreInit, GoID(ev.Args[0]))
	case oldtrace.EvGoInSyscall:
		mappedType = go122.EvGoStatus
		// In the new tracer, GoStatus with GoSyscall knows what thread the
		// syscall is on. In the old tracer, EvGoInSyscall doesn't contain that
		// information and all we can do here is specify NoThread.
		mappedArgs = [4]uint64{ev.Args[0], ^uint64(0), uint64(go122.GoSyscall)}
		delete(it.createdPreInit, GoID(ev.Args[0]))
	case oldtrace.EvHeapAlloc:
		mappedType = go122.EvHeapAlloc
	case oldtrace.EvHeapGoal:
		mappedType = go122.EvHeapGoal
	case oldtrace.EvGCMarkAssistStart:
		mappedType = go122.EvGCMarkAssistBegin
	case oldtrace.EvGCMarkAssistDone:
		mappedType = go122.EvGCMarkAssistEnd
	case oldtrace.EvUserTaskCreate:
		mappedType = go122.EvUserTaskBegin
		parent := ev.Args[1]
		if parent == 0 {
			parent = uint64(NoTask)
		}
		mappedArgs = [4]uint64{ev.Args[0], parent, ev.Args[2], uint64(ev.StkID)}
		name, _ := it.evt.strings.get(stringID(ev.Args[2]))
		it.tasks[TaskID(ev.Args[0])] = taskState{name: name, parentID: TaskID(ev.Args[1])}
	case oldtrace.EvUserTaskEnd:
		mappedType = go122.EvUserTaskEnd
		// Event.Task expects the parent and name to be smuggled in extra args
		// and as extra strings.
		ts, ok := it.tasks[TaskID(ev.Args[0])]
		if ok {
			delete(it.tasks, TaskID(ev.Args[0]))
			mappedArgs = [4]uint64{
				ev.Args[0],
				ev.Args[1],
				uint64(ts.parentID),
				uint64(it.evt.addExtraString(ts.name)),
			}
		} else {
			mappedArgs = [4]uint64{ev.Args[0], ev.Args[1], uint64(NoTask), uint64(it.evt.addExtraString(""))}
		}
	case oldtrace.EvUserRegion:
		switch ev.Args[1] {
		case 0: // start
			mappedType = go122.EvUserRegionBegin
		case 1: // end
			mappedType = go122.EvUserRegionEnd
		}
		mappedArgs = [4]uint64{ev.Args[0], ev.Args[2], uint64(ev.StkID)}
	case oldtrace.EvUserLog:
		mappedType = go122.EvUserLog
		mappedArgs = [4]uint64{ev.Args[0], ev.Args[1], it.inlineToStringID[ev.Args[3]], uint64(ev.StkID)}
	case oldtrace.EvCPUSample:
		mappedType = go122.EvCPUSample
		// When emitted by the Go 1.22 tracer, CPU samples have 5 arguments:
		// timestamp, M, P, G, stack. However, after they get turned into Event,
		// they have the arguments stack, M, P, G.
		//
		// In Go 1.21, CPU samples did not have Ms.
		mappedArgs = [4]uint64{uint64(ev.StkID), ^uint64(0), uint64(ev.P), ev.G}
	default:
		return Event{}, fmt.Errorf("unexpected event type %v", ev.Type)
	}

	if oldtrace.EventDescriptions[ev.Type].Stack {
		if stackIDs := go122.Specs()[mappedType].StackIDs; len(stackIDs) > 0 {
			mappedArgs[stackIDs[0]-1] = uint64(ev.StkID)
		}
	}

	m := NoThread
	if ev.P != -1 && ev.Type != oldtrace.EvCPUSample {
		if t, ok := it.procMs[ProcID(ev.P)]; ok {
			m = ThreadID(t)
		}
	}
	if ev.Type == oldtrace.EvProcStop {
		delete(it.procMs, ProcID(ev.P))
	}
	g := GoID(ev.G)
	if g == 0 {
		g = NoGoroutine
	}
	out := Event{
		ctx: schedCtx{
			G: GoID(g),
			P: ProcID(ev.P),
			M: m,
		},
		table: it.evt,
		base: baseEvent{
			typ:  mappedType,
			time: Time(ev.Ts),
			args: mappedArgs,
		},
	}
	return out, nil
}

// convertOldFormat takes a fully loaded trace in the old trace format and
// returns an iterator over events in the new format.
func convertOldFormat(pr oldtrace.Trace) *oldTraceConverter {
	it := &oldTraceConverter{}
	it.init(pr)
	return it
}
