// 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

import (
	"bytes"
	"encoding/binary"
	"fmt"
	"io"

	"golang.org/x/exp/trace/internal/event"
	"golang.org/x/exp/trace/internal/event/go122"
)

// timestamp is an unprocessed timestamp.
type timestamp uint64

// batch represents a batch of trace events.
// It is unparsed except for its header.
type batch struct {
	m    ThreadID
	time timestamp
	data []byte
	exp  event.Experiment
}

func (b *batch) isStringsBatch() bool {
	return b.exp == event.NoExperiment && len(b.data) > 0 && event.Type(b.data[0]) == go122.EvStrings
}

func (b *batch) isStacksBatch() bool {
	return b.exp == event.NoExperiment && len(b.data) > 0 && event.Type(b.data[0]) == go122.EvStacks
}

func (b *batch) isCPUSamplesBatch() bool {
	return b.exp == event.NoExperiment && len(b.data) > 0 && event.Type(b.data[0]) == go122.EvCPUSamples
}

func (b *batch) isFreqBatch() bool {
	return b.exp == event.NoExperiment && len(b.data) > 0 && event.Type(b.data[0]) == go122.EvFrequency
}

// readBatch reads the next full batch from r.
func readBatch(r interface {
	io.Reader
	io.ByteReader
}) (batch, uint64, error) {
	// Read batch header byte.
	b, err := r.ReadByte()
	if err != nil {
		return batch{}, 0, err
	}
	if typ := event.Type(b); typ != go122.EvEventBatch && typ != go122.EvExperimentalBatch {
		return batch{}, 0, fmt.Errorf("expected batch event, got %s", go122.EventString(typ))
	}

	// Read the experiment of we have one.
	exp := event.NoExperiment
	if event.Type(b) == go122.EvExperimentalBatch {
		e, err := r.ReadByte()
		if err != nil {
			return batch{}, 0, err
		}
		exp = event.Experiment(e)
	}

	// Read the batch header: gen (generation), thread (M) ID, base timestamp
	// for the batch.
	gen, err := binary.ReadUvarint(r)
	if err != nil {
		return batch{}, gen, fmt.Errorf("error reading batch gen: %w", err)
	}
	m, err := binary.ReadUvarint(r)
	if err != nil {
		return batch{}, gen, fmt.Errorf("error reading batch M ID: %w", err)
	}
	ts, err := binary.ReadUvarint(r)
	if err != nil {
		return batch{}, gen, fmt.Errorf("error reading batch timestamp: %w", err)
	}

	// Read in the size of the batch to follow.
	size, err := binary.ReadUvarint(r)
	if err != nil {
		return batch{}, gen, fmt.Errorf("error reading batch size: %w", err)
	}
	if size > go122.MaxBatchSize {
		return batch{}, gen, fmt.Errorf("invalid batch size %d, maximum is %d", size, go122.MaxBatchSize)
	}

	// Copy out the batch for later processing.
	var data bytes.Buffer
	data.Grow(int(size))
	n, err := io.CopyN(&data, r, int64(size))
	if n != int64(size) {
		return batch{}, gen, fmt.Errorf("failed to read full batch: read %d but wanted %d", n, size)
	}
	if err != nil {
		return batch{}, gen, fmt.Errorf("copying batch data: %w", err)
	}

	// Return the batch.
	return batch{
		m:    ThreadID(m),
		time: timestamp(ts),
		data: data.Bytes(),
		exp:  exp,
	}, gen, nil
}
