// pure macOS-version classification for the installer.
//
// The installer needs two darwin facts at pre-flight: the macOS version (from
// `sw_vers`) and whether that version meets the floor required by Tasks 838
// (modern `launchctl bootstrap gui/$UID …`) and 839 (Apple-Silicon Homebrew).
// Older macOS partially succeeds, then breaks at the supervisor or brew-cellar
// layer with cryptic errors — refusing loudly at pre-flight is the contract.
//
// Pure logic with no I/O — caller spawns `sw_vers`, captures stdout, and feeds
// it through parseSwVers + isSupportedMacosVersion. Mirrors the apt-resolve.ts
// pattern: inputs in, decision out, every branch testable with
// real captured fixtures.
/**
 * Parse the stdout of macOS's `sw_vers` command. Real output has the shape:
 *
 *   ProductName: macOS
 *   ProductVersion: 14.4.1
 *   BuildVersion: 23E224
 *
 * Returns null when either ProductName or ProductVersion is absent — the
 * caller treats null as "refuse with malformed-stdout diagnostic" rather than
 * silently coercing to undefined and producing a confusing version check.
 */
export function parseSwVers(stdout) {
    const productMatch = stdout.match(/^ProductName:\s*(.+)$/m);
    const versionMatch = stdout.match(/^ProductVersion:\s*(.+)$/m);
    if (!productMatch || !versionMatch)
        return null;
    return {
        product: productMatch[1].trim(),
        version: versionMatch[1].trim(),
    };
}
/**
 * True when `version`'s major component is ≥ 14 (the floor required by Tasks
 * 838 + 839). Returns false for empty strings, non-numeric leading components,
 * and any major < 14. A numeric-only check is sufficient — Apple's published
 * macOS versions use a strict `MAJOR.MINOR[.PATCH]` integer scheme.
 */
export function isSupportedMacosVersion(version) {
    const m = version.match(/^(\d+)\./);
    if (!m) {
        // Fall back to whole-version-as-integer for the macOS 14.0 / 15 form
        // where the leading number isn't followed by a dot. Defence in depth —
        // the regex above already handles "14.0", but a bare "14" should also
        // pass.
        const bare = version.match(/^(\d+)$/);
        if (!bare)
            return false;
        return parseInt(bare[1], 10) >= 14;
    }
    return parseInt(m[1], 10) >= 14;
}
