package helm

import (
	"bytes"
	"encoding/base64"
	"strings"
	"text/template"

	"gopkg.in/yaml.v3"
)

var funcMap template.FuncMap

func init() {
	funcMap = template.FuncMap{
		"camelCase": camelCase,
		"toYaml":    toYaml,
		"nindent":   nindent,
		"title":     strings.Title,
		"lower":     strings.ToLower,
		"join":      strings.Join,
		"split":     split,
		"quote":     quote,
		"b64enc":    b64enc,
	}
	funcMap["include"] = include
}

func b64enc(s string) string {
	return base64.StdEncoding.EncodeToString([]byte(s))
}

func quote(s string) string {
	return `"` + s + `"`
}

func include(name string, data interface{}) (string, error) {
	buf := &bytes.Buffer{}
	err := template.Must(template.New("").Funcs(funcMap).Parse("{{define \"tmp\"}}{{template \""+name+"\" .}}{{end}}")).
		ExecuteTemplate(buf, "tmp", data)
	return buf.String(), err
}

func camelCase(s string) string {
	parts := strings.Split(s, "_")
	for i := 1; i < len(parts); i++ {
		parts[i] = strings.Title(strings.ToLower(parts[i]))
	}
	return strings.ToLower(parts[0]) + strings.Join(parts[1:], "")
}

func toYaml(v interface{}) string {
	marshaled, err := yaml.Marshal(v)
	if err != nil {
		panic(err)
	}
	return string(marshaled)
}

func nindent(n int, s string) string {
	prefix := strings.Repeat(" ", n)
	return prefix + strings.ReplaceAll(s, "\n", "\n"+prefix)
}

func split(sep, s string) []string {
	return strings.Split(s, sep)
}
