// Package felhomsshd manages the dedicated OOB sshd instance (TASK H1). It is a SECOND sshd —
// separate port, config, host keys, AuthorizedKeysFile, and systemd unit — that COEXISTS with the
// customer's/stock sshd on :22 (never touched). Design + safety earned by
// SPIKE-felhom-sshd-2026-07-05 (§2 claim, §3 SAFE unit, §5 reload-not-restart, §7 AuthorizedKeysFile
// isolation) and SPIKE-oob-wg-operator-peer-2026-07-05 (the tunnel-only belt).
//
// The agent RENDERS the config (Port from the claim) and reloads on change — the wg-felhom pattern.
// It NEVER declares RuntimeDirectory= (G1 [SF-1]) and NEVER restarts on a config change [SF-2].
package felhomsshd

import (
	"fmt"
	"strings"
)

const (
	// ConfDir is the dedicated config tree (host-install creates it; the agent renders the config).
	ConfDir = "/etc/felhom-sshd"
	// ConfPath is the rendered sshd config (referenced by the static unit's ExecStart/ExecReload).
	ConfPath = ConfDir + "/sshd_config"
	// HostKeyPath is the dedicated ed25519 host key (host-install generates it; stable across reloads).
	HostKeyPath = ConfDir + "/ssh_host_ed25519_key"
	// AuthKeysDir holds per-user authorized_keys OUTSIDE ~/.ssh, so the customer's sshd (which reads
	// ~/.ssh/authorized_keys) structurally cannot honour the operator key [SF-3/§7].
	AuthKeysDir = ConfDir + "/authorized_keys"
	// PortFile persists the claimed port (idempotent re-pick).
	PortFile = ConfDir + "/port"
	// PidFile is the instance pidfile (NOT a RuntimeDirectory — that is the G1 incident cause).
	PidFile = "/run/felhom-sshd.pid"
	// Unit is the systemd unit name.
	Unit = "felhom-sshd"
	// OperatorUser is the default operator login (scoped sudo; key in AuthKeysDir only).
	OperatorUser = "felhom-op"
)

// renderConfig builds the felhom-sshd config for a claimed port. Pure + deterministic (byte-stable
// for a given port → a stable conf-hash, no reload churn). The security posture is the SAFE template
// from the spike §3: key-only, dedicated host key + AuthorizedKeysFile, AllowUsers scoped to
// root+felhom-op, binds 0.0.0.0 (+ ::) so it never waits on a late interface, no RuntimeDirectory.
func renderConfig(port int) (string, error) {
	if port < 1 || port > 65535 {
		return "", fmt.Errorf("felhomsshd: port %d out of range", port)
	}
	if port == 22 {
		// The whole point is coexistence — the dedicated instance must NEVER claim :22 [SF-4/trap 5].
		return "", fmt.Errorf("felhomsshd: refusing to render on :22 (the stock/customer sshd port)")
	}
	var b strings.Builder
	b.WriteString("# felhom OOB sshd — agent-managed (H1); DO NOT EDIT\n")
	fmt.Fprintf(&b, "Port %d\n", port)
	b.WriteString("ListenAddress 0.0.0.0\n")
	b.WriteString("ListenAddress ::\n")
	fmt.Fprintf(&b, "HostKey %s\n", HostKeyPath)
	fmt.Fprintf(&b, "PidFile %s\n", PidFile)
	fmt.Fprintf(&b, "AuthorizedKeysFile %s/%%u\n", AuthKeysDir)
	b.WriteString("PasswordAuthentication no\n")
	b.WriteString("PermitRootLogin prohibit-password\n")
	b.WriteString("PubkeyAuthentication yes\n")
	b.WriteString("KbdInteractiveAuthentication no\n")
	b.WriteString("UsePAM yes\n")
	fmt.Fprintf(&b, "AllowUsers root %s\n", OperatorUser)
	b.WriteString("X11Forwarding no\n")
	b.WriteString("Subsystem sftp internal-sftp\n")
	return b.String(), nil
}
