import path from "node:path";
import { isNotFound } from "@poe-code/config-mutations";
export async function resolveIsolatedEnvDetails(env, isolated, providerName, activeProvider) {
    if (!providerName) {
        throw new Error("resolveIsolatedEnvDetails requires providerName.");
    }
    const baseDir = resolveIsolatedBaseDir(env, providerName);
    const requiresConfig = isolated.requiresConfig !== false;
    if (requiresConfig && !isolated.configProbe) {
        throw new Error(`resolveIsolatedEnvDetails requires configProbe when requiresConfig is true (provider "${providerName}").`);
    }
    return {
        agentBinary: isolated.agentBinary,
        env: await resolveIsolatedEnvVars(env, baseDir, isolated.env, activeProvider),
        configProbePath: isolated.configProbe
            ? resolveIsolatedEnvPath(env, baseDir, isolated.configProbe)
            : undefined
    };
}
export async function resolveProviderRuntimeEnv(env, vars, providerName, activeProvider) {
    return resolveIsolatedEnvVars(env, resolveIsolatedBaseDir(env, providerName), vars, activeProvider);
}
export function resolveIsolatedTargetDirectory(input) {
    const expanded = expandHomeShortcut(input.env, input.targetDirectory);
    const baseDir = resolveIsolatedBaseDir(input.env, input.providerName);
    const homeDir = input.env.homeDir;
    const homeDirWithSep = `${homeDir}${path.sep}`;
    if (expanded !== homeDir && !expanded.startsWith(homeDirWithSep)) {
        throw new Error(`Isolated config targets must live under the user's home directory (received "${input.targetDirectory}").`);
    }
    if (expanded === baseDir) {
        return baseDir;
    }
    if (expanded === homeDir) {
        return baseDir;
    }
    if (!expanded.startsWith(homeDirWithSep)) {
        return expanded;
    }
    const mapped = path.join(baseDir, expanded.slice(homeDirWithSep.length));
    return stripAgentHome(mapped, baseDir, input.isolated.agentBinary);
}
function resolveIsolatedBaseDir(env, providerName) {
    return env.resolveHomePath(".poe-code", providerName);
}
async function resolveIsolatedEnvVars(env, baseDir, vars, activeProvider) {
    const out = Object.create(null);
    for (const [key, value] of Object.entries(vars)) {
        out[key] = await resolveIsolatedEnvValue(env, baseDir, value, activeProvider);
    }
    return out;
}
async function resolveIsolatedEnvValue(env, baseDir, value, activeProvider) {
    if (typeof value === "string") {
        return expandHomeShortcut(env, value);
    }
    if (isEnvVarReference(value)) {
        const resolved = env.getVariable(value.name);
        if (typeof resolved !== "string" || resolved.trim().length === 0) {
            throw new Error(`Missing required environment variable "${value.name}" for isolated wrapper.`);
        }
        return resolved;
    }
    if (isProviderCredentialReference(value)) {
        if (!activeProvider) {
            throw new Error('Cannot resolve "providerCredential": no active provider on context.');
        }
        return `${value.prefix ?? ""}${activeProvider.credential}`;
    }
    if (isProviderBaseUrlReference(value)) {
        if (!activeProvider) {
            throw new Error('Cannot resolve "providerBaseUrl": no active provider on context.');
        }
        return activeProvider.baseUrl;
    }
    if (isAgentBaseUrlReference(value)) {
        if (!activeProvider) {
            throw new Error('Cannot resolve "agentBaseUrl": no active provider on context.');
        }
        return activeProvider.agentBaseUrl;
    }
    if (value.kind === "isolatedDir" || value.kind === "isolatedFile") {
        return resolveIsolatedEnvPath(env, baseDir, value);
    }
    throw new Error("Unsupported isolated environment value.");
}
function resolveIsolatedEnvPath(env, baseDir, value) {
    switch (value.kind) {
        case "isolatedDir":
            return value.relativePath
                ? path.join(baseDir, value.relativePath)
                : baseDir;
        case "isolatedFile":
            return path.join(baseDir, value.relativePath);
    }
}
function isEnvVarReference(value) {
    return typeof value === "object" && value.kind === "envVar";
}
function isProviderCredentialReference(value) {
    return typeof value === "object" && value.kind === "providerCredential";
}
function isProviderBaseUrlReference(value) {
    return typeof value === "object" && value.kind === "providerBaseUrl";
}
function isAgentBaseUrlReference(value) {
    return typeof value === "object" && value.kind === "agentBaseUrl";
}
export async function isolatedConfigExists(fs, configProbePath) {
    try {
        await fs.stat(configProbePath);
        return true;
    }
    catch (error) {
        if (isNotFound(error)) {
            return false;
        }
        throw error;
    }
}
export async function applyIsolatedEnvRepairs(input) {
    const repairs = input.isolated.repairs ?? [];
    if (repairs.length === 0 || typeof input.fs.chmod !== "function") {
        return;
    }
    const baseDir = input.env.resolveHomePath(".poe-code", input.providerName);
    for (const repair of repairs) {
        if (repair.kind !== "chmod") {
            continue;
        }
        if (path.isAbsolute(repair.relativePath)) {
            continue;
        }
        const repairPath = path.join(baseDir, repair.relativePath);
        try {
            await input.fs.chmod(repairPath, repair.mode);
        }
        catch (error) {
            if (isNotFound(error)) {
                continue;
            }
            throw error;
        }
    }
}
export async function resolveCliSettings(cliSettings, env, activeProvider) {
    const result = { ...cliSettings.values };
    // Resolve top-level settings
    if (cliSettings.resolved) {
        for (const [key, value] of Object.entries(cliSettings.resolved)) {
            result[key] = await resolveCliSettingValue(value, env, activeProvider);
        }
    }
    // Resolve env settings (nested under settings.env)
    if (cliSettings.env) {
        const resolvedEnv = {};
        for (const [key, value] of Object.entries(cliSettings.env)) {
            if (typeof value === "string") {
                resolvedEnv[key] = value;
            }
            else {
                resolvedEnv[key] = await resolveCliSettingValue(value, env, activeProvider);
            }
        }
        result.env = resolvedEnv;
    }
    return result;
}
async function resolveCliSettingValue(value, env, activeProvider) {
    if (isProviderCredentialReference(value)) {
        if (!activeProvider) {
            throw new Error('Cannot resolve "providerCredential": no active provider on context.');
        }
        return `${value.prefix ?? ""}${activeProvider.credential}`;
    }
    if (isProviderBaseUrlReference(value)) {
        if (!activeProvider) {
            throw new Error('Cannot resolve "providerBaseUrl": no active provider on context.');
        }
        return activeProvider.baseUrl;
    }
    if (isAgentBaseUrlReference(value)) {
        if (!activeProvider) {
            throw new Error('Cannot resolve "agentBaseUrl": no active provider on context.');
        }
        return activeProvider.agentBaseUrl;
    }
    throw new Error("Unsupported CLI setting value type.");
}
function stripAgentHome(mapped, baseDir, agentBinary) {
    const agentDir = `.${agentBinary}`;
    const prefix = path.join(baseDir, agentDir);
    if (mapped === prefix) {
        return baseDir;
    }
    const withSep = `${prefix}${path.sep}`;
    if (mapped.startsWith(withSep)) {
        return path.join(baseDir, mapped.slice(withSep.length));
    }
    return mapped;
}
function expandHomeShortcut(env, input) {
    if (!input.startsWith("~")) {
        return input;
    }
    if (input === "~") {
        return env.homeDir;
    }
    if (input.startsWith("~/") || input.startsWith(`~${path.sep}`)) {
        return path.join(env.homeDir, input.slice(2));
    }
    if (input.startsWith("~./") || input.startsWith(`~.${path.sep}`)) {
        return path.join(env.homeDir, `.${input.slice(3)}`);
    }
    return input;
}
//# sourceMappingURL=isolated-env.js.map