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

package counter

import (
	"fmt"
	"runtime"
	"strings"
	"sync"
)

// On the disk, and upstream, stack counters look like sets of
// regular counters with names that include newlines.

// a StackCounter is the in-memory knowledge about a stack counter.
// StackCounters are more expensive to use than regular Counters,
// requiring, at a minimum, a call to runtime.Callers.
type StackCounter struct {
	name  string
	depth int
	file  *file

	mu sync.Mutex
	// as this is a detail of the implementation, it could be replaced
	// by a more efficient mechanism
	stacks []stack
}

type stack struct {
	pcs     []uintptr
	counter *Counter
}

func NewStack(name string, depth int) *StackCounter {
	return &StackCounter{name: name, depth: depth, file: &defaultFile}
}

// Inc increments a stack counter. It computes the caller's stack and
// looks up the corresponding counter. It then increments that counter,
// creating it if necessary.
func (c *StackCounter) Inc() {
	pcs := make([]uintptr, c.depth)
	n := runtime.Callers(2, pcs) // caller of Inc
	pcs = pcs[:n]

	c.mu.Lock()
	defer c.mu.Unlock()

	// Existing counter?
	var ctr *Counter
	for _, s := range c.stacks {
		if eq(s.pcs, pcs) {
			if s.counter != nil {
				ctr = s.counter
				break
			}
		}
	}

	if ctr == nil {
		// Create new counter.
		ctr = &Counter{
			name: EncodeStack(pcs, c.name),
			file: c.file,
		}
		c.stacks = append(c.stacks, stack{pcs: pcs, counter: ctr})
	}

	ctr.Inc()
}

// EncodeStack returns the name of the counter to
// use for the given stack of program counters.
// The name encodes the stack.
func EncodeStack(pcs []uintptr, prefix string) string {
	var locs []string
	lastImport := ""
	frs := runtime.CallersFrames(pcs)
	for {
		fr, more := frs.Next()
		// TODO(adonovan): this CutLast(".") operation isn't
		// appropriate for generic function symbols.
		path, fname := cutLastDot(fr.Function)
		if path == lastImport {
			path = `"` // (a ditto mark)
		} else {
			lastImport = path
		}
		var loc string
		if fr.Func != nil {
			// Use function-relative line numbering.
			// f:+2 means two lines into function f.
			// f:-1 should never happen, but be conservative.
			_, entryLine := fr.Func.FileLine(fr.Entry)
			loc = fmt.Sprintf("%s.%s:%+d", path, fname, fr.Line-entryLine)
		} else {
			// The function is non-Go code or is fully inlined:
			// use absolute line number within enclosing file.
			loc = fmt.Sprintf("%s.%s:=%d", path, fname, fr.Line)
		}
		locs = append(locs, loc)
		if !more {
			break
		}
	}

	name := prefix + "\n" + strings.Join(locs, "\n")
	if len(name) > maxNameLen {
		const bad = "\ntruncated\n"
		name = name[:maxNameLen-len(bad)] + bad
	}
	return name
}

// DecodeStack expands the (compressed) stack encoded in the counter name.
func DecodeStack(ename string) string {
	if !strings.Contains(ename, "\n") {
		return ename // not a stack counter
	}
	lines := strings.Split(ename, "\n")
	var lastPath string // empty or ends with .
	for i, line := range lines {
		path, rest := cutLastDot(line)
		if len(path) == 0 {
			continue // unchanged
		}
		if len(path) == 1 && path[0] == '"' {
			lines[i] = lastPath + rest
		} else {
			lastPath = path + "."
			// line unchanged
		}
	}
	return strings.Join(lines, "\n") // trailing \n?
}

// input is <import path>.<function name>
// output is (import path, function name)
func cutLastDot(x string) (before, after string) {
	i := strings.LastIndex(x, ".")
	if i < 0 {
		return "", x
	}
	return x[:i], x[i+1:]
}

// Names reports all the counter names associated with a StackCounter.
func (c *StackCounter) Names() []string {
	c.mu.Lock()
	defer c.mu.Unlock()
	names := make([]string, len(c.stacks))
	for i, s := range c.stacks {
		names[i] = s.counter.Name()
	}
	return names
}

// Counters returns the known Counters for a StackCounter.
// There may be more in the count file.
func (c *StackCounter) Counters() []*Counter {
	c.mu.Lock()
	defer c.mu.Unlock()
	counters := make([]*Counter, len(c.stacks))
	for i, s := range c.stacks {
		counters[i] = s.counter
	}
	return counters
}

func eq(a, b []uintptr) bool {
	if len(a) != len(b) {
		return false
	}
	for i := range a {
		if a[i] != b[i] {
			return false
		}
	}
	return true
}

// ReadStack reads the given stack counter.
// This is the implementation of
// golang.org/x/telemetry/counter/countertest.ReadStackCounter.
func ReadStack(c *StackCounter) (map[string]uint64, error) {
	ret := map[string]uint64{}
	for _, ctr := range c.Counters() {
		v, err := Read(ctr)
		if err != nil {
			return nil, err
		}
		ret[DecodeStack(ctr.Name())] = v
	}
	return ret, nil
}

// IsStackCounter reports whether the counter name is for a stack counter.
func IsStackCounter(name string) bool {
	return strings.Contains(name, "\n")
}
