/**
 * interpolate.ts
 *
 * Resolves ${{ VAR }} and ${{ VAR | default }} expressions in YAML-loaded
 * configuration values. Used by the source loader to inject environment
 * variables into config/sources.yaml at parse time.
 *
 * Design choices:
 *   - ${{ }} syntax (not ${ }) to avoid collision with shell and JS templates
 *   - Required by default — missing var with no default throws immediately
 *   - Pipe | for defaults — familiar from GitHub Actions, Helm, etc.
 *   - No nested logic — this is substitution, not a template engine
 *   - Recursive on objects/arrays — env vars work at any depth
 */
// ---------------------------------------------------------------------------
// Core interpolation
// ---------------------------------------------------------------------------
/**
 * Pattern matching ${{ VAR }} and ${{ VAR | default_value }}.
 * Captures:
 *   group 1: variable name (trimmed)
 *   group 2: default value (trimmed), or undefined if no pipe
 */
const INTERP_PATTERN = /\$\{\{\s*([^}|]+?)(?:\s*\|\s*([^}]*?))?\s*\}\}/g;
/**
 * Recursively interpolate all string values in a parsed YAML structure.
 * Non-string values (numbers, booleans, null) pass through unchanged.
 */
export function interpolate(value, env = process.env) {
    if (typeof value === "string") {
        return interpolateString(value, env);
    }
    if (Array.isArray(value)) {
        return value.map((item) => interpolate(item, env));
    }
    if (value !== null && typeof value === "object") {
        const result = {};
        for (const [key, val] of Object.entries(value)) {
            result[key] = interpolate(val, env);
        }
        return result;
    }
    // Numbers, booleans, null — pass through
    return value;
}
// ---------------------------------------------------------------------------
// Recursive interpolation for parsed YAML structures
// ---------------------------------------------------------------------------
/**
 * Interpolate a single string value, replacing all ${{ VAR }} expressions
 * with values from the provided environment record.
 *
 * @throws Error if a required variable (no default) is not set
 */
export function interpolateString(value, env = process.env) {
    return value.replace(INTERP_PATTERN, (match, varName, defaultValue) => {
        const name = varName.trim();
        const resolved = env[name];
        if (resolved !== undefined && resolved !== "")
            return resolved;
        if (defaultValue !== undefined)
            return defaultValue.trim();
        throw new Error("Required environment variable " +
            name +
            " is not set and has no default. " +
            "Set it in the environment file or pass it directly. " +
            "Expression: " +
            match);
    });
}
