import { existsSync, readFileSync } from "fs";
import { homedir } from "os";
import { dirname, join, resolve } from "path";
import { fileURLToPath } from "url";
// =============================================================================
// Package Detection
// =============================================================================
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
/**
 * Detect if we're running as a Bun compiled binary.
 * Bun binaries have import.meta.url containing "$bunfs", "~BUN", or "%7EBUN" (Bun's virtual filesystem path)
 */
export const isBunBinary = import.meta.url.includes("$bunfs") || import.meta.url.includes("~BUN") || import.meta.url.includes("%7EBUN");
/** Detect if Bun is the runtime (compiled binary or bun run) */
export const isBunRuntime = !!process.versions.bun;
export function detectInstallMethod() {
    if (isBunBinary) {
        return "bun-binary";
    }
    const resolvedPath = `${__dirname}\0${process.execPath || ""}`.toLowerCase();
    if (resolvedPath.includes("/pnpm/") || resolvedPath.includes("/.pnpm/") || resolvedPath.includes("\\pnpm\\")) {
        return "pnpm";
    }
    if (resolvedPath.includes("/yarn/") || resolvedPath.includes("/.yarn/") || resolvedPath.includes("\\yarn\\")) {
        return "yarn";
    }
    if (isBunRuntime) {
        return "bun";
    }
    if (resolvedPath.includes("/npm/") || resolvedPath.includes("/node_modules/") || resolvedPath.includes("\\npm\\")) {
        return "npm";
    }
    return "unknown";
}
export function getUpdateInstruction(packageName) {
    const method = detectInstallMethod();
    switch (method) {
        case "bun-binary":
            return `Download from: https://github.com/aebrer/dreb/releases/latest`;
        case "pnpm":
            return `Run: pnpm install -g ${packageName}`;
        case "yarn":
            return `Run: yarn global add ${packageName}`;
        case "bun":
            return `Run: bun install -g ${packageName}`;
        case "npm":
            return `Run: npm install -g ${packageName}`;
        default:
            return `Run: npm install -g ${packageName}`;
    }
}
// =============================================================================
// Package Asset Paths (shipped with executable)
// =============================================================================
/**
 * Get the base directory for resolving package assets (themes, package.json, README.md, CHANGELOG.md).
 * - For Bun binary: returns the directory containing the executable
 * - For Node.js (dist/): returns __dirname (the dist/ directory)
 * - For tsx (src/): returns parent directory (the package root)
 */
export function getPackageDir() {
    // Allow override via environment variable (useful for Nix/Guix where store paths tokenize poorly)
    const envDir = process.env.DREB_PACKAGE_DIR;
    if (envDir) {
        if (envDir === "~")
            return homedir();
        if (envDir.startsWith("~/"))
            return homedir() + envDir.slice(1);
        return envDir;
    }
    if (isBunBinary) {
        // Bun binary: process.execPath points to the compiled executable
        return dirname(process.execPath);
    }
    // Node.js: walk up from __dirname until we find package.json
    let dir = __dirname;
    while (dir !== dirname(dir)) {
        if (existsSync(join(dir, "package.json"))) {
            return dir;
        }
        dir = dirname(dir);
    }
    // Fallback (shouldn't happen)
    return __dirname;
}
/**
 * Get path to built-in themes directory (shipped with package)
 * - For Bun binary: theme/ next to executable
 * - For Node.js (dist/): dist/modes/interactive/theme/
 * - For tsx (src/): src/modes/interactive/theme/
 */
export function getThemesDir() {
    if (isBunBinary) {
        return join(dirname(process.execPath), "theme");
    }
    // Theme is in modes/interactive/theme/ relative to src/ or dist/
    const packageDir = getPackageDir();
    const srcOrDist = existsSync(join(packageDir, "src")) ? "src" : "dist";
    return join(packageDir, srcOrDist, "modes", "interactive", "theme");
}
/**
 * Get path to HTML export template directory (shipped with package)
 * - For Bun binary: export-html/ next to executable
 * - For Node.js (dist/): dist/core/export-html/
 * - For tsx (src/): src/core/export-html/
 */
