/**
 * Native OS folder picker dialog for project path selection.
 *
 * The "New Project" form in the browser has a "Browse..." button next to
 * the typed-path autocomplete. When clicked, it sends
 * `POST /api/paths/pick-directory` to this handler, which launches a
 * native OS folder picker dialog on the user's machine and returns the
 * absolute path of the selected directory (or `null` when cancelled).
 *
 * Platform strategy (tried in order):
 *   1. macOS  — osascript (built-in, zero deps, native look)
 *   2. Linux  — zenity (GTK), kdialog (KDE), then Python tkinter
 *   3. Windows — PowerShell (COM object)
 *   4. Fallback — Python tkinter (bundled with most Python installs)
 *
 * The first available tool wins; if none work, we return an error.
 * All child processes are synchronous — the browser is waiting anyway.
 */
import { execSync } from "node:child_process";
import { platform } from "node:os";
// ---------------------------------------------------------------------------
// Platform pickers
// ---------------------------------------------------------------------------
/**
 * macOS: Use `osascript` with AppleScript to show a native folder chooser.
 * Returns the POSIX path or empty string on cancel.
 */
function pickMacOS() {
    const script = `
    set folderPath to POSIX path of (choose folder with prompt "Select project directory")
    return folderPath
  `.trim();
    try {
        const result = execSync(`osascript -e '${script.replace(/'/g, "'\\''")}'`, {
            encoding: "utf-8",
            timeout: 180_000, // 3 min — user might take time to browse
        });
        const trimmed = result.trim();
        return trimmed || null;
    }
    catch {
        // osascript exits non-zero on user cancel (error -128) — treat as silent cancel
        return null;
    }
}
/**
 * Run a command that shows a folder picker dialog. Returns `null` on user
 * cancellation, and falls through (re-throws) if the tool is not installed.
 */
function tryDialog(cmd) {
    try {
        const result = execSync(cmd, { encoding: "utf-8", timeout: 180_000 });
        return result.trim() || null;
    }
    catch (err) {
        // exit code 1 = user cancelled the dialog → stop here, return null
        // exit code 127 = command not found → re-throw so the next picker tries
        const status = err && typeof err === "object" && "status" in err
            ? err.status
            : undefined;
        if (status === 1)
            return null;
        throw err;
    }
}
/**
 * Linux: Try zenity (GTK), then kdialog (KDE), then Python tkinter.
 */
function pickLinux() {
    try {
        return tryDialog(`zenity --file-selection --directory --title="Select project directory"`);
    }
    catch {
        // zenity not available
    }
    try {
        return tryDialog(`kdialog --getexistingdirectory "${process.env.HOME ?? "/"}" --title "Select project directory"`);
    }
    catch {
        // kdialog not available
    }
    // Try Python tkinter
    return pickTkinter();
}
/**
 * Windows: Use PowerShell to invoke the COM Shell.Application folder picker.
 */
function pickWindows() {
    const script = `
    Add-Type -AssemblyName System.Windows.Forms
    $f = New-Object System.Windows.Forms.FolderBrowserDialog
    $f.Description = "Select project directory"
    $f.ShowNewFolderButton = $true
    if ($f.ShowDialog() -eq "OK") { $f.SelectedPath } else { "" }
  `.trim();
    try {
        const result = execSync(`powershell -NoProfile -Command "${script.replace(/"/g, '\\"')}"`, { encoding: "utf-8", timeout: 180_000 });
        return result.trim() || null;
    }
    catch {
        return null;
    }
}
/**
 * Python tkinter fallback — works on any OS with Python + tkinter installed.
 * tkinter is bundled with macOS Python from python.org and most Linux distros.
 */
function pickTkinter() {
    const script = `import tkinter as tk
from tkinter import filedialog
root = tk.Tk()
root.withdraw()
root.attributes('-topmost', True)
d = filedialog.askdirectory(title="Select project directory")
root.destroy()
print(d if d else "")
`.replace(/\n/g, ";").replace(/"/g, '\\"');
    try {
        const result = execSync(`python3 -c "${script}"`, {
            encoding: "utf-8",
            timeout: 180_000,
        });
        return result.trim() || null;
    }
    catch {
        // python3 not found — try 'python' (Windows)
        try {
            const result = execSync(`python -c "${script}"`, {
                encoding: "utf-8",
                timeout: 180_000,
            });
            return result.trim() || null;
        }
        catch {
            return null;
        }
    }
}
// ---------------------------------------------------------------------------
// Public handler
// ---------------------------------------------------------------------------
/**
 * Attempt to open a native folder picker dialog and return the selected path.
 *
 * Synchronous and blocking by design — the browser form is waiting for a
 * response and the user is interacting with the dialog.
 */
export function handlePickDirectory() {
    const os = platform();
    try {
        let path = null;
        if (os === "darwin") {
            path = pickMacOS();
        }
        else if (os === "linux") {
            path = pickLinux();
        }
        else if (os === "win32") {
            path = pickWindows();
        }
        else {
            // Unknown platform — try Python tkinter as universal fallback
            path = pickTkinter();
        }
        if (path === null) {
            // User cancelled or no picker available. Distinguish:
            // When no path AND no error in the platform pickers, it's a cancel.
            return { path: null };
        }
        return { path };
    }
    catch (err) {
        // The platform picker failed entirely (not cancelled — process error).
        const msg = err instanceof Error ? err.message : String(err);
        return {
            path: null,
            error: `Could not open folder picker: ${msg}`,
        };
    }
}
