// Pure validation + path helpers for the founder-side tier-set installer flags
// (Task 240). Two flags wired into the installer at src/index.ts:
//   --tier <solo|family|pro>      personal-mode (brand.commercialMode === false)
//   --entitlement-base64 <b64>    commercial-mode (brand.commercialMode === true)
//
// Both helpers throw on invalid input; the caller exits non-zero and surfaces the
// thrown message. No filesystem or console side effects — index.ts owns those.
import { resolve } from "node:path";
const VALID_TIERS = new Set(["solo", "family", "pro"]);
export function isValidTier(value) {
    return VALID_TIERS.has(value);
}
/**
 * Validate the `--tier <enum>` argv value and the brand mode.
 *
 * Throws when:
 *   - raw is missing / starts with `--` (no value supplied after the flag)
 *   - raw is not in {solo, family, pro}
 *   - brand is commercial-mode (operator must use --entitlement-base64 instead)
 */
export function validateTierFlag(raw, commercialMode) {
    if (commercialMode) {
        throw new Error("--tier is for personal mode. Commercial mode — use --entitlement-base64 to deliver a signed payload.");
    }
    if (!raw || raw.startsWith("--")) {
        throw new Error("--tier requires a value (one of: solo, family, pro).");
    }
    if (!isValidTier(raw)) {
        throw new Error(`--tier value must be one of: solo, family, pro (got: ${raw}).`);
    }
    return raw;
}
/**
 * Validate the `--entitlement-base64 <b64>` argv value and the brand mode.
 *
 * Round-trips through Buffer to detect malformed base64 — Buffer.from is loose
 * (silently drops invalid chars), so an explicit re-encode comparison is the
 * cheapest way to confirm the input is real base64. Whitespace (newlines from
 * SSH transit, stray \r) is stripped first.
 *
 * Throws when:
 *   - brand is personal-mode (operator must use --tier instead)
 *   - raw is missing / starts with `--`
 *   - stripped base64 fails the round-trip check (malformed chars)
 *   - decoded bytes are empty
 *
 * Returns the decoded Buffer; caller writes it to entitlement.json verbatim.
 * No JSON parse, no signature validation — that's the verifier's job at session
 * start. The installer is a dumb delivery channel.
 */
export function validateEntitlementBase64(raw, commercialMode) {
    if (!commercialMode) {
        throw new Error("--entitlement-base64 is for commercial mode. Personal mode — use --tier <enum> to set tier directly.");
    }
    if (!raw || raw.startsWith("--")) {
        throw new Error("--entitlement-base64 requires a base64-encoded value.");
    }
    const stripped = raw.replace(/\s/g, "");
    if (stripped.length === 0) {
        throw new Error("--entitlement-base64 value is empty after whitespace stripping.");
    }
    const decoded = Buffer.from(stripped, "base64");
    if (decoded.toString("base64") !== stripped) {
        throw new Error("--entitlement-base64 value is not valid base64.");
    }
    if (decoded.length === 0) {
        throw new Error("--entitlement-base64 decoded to zero bytes.");
    }
    return decoded;
}
/**
 * Build the absolute path where the installer writes entitlement.json. Matches
 * the verifier's `resolve(brand.configDir, "entitlement.json")` (entitlement
 * lib src/index.ts:140) so writer + reader agree on a single location.
 */
export function entitlementPath(homeDir, configDir) {
    return resolve(homeDir, configDir, "entitlement.json");
}
/**
 * Stamp the validated tier onto an account.json config object. Pure merge;
 * preserves every other key (enabledPlugins, outputStyle, thinkingView, etc.).
 */
export function applyTierToAccountConfig(config, tier) {
    return { ...config, tier };
}
