// SPDX-License-Identifier: Apache-2.0
// Copyright Authors of Cilium

package internal

import (
	"fmt"
	"os"
	"path/filepath"
	"reflect"
	"runtime"
	"strings"
)

func PrettyType(x any) string {
	return fmt.Sprintf("%T", x)
}

func FuncNameAndLocation(fn any) string {
	f := runtime.FuncForPC(reflect.ValueOf(fn).Pointer())
	file, line := f.FileLine(f.Entry())
	name := f.Name()
	name = strings.TrimSuffix(name, "-fm")
	// Truncate the path in name as it'll be repeated in file path
	if idx := strings.LastIndex(name, "/"); idx > 0 {
		name = name[idx+1:]
	}
	if file != "<autogenerated>" {
		return fmt.Sprintf("%s (%s:%d)", name, usefulPathSegment(file), line)
	}
	return name
}

// Purely a heuristic.
var commonRoots = map[string]struct{}{
	"pkg": {},
	"cmd": {},
}

func usefulPathSegment(file string) string {
	p := filepath.Clean(file)
	segs := strings.Split(p, string(os.PathSeparator))

	for i := len(segs) - 1; i > 0; i-- {
		if _, ok := commonRoots[segs[i]]; ok {
			segs = segs[i:]
			break
		}
	}

	// Truncate to at most 3 segments
	if len(segs) > 3 {
		segs = segs[len(segs)-4:]
		segs[0] = "..."
	}

	return filepath.Join(segs...)
}
