package fangs

import (
	"os"
	"reflect"
	"regexp"
	"runtime"
	"strings"
)

// Flatten takes multiple entries and creates a "flattened" list by further splitting
// comma-separated entries and removing empty entries
func Flatten(commaSeparatedEntries ...string) []string {
	var out []string
	for _, v := range commaSeparatedEntries {
		for _, s := range strings.Split(v, ",") {
			s = strings.TrimSpace(s)
			if s == "" {
				continue
			}
			out = append(out, s)
		}
	}
	return out
}

func contains(parts []string, value string) bool {
	for _, v := range parts {
		if v == value {
			return true
		}
	}
	return false
}

var envVarRegex = regexp.MustCompile("[^a-zA-Z0-9_]")

func envVar(appName string, parts ...string) string {
	v := strings.Join(parts, "_")
	if appName != "" {
		v = appName + "_" + v
	}
	v = envVarRegex.ReplaceAllString(v, "_")
	return strings.ToUpper(v)
}

func fileExists(name string) bool {
	fi, err := os.Stat(name)
	return err == nil && !fi.IsDir()
}

// isPromotedMethod returns true if the method with the given name is promoted from
// an embedded struct.
// NOTE: this is currently _not_ a completely reliable method to identify this information,
// as there is no way using standard go or reflection to identify this. the method currently
// uses some undefined behavior of the go runtime that may change or may be unreliable when
// used by structs created with reflection or if debug information is not present
func isPromotedMethod(o any, method string) bool {
	v := reflect.ValueOf(o)
	t := v.Type()
	m, ok := t.MethodByName(method)
	if !ok {
		return false
	}
	f := runtime.FuncForPC(m.Func.Pointer())
	fileName, _ := f.FileLine(f.Entry())
	return fileName == "<autogenerated>"
}
