/**
 * Generic environment loading from Zod schemas.
 *
 * Provides `load_env` which iterates Zod schema keys, gets env values, and validates.
 * Apps handle error messages themselves (they're always app-specific).
 *
 * @module
 */
import { z } from 'zod';
/**
 * Error thrown when environment validation fails.
 *
 * Contains structured information for apps to format their own error messages.
 */
export class EnvValidationError extends Error {
    /** The raw env values that were read. */
    raw;
    /** The Zod validation error. */
    zod_error;
    /** True if every env var was undefined (nothing loaded). */
    all_undefined;
    constructor(raw, zod_error) {
        super('Environment validation failed');
        this.raw = raw;
        this.zod_error = zod_error;
        this.all_undefined = Object.values(raw).every((v) => v === undefined);
    }
    /**
     * Format Zod validation issues as human-readable strings.
     *
     * @returns array of formatted issue strings like `"PORT: Expected number"`
     */
    format_issues() {
        return this.zod_error.issues.map((issue) => `${issue.path.join('.')}: ${issue.message}`);
    }
}
/**
 * Log formatted env validation issues to stderr.
 *
 * Handles the common case: labels each Zod issue with an optional prefix.
 * Callers who want app-specific "getting started" instructions should check
 * `error.all_undefined` before calling this.
 *
 * @param error - the env validation error
 * @param label - optional prefix for log lines (e.g., 'zap daemon', 'env')
 */
export const log_env_validation_error = (error, label) => {
    const prefix = label ? `[${label}] ` : '';
    if (error.all_undefined) {
        console.error(`${prefix}No environment configured.`);
    }
    else {
        console.error(`${prefix}Invalid environment configuration:`);
        for (const line of error.format_issues()) {
            console.error(`${prefix}  ${line}`);
        }
    }
};
/**
 * Load and validate env vars against a Zod schema.
 *
 * @param schema - Zod object schema defining expected env vars
 * @param get_env - function to read an env var by key
 * @returns validated env object
 * @throws EnvValidationError if Zod validation fails
 */
export const load_env = (schema, get_env) => {
    const raw = {};
    for (const key of Object.keys(schema.shape)) {
        raw[key] = get_env(key);
    }
    const result = schema.safeParse(raw);
    if (!result.success) {
        throw new EnvValidationError(raw, result.error);
    }
    return result.data;
};
