import { SECRETS_FILE } from "../secrets/index.js";
export class MissingSecretError extends Error {
    secretName;
    constructor(secretName) {
        super(`Missing secret '${secretName}'\n\n` +
            `This secret is declared in specific.hcl but has no value in ${SECRETS_FILE}.\n\n` +
            `Run: specific secrets set ${secretName}`);
        this.secretName = secretName;
        this.name = "MissingSecretError";
    }
}
export function resolveEnvValue(value, databases, secrets, servicePort) {
    if (typeof value === "string") {
        return value;
    }
    switch (value.type) {
        case "port":
            if (servicePort === undefined) {
                throw new Error("Port reference used but no port allocated");
            }
            return String(servicePort);
        case "database": {
            const db = databases.get(value.name);
            if (!db) {
                throw new Error(`Database "${value.name}" not found`);
            }
            switch (value.attribute) {
                case "url":
                    return db.url;
                case "host":
                    return db.host;
                case "port":
                    return String(db.port);
                case "user":
                    return db.user;
                case "password":
                    return db.password;
                case "name":
                    return db.dbName;
                case "endpoint":
                    if (!db.endpoint) {
                        throw new Error(`Database "${value.name}" does not have an endpoint (not an object_store)`);
                    }
                    return db.endpoint;
                case "access_key":
                    if (!db.accessKey) {
                        throw new Error(`Database "${value.name}" does not have an access_key (not an object_store)`);
                    }
                    return db.accessKey;
                case "secret_key":
                    if (!db.secretKey) {
                        throw new Error(`Database "${value.name}" does not have a secret_key (not an object_store)`);
                    }
                    return db.secretKey;
                default:
                    throw new Error(`Unknown database attribute: ${value.attribute}`);
            }
        }
        case "config":
            // Config variables not supported yet
            throw new Error(`Config variables not supported in dev mode yet`);
        case "secret": {
            const secretValue = secrets.get(value.name);
            if (secretValue === undefined) {
                throw new MissingSecretError(value.name);
            }
            return secretValue;
        }
        case "build":
            // Build references shouldn't appear in env
            throw new Error(`Build references cannot be used as env values`);
        default:
            throw new Error(`Unknown reference type`);
    }
}
export function resolveEnv(env, databases, secrets, servicePort) {
    if (!env) {
        return {};
    }
    const resolved = {};
    for (const [key, value] of Object.entries(env)) {
        resolved[key] = resolveEnvValue(value, databases, secrets, servicePort);
    }
    return resolved;
}
/**
 * Resolve environment variables for exec mode.
 * Silently skips port references since there's no service port in exec context.
 */
export function resolveEnvForExec(env, databases, secrets) {
    if (!env) {
        return {};
    }
    const resolved = {};
    for (const [key, value] of Object.entries(env)) {
        if (typeof value === "string") {
            resolved[key] = value;
            continue;
        }
        // Skip port references silently
        if (value.type === "port") {
            continue;
        }
        // For other reference types, use the standard resolver (will throw on errors)
        resolved[key] = resolveEnvValue(value, databases, secrets);
    }
    return resolved;
}
//# sourceMappingURL=env-resolver.js.map