/**
 * kubectl-context.ts — shared kubectl-context resolver.
 *
 * Single source of truth for the D1 / SEC-NEW-003 context-resolution
 * policy. Extracted so `upgrade-kubernetes.ts`, `auth-refresh-kubernetes.ts`,
 * `services.ts`, and any future kubernetes-substrate consumer can call the
 * same helper instead of duplicating it.
 *
 * Policy (matches the pre-existing auth-refresh-kubernetes.ts and services.ts
 * behaviour — see also docs/architecture/peripheral-services-on-k3s.md):
 *
 *   1. `host.kubectl_context_pinned` in `~/.olam/config.json` (preferred,
 *      persistent — the doc-recommended way).
 *   2. `OLAM_K8S_CONTEXT_ACK` env var (deprecated fallback; emits a
 *      deprecation warning to nudge operators toward (1)).
 *   3. Both absent → error result with actionable remediation.
 *
 * No `fs` reads in this module beyond what `readConfig` does; no kubectl
 * invocations. Pure resolution. Safe to call from any layer.
 */
import { readConfig, writeConfig } from './config.js';
import { defaultGetContexts, isOlamManagedContext } from './k8s-context-discovery.js';
const DEPRECATION_WARNING = 'OLAM_K8S_CONTEXT_ACK is deprecated; set host.kubectl_context_pinned in ~/.olam/config.json';
const NO_CONTEXT_ERROR = 'kubectl_context_pinned is not set in ~/.olam/config.json and OLAM_K8S_CONTEXT_ACK is not set.\n' +
    '  Set it with: olam config set host.kubectl_context_pinned <your-kubectl-context>\n' +
    '  List candidates with: kubectl config get-contexts -o name';
/**
 * Canonical kubectl context provisioned by `olam setup` / `olam up` — the
 * k3d cluster named by `DEFAULT_K3S_CLUSTER` (`olam-host`) surfaces as the
 * context `k3d-olam-host`. Defined locally (rather than imported from
 * bootstrap-kubernetes.ts) to avoid a module cycle; kept in sync via this
 * comment. When present among the operator's contexts, auto-pin prefers it.
 */
export const CANONICAL_K3S_CONTEXT = 'k3d-olam-host';
/**
 * Resolve the operator's kubectl context name. See module docstring for policy.
 *
 * `configPath` lets callers (and tests) point at a non-default config file.
 * Returns a `KubectlContextResolution` — callers branch on `error` vs `context`.
 */
export function resolveKubectlContext(configPath) {
    const cfg = readConfig({ configPath });
    const raw = cfg.host['kubectl_context_pinned'];
    if (typeof raw === 'string' && raw.length > 0) {
        return { context: raw };
    }
    const ack = process.env['OLAM_K8S_CONTEXT_ACK'];
    if (typeof ack === 'string' && ack.length > 0) {
        return { context: ack, deprecationWarning: DEPRECATION_WARNING };
    }
    return { error: NO_CONTEXT_ERROR };
}
function buildNoAutoPinError(olamContexts) {
    if (olamContexts.length === 0) {
        return ('No kubectl context is pinned and none could be auto-detected.\n' +
            '  No k3d-olam-* context exists yet — provision one with: olam setup\n' +
            '  Or pin an existing context manually:\n' +
            '    olam config set host.kubectl_context_pinned <your-kubectl-context>\n' +
            '  (list candidates with: kubectl config get-contexts -o name)');
    }
    return ('No kubectl context is pinned and auto-pin is ambiguous.\n' +
        `  Found ${olamContexts.length} olam-managed contexts: ${olamContexts.join(', ')}\n` +
        '  Pick one explicitly:\n' +
        `    olam config set host.kubectl_context_pinned ${olamContexts[0]}`);
}
/**
 * Resolve the kubectl context, auto-pinning when it can be done unambiguously.
 *
 * Unlike the pure `resolveKubectlContext`, this helper is allowed to (a) shell
 * out to `kubectl` to enumerate contexts and (b) persist a pin to
 * `~/.olam/config.json`. It exists so the onboarding flow (`olam upgrade`)
 * helps the operator resolve a missing pin instead of dead-ending.
 *
 * Policy:
 *   - Already pinned / `OLAM_K8S_CONTEXT_ACK` set → return it, write nothing.
 *   - Exactly the canonical `k3d-olam-host` present → pin it.
 *   - Exactly one `k3d-olam-*` context present → pin it.
 *   - Zero or multiple non-canonical `k3d-olam-*` → return an actionable error
 *     listing the candidates and the exact `olam config set` command.
 */
export function autoPinKubectlContext(deps = {}) {
    const existing = resolveKubectlContext(deps.configPath);
    if (existing.context !== undefined) {
        return { context: existing.context };
    }
    const getContexts = deps.getContexts ?? defaultGetContexts;
    const writeConfigFn = deps.writeConfigFn ?? writeConfig;
    const olamContexts = getContexts().filter(isOlamManagedContext);
    let chosen;
    if (olamContexts.includes(CANONICAL_K3S_CONTEXT)) {
        chosen = CANONICAL_K3S_CONTEXT;
    }
    else if (olamContexts.length === 1) {
        chosen = olamContexts[0];
    }
    if (chosen === undefined) {
        return { error: buildNoAutoPinError(olamContexts) };
    }
    writeConfigFn({ host: { kubectl_context_pinned: chosen } }, { configPath: deps.configPath });
    return {
        context: chosen,
        autoPinnedMessage: `auto-pinned kubectl context "${chosen}" → ~/.olam/config.json (host.kubectl_context_pinned)`,
    };
}
//# sourceMappingURL=kubectl-context.js.map