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

//go:build !disable_events
// +build !disable_events

package event

import (
	"reflect"
	"runtime"
	"sort"
	"strings"
)

const (
	// this is the maximum amount of helpers we scan past to find a non helper
	helperDepthLimit = 5
)

type sources struct {
	entries []caller
}

type Source struct {
	Space string
	Owner string
	Name  string
}

type caller struct {
	helper bool
	pc     uintptr
	source Source
}

var globalCallers chan *sources

// RegisterHelper records a function as being an event helper that should not
// be used when capturing the source information on events.
// v should be either a string or a function pointer.
// If v is a string it is of the form
//
//	Space.Owner.Name
//
// where Owner and Name cannot contain '/' and Name also cannot contain '.'
func RegisterHelper(v interface{}) {
	g := <-globalCallers
	defer func() { globalCallers <- g }()
	switch v := v.(type) {
	case string:
		g.entries = append(g.entries, caller{source: splitName(v), helper: true})
	default:
		g.helperFunction(v)
	}
}

func init() {
	g := &sources{}
	// make all entries in the event package helpers
	globalCallers = make(chan *sources, 1)
	globalCallers <- g
	RegisterHelper("golang.org/x/exp/event")
}

func newCallers() sources {
	g := <-globalCallers
	defer func() { globalCallers <- g }()
	c := sources{}
	c.entries = make([]caller, len(g.entries))
	copy(c.entries, g.entries)
	return c
}

func (c *sources) addCaller(entry caller) {
	i := sort.Search(len(c.entries), func(i int) bool {
		return c.entries[i].pc >= entry.pc
	})
	if i >= len(c.entries) {
		// add to end
		c.entries = append(c.entries, entry)
		return
	}
	if c.entries[i].pc == entry.pc {
		// already present
		return
	}
	//expand the array
	c.entries = append(c.entries, caller{})
	//make a space
	copy(c.entries[i+1:], c.entries[i:])
	// insert the entry
	c.entries[i] = entry
}

func (c *sources) getCaller(pc uintptr) (caller, bool) {
	i := sort.Search(len(c.entries), func(i int) bool {
		return c.entries[i].pc >= pc
	})
	if i == len(c.entries) || c.entries[i].pc != pc {
		return caller{}, false
	}
	return c.entries[i], true
}

func scanStack() Source {
	g := <-globalCallers
	defer func() { globalCallers <- g }()
	return g.scanStack()
}

func (c *sources) scanStack() Source {
	// first capture the caller stack
	var stack [helperDepthLimit]uintptr
	// we can skip the first three entries
	//   runtime.Callers
	//   event.(*sources).scanStack (this function)
	//   another function in this package (because scanStack is private)
	depth := runtime.Callers(3, stack[:]) // start at 2 to skip Callers and this function
	// do a cheap first pass to see if we have an entry for this stack
	for i := 0; i < depth; i++ {
		pc := stack[i]
		e, found := c.getCaller(pc)
		if found {
			if !e.helper {
				// exact non helper match match found, return it
				return e.source
			}
			// helper found, keep scanning
			continue
		}
		// stack entry not found, we need to fill one in
		f := runtime.FuncForPC(stack[i])
		if f == nil {
			// symtab lookup failed, pretend it does not exist
			continue
		}
		e = caller{
			source: splitName(f.Name()),
			pc:     pc,
		}
		e.helper = c.isHelper(e)
		c.addCaller(e)
		if !e.helper {
			// found a non helper entry, add it and return it
			return e.source
		}
	}
	// ran out of stack, was all helpers
	return Source{}
}

// we do helper matching by name, if the pc matched we would have already found
// that, but helper registration does not know the call stack pcs
func (c *sources) isHelper(entry caller) bool {
	// scan to see if it matches any of the helpers
	// we match by name in case of inlining
	for _, e := range c.entries {
		if !e.helper {
			// ignore all the non helper entries
			continue
		}
		if isMatch(entry.source.Space, e.source.Space) &&
			isMatch(entry.source.Owner, e.source.Owner) &&
			isMatch(entry.source.Name, e.source.Name) {
			return true
		}
	}
	return false
}

func isMatch(value, against string) bool {
	return len(against) == 0 || value == against
}

func (c *sources) helperFunction(v interface{}) {
	r := reflect.ValueOf(v)
	pc := r.Pointer()
	f := runtime.FuncForPC(pc)
	entry := caller{
		source: splitName(f.Name()),
		pc:     f.Entry(),
		helper: true,
	}
	c.addCaller(entry)
	if entry.pc != pc {
		entry.pc = pc
		c.addCaller(entry)
	}
}

func splitName(full string) Source {
	// Function is the fully-qualified function name. The name itself may
	// have dots (for a closure, for instance), but it can't have slashes.
	// So the package path ends at the first dot after the last slash.
	entry := Source{Space: full}
	slash := strings.LastIndexByte(full, '/')
	if slash < 0 {
		slash = 0
	}
	if dot := strings.IndexByte(full[slash:], '.'); dot >= 0 {
		entry.Space = full[:slash+dot]
		entry.Name = full[slash+dot+1:]
		if dot = strings.LastIndexByte(entry.Name, '.'); dot >= 0 {
			entry.Owner = entry.Name[:dot]
			entry.Name = entry.Name[dot+1:]
		}
	}
	return entry
}