export function getExportTemplateDir() {
    if (isBunBinary) {
        return join(dirname(process.execPath), "export-html");
    }
    const packageDir = getPackageDir();
    const srcOrDist = existsSync(join(packageDir, "src")) ? "src" : "dist";
    return join(packageDir, srcOrDist, "core", "export-html");
}
/** Get path to package.json */
export function getPackageJsonPath() {
    return join(getPackageDir(), "package.json");
}
/** Get path to README.md */
export function getReadmePath() {
    return resolve(join(getPackageDir(), "README.md"));
}
/** Get path to docs directory */
export function getDocsPath() {
    return resolve(join(getPackageDir(), "docs"));
}
/** Get path to examples directory */
export function getExamplesPath() {
    return resolve(join(getPackageDir(), "examples"));
}
/** Get path to CHANGELOG.md */
export function getChangelogPath() {
    return resolve(join(getPackageDir(), "CHANGELOG.md"));
}
// =============================================================================
// App Config (from package.json drebConfig)
// =============================================================================
const pkg = JSON.parse(readFileSync(getPackageJsonPath(), "utf-8"));
export const APP_NAME = pkg.drebConfig?.name || "dreb";
export const CONFIG_DIR_NAME = pkg.drebConfig?.configDir || ".dreb";
export const VERSION = pkg.version;
// e.g., DREB_CODING_AGENT_DIR
export const ENV_AGENT_DIR = `${APP_NAME.toUpperCase()}_CODING_AGENT_DIR`;
// =============================================================================
// User Config Paths (~/.dreb/agent/*)
// =============================================================================
/** Get the agent config directory (e.g., ~/.dreb/agent/) */
export function getAgentDir() {
    const envDir = process.env[ENV_AGENT_DIR];
    if (envDir) {
        // Expand tilde to home directory
        if (envDir === "~")
            return homedir();
        if (envDir.startsWith("~/"))
            return homedir() + envDir.slice(1);
        return envDir;
    }
    return join(homedir(), CONFIG_DIR_NAME, "agent");
}
/** Get path to user's custom themes directory */
export function getCustomThemesDir() {
    return join(getAgentDir(), "themes");
}
/** Get path to models.json */
export function getModelsPath() {
    return join(getAgentDir(), "models.json");
}
/** Get path to auth.json */
export function getAuthPath() {
    return join(getAgentDir(), "auth.json");
}
/** Get path to settings.json */
export function getSettingsPath() {
    return join(getAgentDir(), "settings.json");
}
/** Get path to tools directory */
export function getToolsDir() {
    return join(getAgentDir(), "tools");
}
/** Get path to managed binaries directory (fd, rg) */
export function getBinDir() {
    return join(getAgentDir(), "bin");
}
/** Get path to prompt templates directory */
export function getPromptsDir() {
    return join(getAgentDir(), "prompts");
}
/** Get path to sessions directory */
export function getSessionsDir() {
    return join(getAgentDir(), "sessions");
}
/** Get path to subagent sessions directory */
export function getSubagentSessionsDir() {
    return join(getAgentDir(), "subagent-sessions");
}
/** Get path to debug log file */
export function getDebugLogPath() {
    return join(getAgentDir(), `${APP_NAME}-debug.log`);
}
/** Get path to secrets directory */
export function getSecretsDir() {
    return join(homedir(), `.${APP_NAME}`, "secrets");
}
/**
 * Load providers.env from ~/.dreb/secrets/providers.env.
 * Sets env vars for API keys and provider configuration.
 * Explicit env vars take priority (won't be overwritten).
 */
export function loadProvidersEnv() {
    const envPath = join(getSecretsDir(), "providers.env");
    if (!existsSync(envPath))
        return;
    const content = readFileSync(envPath, "utf-8");
    for (const line of content.split("\n")) {
        const trimmed = line.trim();
        if (!trimmed || trimmed.startsWith("#"))
            continue;
        const eqIndex = trimmed.indexOf("=");
        if (eqIndex === -1)
            continue;
        const key = trimmed.slice(0, eqIndex).trim();
        let value = trimmed.slice(eqIndex + 1).trim();
        // Strip surrounding quotes
        if ((value.startsWith('"') && value.endsWith('"')) || (value.startsWith("'") && value.endsWith("'"))) {
            value = value.slice(1, -1);
        }
        // Don't overwrite existing env vars (explicit env takes priority)
        if (!(key in process.env)) {
            process.env[key] = value;
        }
    }
}
//# sourceMappingURL=config.js.map