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

//go:build go1.21

package raw

import (
	"bufio"
	"fmt"
	"io"
	"strconv"
	"strings"
	"unicode"

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

// TextReader parses a text format trace with only very basic validation
// into an event stream.
type TextReader struct {
	v     version.Version
	specs []event.Spec
	names map[string]event.Type
	s     *bufio.Scanner
}

// NewTextReader creates a new reader for the trace text format.
func NewTextReader(r io.Reader) (*TextReader, error) {
	tr := &TextReader{s: bufio.NewScanner(r)}
	line, err := tr.nextLine()
	if err != nil {
		return nil, err
	}
	trace, line := readToken(line)
	if trace != "Trace" {
		return nil, fmt.Errorf("failed to parse header")
	}
	gover, line := readToken(line)
	if !strings.HasPrefix(gover, "Go1.") {
		return nil, fmt.Errorf("failed to parse header Go version")
	}
	rawv, err := strconv.ParseUint(gover[len("Go1."):], 10, 64)
	if err != nil {
		return nil, fmt.Errorf("failed to parse header Go version: %v", err)
	}
	v := version.Version(rawv)
	if !v.Valid() {
		return nil, fmt.Errorf("unknown or unsupported Go version 1.%d", v)
	}
	tr.v = v
	tr.specs = v.Specs()
	tr.names = event.Names(tr.specs)
	for _, r := range line {
		if !unicode.IsSpace(r) {
			return nil, fmt.Errorf("encountered unexpected non-space at the end of the header: %q", line)
		}
	}
	return tr, nil
}

// Version returns the version of the trace that we're reading.
func (r *TextReader) Version() version.Version {
	return r.v
}

// ReadEvent reads and returns the next trace event in the text stream.
func (r *TextReader) ReadEvent() (Event, error) {
	line, err := r.nextLine()
	if err != nil {
		return Event{}, err
	}
	evStr, line := readToken(line)
	ev, ok := r.names[evStr]
	if !ok {
		return Event{}, fmt.Errorf("unidentified event: %s", evStr)
	}
	spec := r.specs[ev]
	args, err := readArgs(line, spec.Args)
	if err != nil {
		return Event{}, fmt.Errorf("reading args for %s: %v", evStr, err)
	}
	if spec.IsStack {
		len := int(args[1])
		for i := 0; i < len; i++ {
			line, err := r.nextLine()
			if err == io.EOF {
				return Event{}, fmt.Errorf("unexpected EOF while reading stack: args=%v", args)
			}
			if err != nil {
				return Event{}, err
			}
			frame, err := readArgs(line, frameFields)
			if err != nil {
				return Event{}, err
			}
			args = append(args, frame...)
		}
	}
	var data []byte
	if spec.HasData {
		line, err := r.nextLine()
		if err == io.EOF {
			return Event{}, fmt.Errorf("unexpected EOF while reading data for %s: args=%v", evStr, args)
		}
		if err != nil {
			return Event{}, err
		}
		data, err = readData(line)
		if err != nil {
			return Event{}, err
		}
	}
	return Event{
		Version: r.v,
		Ev:      ev,
		Args:    args,
		Data:    data,
	}, nil
}

func (r *TextReader) nextLine() (string, error) {
	for {
		if !r.s.Scan() {
			if err := r.s.Err(); err != nil {
				return "", err
			}
			return "", io.EOF
		}
		txt := r.s.Text()
		tok, _ := readToken(txt)
		if tok == "" {
			continue // Empty line or comment.
		}
		return txt, nil
	}
}

var frameFields = []string{"pc", "func", "file", "line"}

func readArgs(s string, names []string) ([]uint64, error) {
	var args []uint64
	for _, name := range names {
		arg, value, rest, err := readArg(s)
		if err != nil {
			return nil, err
		}
		if arg != name {
			return nil, fmt.Errorf("expected argument %q, but got %q", name, arg)
		}
		args = append(args, value)
		s = rest
	}
	for _, r := range s {
		if !unicode.IsSpace(r) {
			return nil, fmt.Errorf("encountered unexpected non-space at the end of an event: %q", s)
		}
	}
	return args, nil
}

func readArg(s string) (arg string, value uint64, rest string, err error) {
	var tok string
	tok, rest = readToken(s)
	if len(tok) == 0 {
		return "", 0, s, fmt.Errorf("no argument")
	}
	parts := strings.SplitN(tok, "=", 2)
	if len(parts) < 2 {
		return "", 0, s, fmt.Errorf("malformed argument: %q", tok)
	}
	arg = parts[0]
	value, err = strconv.ParseUint(parts[1], 10, 64)
	if err != nil {
		return arg, value, s, fmt.Errorf("failed to parse argument value %q for arg %q", parts[1], parts[0])
	}
	return
}

func readToken(s string) (token, rest string) {
	tkStart := -1
	for i, r := range s {
		if r == '#' {
			return "", ""
		}
		if !unicode.IsSpace(r) {
			tkStart = i
			break
		}
	}
	if tkStart < 0 {
		return "", ""
	}
	tkEnd := -1
	for i, r := range s[tkStart:] {
		if unicode.IsSpace(r) || r == '#' {
			tkEnd = i + tkStart
			break
		}
	}
	if tkEnd < 0 {
		return s[tkStart:], ""
	}
	return s[tkStart:tkEnd], s[tkEnd:]
}

func readData(line string) ([]byte, error) {
	parts := strings.SplitN(line, "=", 2)
	if len(parts) < 2 || strings.TrimSpace(parts[0]) != "data" {
		return nil, fmt.Errorf("malformed data: %q", line)
	}
	data, err := strconv.Unquote(strings.TrimSpace(parts[1]))
	if err != nil {
		return nil, fmt.Errorf("failed to parse data: %q: %v", line, err)
	}
	return []byte(data), nil
}
