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

package runtime

import (
	"internal/bytealg"
	_ "unsafe" // for go:linkname
)

// Frames may be used to get function/file/line information for a
// slice of PC values returned by Callers.
type Frames struct {
	// callers is a slice of PCs that have not yet been expanded to frames.
	callers []uintptr

	// The last PC we saw.
	last uintptr

	// The number of times we've seen last.
	lastCount int
}

// Frame is the information returned by Frames for each call frame.
type Frame struct {
	// PC is the program counter for the location in this frame.
	// For a frame that calls another frame, this will be the
	// program counter of a call instruction. Because of inlining,
	// multiple frames may have the same PC value, but different
	// symbolic information.
	PC uintptr

	// Func is the Func value of this call frame. This may be nil
	// for non-Go code or fully inlined functions.
	Func *Func

	// Function is the package path-qualified function name of
	// this call frame. If non-empty, this string uniquely
	// identifies a single function in the program.
	// This may be the empty string if not known.
	// If Func is not nil then Function == Func.Name().
	Function string

	// File and Line are the file name and line number of the
	// location in this frame. For non-leaf frames, this will be
	// the location of a call. These may be the empty string and
	// zero, respectively, if not known.
	File string
	Line int

	// Entry point program counter for the function; may be zero
	// if not known. If Func is not nil then Entry ==
	// Func.Entry().
	Entry uintptr
}

// CallersFrames takes a slice of PC values returned by Callers and
// prepares to return function/file/line information.
// Do not change the slice until you are done with the Frames.
func CallersFrames(callers []uintptr) *Frames {
	return &Frames{callers: callers}
}

// Next returns frame information for the next caller.
// If more is false, there are no more callers (the Frame value is valid).
func (ci *Frames) Next() (frame Frame, more bool) {
	if len(ci.callers) == 0 {
		return Frame{}, false
	}

	pc := ci.callers[0]
	ci.callers = ci.callers[1:]

	i := 0
	if pc == ci.last {
		ci.lastCount++
		i = ci.lastCount
	} else {
		ci.last = pc
		ci.lastCount = 0
	}
	more = len(ci.callers) > 0

	// Subtract 1 from PC to undo the 1 we added in callback in
	// go-callers.c.
	function, file, line, _ := funcfileline(pc-1, int32(i), more)
	if function == "" && file == "" {
		return Frame{}, more
	}

	// Demangle function name if needed.
	function = demangleSymbol(function)

	// Create entry.
	entry := funcentry(pc - 1)
	f := &Func{name: function, entry: entry}

	xpc := pc
	if xpc > entry {
		xpc--
	}

	frame = Frame{
		PC:       xpc,
		Func:     f,
		Function: function,
		File:     file,
		Line:     line,
		Entry:    entry,
	}

	return frame, more
}

//go:noescape
// pcInlineCallers is written in C.
func pcInlineCallers(pc uintptr, locbuf *location, max int32) int32

// runtime_expandFinalInlineFrame expands the final pc in stk to include all
// "callers" if pc is inline.
//
//go:linkname runtime_expandFinalInlineFrame runtime_1pprof.runtime__expandFinalInlineFrame
func runtime_expandFinalInlineFrame(stk []uintptr) []uintptr {
	if len(stk) == 0 {
		return stk
	}
	pc := stk[len(stk)-1]
	tracepc := pc - 1

	var locbuf [_TracebackMaxFrames]location
	n := pcInlineCallers(tracepc, &locbuf[0], int32(len(locbuf)))

	// Returning the same PC several times causes Frame.Next to do
	// the right thing.
	for i := int32(1); i < n; i++ {
		stk = append(stk, pc)
	}

	return stk
}

// NOTE: Func does not expose the actual unexported fields, because we return *Func
// values to users, and we want to keep them from being able to overwrite the data
// with (say) *f = Func{}.
// All code operating on a *Func must call raw() to get the *_func
// or funcInfo() to get the funcInfo instead.

// A Func represents a Go function in the running binary.
type Func struct {
	name  string
	entry uintptr
}

// FuncForPC returns a *Func describing the function that contains the
// given program counter address, or else nil.
//
// If pc represents multiple functions because of inlining, it returns
// the *Func describing the innermost function, but with an entry of
// the outermost function.
func FuncForPC(pc uintptr) *Func {
	name, _, _, _ := funcfileline(pc, -1, false)
	if name == "" {
		return nil
	}
	entry := funcentry(pc)
	return &Func{name: name, entry: entry}
}

// Name returns the name of the function.
func (f *Func) Name() string {
	if f == nil {
		return ""
	}
	return f.name
}

// Entry returns the entry address of the function.
func (f *Func) Entry() uintptr {
	if f == nil {
		return 0
	}
	return f.entry
}

// FileLine returns the file name and line number of the
// source code corresponding to the program counter pc.
// The result will not be accurate if pc is not a program
// counter within f.
func (f *Func) FileLine(pc uintptr) (file string, line int) {
	_, file, line, _ = funcfileline(pc, -1, false)
	return file, line
}

func hexval(b byte) uint {
	if b >= '0' && b <= '9' {
		return uint(b - '0')
	}
	if b >= 'a' && b <= 'f' {
		return uint(b-'a') + 10
	}
	return 0
}

func hexDigitsToRune(digits []byte, ndig int) rune {
	result := uint(0)
	for i := 0; i < ndig; i++ {
		result <<= uint(4)
		result |= hexval(digits[i])
	}
	return rune(result)
}

// decodeIdentifier performs an in-place decoding on the input byte slice.
// This undoes the compiler underscore mangling.
// Returns the number of bytes used by the result.
func decodeIdentifier(bsl []byte) int {
	underscoreCodes := map[byte]byte{
		'_': '_',
		'0': '.',
		'1': '/',
		'2': '*',
		'3': ',',
		'4': '{',
		'5': '}',
		'6': '[',
		'7': ']',
		'8': '(',
		'9': ')',
		'a': '"',
		'b': ' ',
		'c': ';',
	}

	j := 0
	for i := 0; i < len(bsl); i++ {
		b := bsl[i]
		if b != '_' || i+1 >= len(bsl) {
			bsl[j] = b
			j++
			continue
		}

		if d, ok := underscoreCodes[bsl[i+1]]; ok {
			i++
			bsl[j] = d
			j++
			continue
		}

		rlen := 0
		switch bsl[i+1] {
		case 'x':
			rlen = 2
		case 'u':
			rlen = 4
		case 'U':
			rlen = 8
		}

		if rlen > 0 && i+1+rlen < len(bsl) {
			r := hexDigitsToRune(bsl[i+2:], rlen)
			nc := encoderune(bsl[j:], r)
			j += nc
			i += rlen + 1
		} else {
			bsl[j] = b
			j++
		}
	}
	return j
}

// Demangle a function symbol. Applies the reverse of go_encode_id()
// as used in the compiler.

func demangleSymbol(s string) string {
	if bytealg.IndexByteString(s, '.') < 0 {
		// A symbol with no '.' is not a Go symbol.
		return s
	}

	bsl := []byte(s)
	nchars := decodeIdentifier(bsl)
	bsl = bsl[:nchars]
	return string(bsl)
}

// implemented in go-caller.c
func funcfileline(uintptr, int32, bool) (string, string, int, int)
func funcentry(uintptr) uintptr
