package rosa

import (
	"slices"
	"strings"
)

var _meson = H("meson")

// MesonHelper builds and tests a meson project.
type MesonHelper struct {
	// Runs after setup.
	ScriptCompileEarly string
	// Runs after compile.
	ScriptCompiled string
	// Runs after install.
	Script string

	// Flags passed to the setup command.
	Setup []KV
	// Whether to skip meson test.
	SkipTest bool
}

var _ Helper = new(MesonHelper)

// extra returns hardcoded meson runtime dependencies.
func (*MesonHelper) extra(int) P { return P{_meson} }

// wantsChmod returns false.
func (*MesonHelper) wantsChmod() bool { return false }

// wantsWrite returns false.
func (*MesonHelper) wantsWrite() bool { return false }

// scriptEarly returns the zero value.
func (*MesonHelper) scriptEarly() string { return "" }

// wantsDir requests a new directory in TMPDIR.
func (*MesonHelper) wantsDir() (string, bool) { return `"$(mktemp -d)"`, false }

// script generates the cure script.
func (attr *MesonHelper) script(t Toolchain, name string) string {
	if attr == nil {
		attr = new(MesonHelper)
	}

	scriptCompiled := attr.ScriptCompiled
	if len(scriptCompiled) > 0 && scriptCompiled[0] != '\n' {
		scriptCompiled = "\n" + scriptCompiled
	}

	var scriptTest string
	if !attr.SkipTest && t.opts&OptSkipCheck == 0 {
		scriptTest = `
meson test \
	--print-errorlogs`
	}

	return `
cd "$(mktemp -d)"
meson setup \
	` + strings.Join(slices.Collect(func(yield func(string) bool) {
		for _, v := range append([]KV{
			{"wrap-mode", "nofallback"},
			{"prefix", "/system"},
			{"buildtype", "release"},
		}, attr.Setup...) {
			s := "-" + v[0]
			if len(v[0]) > 0 && v[0][0] != 'D' {
				s = "-" + s
			}
			if v[1] != "" {
				s += "=" + v[1]
			}
			if !yield(s) {
				return
			}
		}
	}), " \\\n\t") + ` \
	. '/usr/src/` + name + `'
meson compile` + scriptCompiled + scriptTest + `
meson install \
	--destdir=/work
` + attr.Script
}
