// The earlyinit is part of the Rosa OS initramfs and serves as the system init.
//
// This program is an internal detail of Rosa OS and is not usable on its own.
// It is not covered by the compatibility promise.
package main

import (
	"log"
	"os"
	"runtime"
	"strings"
	. "syscall"
)

func main() {
	runtime.LockOSThread()
	log.SetFlags(0)
	log.SetPrefix("earlyinit: ")

	var (
		option map[string]string
		flags  []string
	)
	if len(os.Args) > 1 {
		option = make(map[string]string)
		for _, s := range os.Args[1:] {
			key, value, ok := strings.Cut(s, "=")
			if !ok {
				flags = append(flags, s)
				continue
			}
			option[key] = value
		}
	}

	if err := Mount(
		"devtmpfs",
		"/dev/",
		"devtmpfs",
		MS_NOSUID|MS_NOEXEC,
		"",
	); err != nil {
		log.Fatalf("cannot mount devtmpfs: %v", err)
	}

	// The kernel might be unable to set up the console. When that happens,
	// printk is called with "Warning: unable to open an initial console."
	// and the init runs with no files. The checkfds runtime function
	// populates 0-2 by opening /dev/null for them.
	//
	// This check replaces 1 and 2 with /dev/kmsg to improve the chance
	// of output being visible to the user.
	if fi, err := os.Stdout.Stat(); err == nil {
		if stat, ok := fi.Sys().(*Stat_t); ok {
			if stat.Rdev == 0x103 {
				var fd int
				if fd, err = Open(
					"/dev/kmsg",
					O_WRONLY|O_CLOEXEC,
					0,
				); err != nil {
					log.Fatalf("cannot open kmsg: %v", err)
				}

				if err = Dup3(fd, Stdout, 0); err != nil {
					log.Fatalf("cannot open stdout: %v", err)
				}
				if err = Dup3(fd, Stderr, 0); err != nil {
					log.Fatalf("cannot open stderr: %v", err)
				}

				if err = Close(fd); err != nil {
					log.Printf("cannot close kmsg: %v", err)
				}
			}
		}
	}

	// staying in rootfs, these are no longer used
	must(os.Remove("/root"))
	must(os.Remove("/init"))

	must(os.Mkdir("/proc", 0))
	mustSyscall("mount proc", Mount(
		"proc",
		"/proc",
		"proc",
		MS_NOSUID|MS_NOEXEC|MS_NODEV,
		"hidepid=1",
	))

	must(os.Mkdir("/sys", 0))
	mustSyscall("mount sysfs", Mount(
		"sysfs",
		"/sys",
		"sysfs",
		0,
		"",
	))

	// after top level has been set up
	mustSyscall("remount root", Mount(
		"",
		"/",
		"",
		MS_REMOUNT|MS_BIND|
			MS_RDONLY|MS_NODEV|MS_NOSUID|MS_NOEXEC,
		"",
	))

	must(os.WriteFile(
		"/sys/module/firmware_class/parameters/path",
		[]byte("/system/lib/firmware"),
		0,
	))

}

// mustSyscall calls [log.Fatalln] if err is non-nil.
func mustSyscall(action string, err error) {
	if err != nil {
		log.Fatalln("cannot "+action+":", err)
	}
}

// must calls [log.Fatal] with err if it is non-nil.
func must(err error) {
	if err != nil {
		log.Fatal(err)
	}
}
