package main

import (
	"os"
	"os/exec"
	"path"
	"strconv"
	"sync/atomic"

	"git.gensokyo.uk/security/fortify/internal/fmsg"
)

var (
	dataHome string
)

func init() {
	// dataHome
	if p, ok := os.LookupEnv("FORTIFY_DATA_HOME"); ok {
		dataHome = p
	} else {
		dataHome = "/var/lib/fortify/" + strconv.Itoa(os.Getuid())
	}
}

func lookPath(file string) string {
	if p, err := exec.LookPath(file); err != nil {
		fmsg.Fatalf("%s: command not found", file)
		panic("unreachable")
	} else {
		return p
	}
}

var beforeRunFail = new(atomic.Pointer[func()])

func mustRun(name string, arg ...string) {
	fmsg.VPrintf("spawning process: %q %q", name, arg)
	cmd := exec.Command(name, arg...)
	cmd.Stdin, cmd.Stdout, cmd.Stderr = os.Stdin, os.Stdout, os.Stderr
	if err := cmd.Run(); err != nil {
		if f := beforeRunFail.Swap(nil); f != nil {
			(*f)()
		}
		fmsg.Fatalf("%s: %v", name, err)
		panic("unreachable")
	}
}

type appPathSet struct {
	// ${dataHome}/${id}
	baseDir string
	// ${baseDir}/app
	metaPath string
	// ${baseDir}/files
	homeDir string
	// ${baseDir}/cache
	cacheDir string
	// ${baseDir}/cache/nix
	nixPath string
}

func pathSetByApp(id string) *appPathSet {
	pathSet := new(appPathSet)
	pathSet.baseDir = path.Join(dataHome, id)
	pathSet.metaPath = path.Join(pathSet.baseDir, "app")
	pathSet.homeDir = path.Join(pathSet.baseDir, "files")
	pathSet.cacheDir = path.Join(pathSet.baseDir, "cache")
	pathSet.nixPath = path.Join(pathSet.cacheDir, "nix")
	return pathSet
}