package rosa

import (
	"slices"
	"strings"

	"hakurei.app/internal/pkg"
)

func (t Toolchain) newMeson() (pkg.Artifact, string) {
	const (
		version  = "1.11.1"
		checksum = "uvILRxdopwc6Dy17UbIeClcQr0qHqyTaqyk1M9OqWKN9PwB9N6UVAiyN8kSSz3r2"
	)
	return t.NewPackage("meson", version, newFromGitHub(
		"mesonbuild/meson",
		version,
		checksum,
	), &PackageAttr{
		Env: []string{
			"CMAKE_MAKE_PROGRAM=ninja",
		},
	}, &PipHelper{
		EnterSource: true,
		Check: `
cd 'test cases'
rm -rf \
	'common/32 has header' \
	'common/66 vcstag' \
	'common/153 wrap file should not failed' \
	'common/184 openmp' \
	'common/189 check header' \
	'linuxlike/6 subdir include order' \
	'linuxlike/9 compiler checks with dependencies' \
	'linuxlike/13 cmake dependency' \
	'frameworks/15 llvm' \
	'frameworks/29 blocks'
cd ..

python3 ./run_project_tests.py \
	-v \
	` + jobsFlagE + ` \
	--failfast \
	--backend=ninja
`,
	},
		PythonSetuptools,
		PkgConfig,
		CMake,
		Ninja,
		PythonPyTest,
	), version
}
func init() {
	artifactsM[Meson] = Metadata{
		f: Toolchain.newMeson,

		Name:        "meson",
		Description: "an open source build system",
		Website:     "https://mesonbuild.com/",

		Dependencies: P{
			Python,
			PkgConfig,
			CMake,
			Ninja,
		},

		ID: 6472,
	}
}

// MesonHelper is the [Meson] build system helper.
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 "" }

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

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

// script generates the cure script.
func (attr *MesonHelper) script(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 && presetOpts&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
}
