import fs from "node:fs";
import path from "node:path";
import dotenv from "dotenv";
import { normalizeProfileName, } from "../services/permissions/permissionProfiles.js";
import { budgetFor, readInferenceEffort } from "../services/inference/inferenceSettingsService.js";
import { DEFAULT_DEEPSEEK_MODEL } from "../services/deepseek/models.js";
import { UiLanguageService } from "../services/ui/languageService.js";
export function bootstrapConfig(options) {
    const projectPath = path.resolve(options.project ?? process.cwd());
    loadEnvFiles(projectPath);
    const dataDir = path.resolve(options.dataDir ??
        process.env.DEEPSEEKCODE_HOME ??
        path.join(projectPath, ".deepseekcode"));
    const stateDir = path.join(dataDir, "state");
    fs.mkdirSync(stateDir, { recursive: true });
    const model = options.model ?? process.env.DEEPSEEK_MODEL ?? DEFAULT_DEEPSEEK_MODEL;
    const language = new UiLanguageService(projectPath).current().language;
    const permissionProfile = normalizeProfileName(options.permissionProfile ?? process.env.DEEPSEEKCODE_PERMISSION_PROFILE ?? "safe") ?? "safe";
    const grants = permissionProfileToGrants(permissionProfile);
    return {
        projectPath,
        dataDir,
        stateDbPath: path.join(stateDir, "deepseekcode.sqlite"),
        model,
        provider: resolveProviderConfig(projectPath, model),
        shellEnabled: Boolean(options.allowShell) || grants.allowShell,
        browserEnabled: Boolean(options.allowBrowser) || grants.allowBrowser,
        permissionProfile,
        language,
    };
}
function permissionProfileToGrants(profile) {
    if (profile === "open")
        return { allowShell: true, allowBrowser: true };
    if (profile === "dev")
        return { allowShell: true, allowBrowser: false };
    if (profile === "browser")
        return { allowShell: false, allowBrowser: true };
    return { allowShell: false, allowBrowser: false };
}
export function loadEnvFiles(projectPath) {
    dotenv.config({ path: path.resolve(".env"), override: false, quiet: true });
    dotenv.config({ path: path.join(projectPath, ".env"), override: false, quiet: true });
}
function resolveProviderConfig(projectPath, requested) {
    const inferenceBudget = budgetFor(readInferenceEffort(projectPath));
    const fromProfile = readProviderProfile(projectPath, requested);
    if (fromProfile)
        return { ...fromProfile, maxOutputTokens: numberEnv("DEEPSEEKCODE_MAX_OUTPUT_TOKENS", inferenceBudget.maxOutputTokens) };
    const apiKey = readEnv("DEEPSEEK_API_KEY");
    if (!apiKey)
        return null;
    return {
        name: "deepseek-default",
        kind: "open_ai_compatible",
        baseUrl: readEnv("DEEPSEEK_BASE_URL") ?? "https://api.deepseek.com",
        apiKey,
        model: requested,
        timeoutSecs: numberEnv("DEEPSEEK_TIMEOUT_SECS", 45),
        reasoningEffort: readEnv("DEEPSEEKCODE_REASONING_EFFORT") ?? "high",
        maxOutputTokens: numberEnv("DEEPSEEKCODE_MAX_OUTPUT_TOKENS", inferenceBudget.maxOutputTokens),
    };
}
function readProviderProfile(projectPath, requested) {
    const paths = [
        readEnv("DEEPSEEKCODE_PROVIDER_CONFIG"),
        path.join(projectPath, ".deepseekcode", "providers.json"),
        process.env.DEEPSEEKCODE_HOME
            ? path.join(process.env.DEEPSEEKCODE_HOME, "config", "providers.json")
            : undefined,
    ].filter((value) => Boolean(value));
    for (const profilePath of paths) {
        if (!fs.existsSync(profilePath))
            continue;
        const document = JSON.parse(fs.readFileSync(profilePath, "utf8"));
        const selected = requested === "deepseek-default"
            ? document.default_profile ?? requested
            : requested;
        const profile = document.profiles?.find((entry) => entry.name === selected);
        if (!profile)
            continue;
        const apiKey = profile.api_key ??
            (profile.api_key_env ? readEnv(profile.api_key_env) : undefined) ??
            "";
        if (!apiKey)
            continue;
        return {
            name: profile.name,
            kind: "open_ai_compatible",
            baseUrl: profile.base_url,
            apiKey,
            model: profile.model,
            timeoutSecs: Math.max(1, profile.timeout_secs ?? 45),
            reasoningEffort: profile.reasoning_effort ?? readEnv("DEEPSEEKCODE_REASONING_EFFORT") ?? "high",
            maxOutputTokens: numberEnv("DEEPSEEKCODE_MAX_OUTPUT_TOKENS", 1200),
        };
    }
    return null;
}
function readEnv(name) {
    const value = process.env[name]?.trim();
    return value ? value : undefined;
}
function numberEnv(name, fallback) {
    const value = readEnv(name);
    if (!value)
        return fallback;
    const parsed = Number(value);
    return Number.isFinite(parsed) ? parsed : fallback;
}
