package auth

import (
	"fmt"
	"os"
)

// PAMService is the name of the PAM service nadir authenticates against.
// It maps to /etc/pam.d/<PAMService>. We use a dedicated service rather than
// a stock one like "login" so we control exactly which modules run during
// authentication. See README.md ("PAM service") for the full rationale.
const PAMService = "nadir"

var pamServicePath = "/etc/pam.d/" + PAMService

// pamServiceContent is the minimal stack nadir needs: verify the password
// against /etc/shadow and confirm the account is valid. It deliberately omits
// pam_fprintd (blocks ~30s waiting for a fingerprint swipe that never comes),
// pam_systemd, pam_env, and the rest of the distro's login stack.
const pamServiceContent = `#%PAM-1.0
# Managed by nadir. Do not rely on hand edits surviving - nadir recreates this
# file on startup only if it is missing. Minimal auth stack: verify the
# password against /etc/shadow and confirm the account is valid. Deliberately
# omits pam_fprintd (blocks ~30s on a fingerprint swipe), pam_systemd, pam_env.
auth     required   pam_unix.so
account  required   pam_unix.so
`

// EnsurePAMService writes the PAM service file if it is missing. nadir already
// runs as root (pam_unix needs to read /etc/shadow), so it can install its own
// PAM config rather than relying on a separate install step.
//
// It will not overwrite an existing file: an admin who has customized
// /etc/pam.d/nadir keeps their version. Returns an error only on a real I/O
// problem so main can fail loudly instead of later looking like bad
// credentials (a missing file falls through to pam_deny via /etc/pam.d/other).
func EnsurePAMService() error {
	switch _, err := os.Stat(pamServicePath); {
	case err == nil:
		return nil // already present - leave admin customizations intact
	case os.IsNotExist(err):
		// fall through and create it
	default:
		return fmt.Errorf("stat %s: %w", pamServicePath, err)
	}

	if err := os.WriteFile(pamServicePath, []byte(pamServiceContent), 0644); err != nil {
		return fmt.Errorf("write %s: %w (need root, and /etc/pam.d must be writable)", pamServicePath, err)
	}
	return nil
}
