import { spawnSync } from "node:child_process";
import { chmodSync, existsSync, mkdirSync, readFileSync, unlinkSync, writeFileSync } from "node:fs";
import { homedir } from "node:os";
import { join } from "node:path";
const LABEL = "dev.visionclaw.agent";
const LAUNCH_AGENTS_DIR = join(homedir(), "Library", "LaunchAgents");
const PLIST_PATH = join(LAUNCH_AGENTS_DIR, `${LABEL}.plist`);
const VISIONCLAW_DIR = join(homedir(), ".visionclaw");
const WRAPPER_PATH = join(VISIONCLAW_DIR, "start.sh");
const LOG_DIR = join(VISIONCLAW_DIR, "logs");
const GREEN = "\x1b[32m";
const RED = "\x1b[31m";
const YELLOW = "\x1b[33m";
const DIM = "\x1b[2m";
const RESET = "\x1b[0m";
const BOLD = "\x1b[1m";
function ok(msg) {
    console.log(`  ${GREEN}✓${RESET} ${msg}`);
}
function fail(msg) {
    console.log(`  ${RED}✗${RESET} ${msg}`);
}
function warn(msg) {
    console.log(`  ${YELLOW}!${RESET} ${msg}`);
}
function shellQuote(value) {
    return `'${value.replace(/'/g, "'\\''")}'`;
}
function generateWrapperScript(options) {
    const args = ["daemon", "start", "--installed"];
    if (options.debug)
        args.push("--debug");
    if (options.profile && options.profile !== "default")
        args.push("--profile", options.profile);
    const renderedArgs = args.map(shellQuote).join(" ");
    return `#!/bin/bash
# VisionClaw LaunchAgent wrapper — generated by "visionclaw daemon install".
# This intentionally invokes the global visionclaw command at boot so pnpm/npm
# upgrades are picked up without rewriting the LaunchAgent plist.

export HOME="${homedir()}"
export PATH="/opt/homebrew/bin:/usr/local/bin:$HOME/.nvm/current/bin:$HOME/Library/pnpm:$HOME/Library/pnpm/bin:$PATH"

for f in "$HOME/.zprofile" "$HOME/.zshrc" "$HOME/.bash_profile" "$HOME/.bashrc" "$HOME/.profile"; do
  [ -f "$f" ] && source "$f" 2>/dev/null
done

if ! command -v visionclaw &>/dev/null; then
  echo "$(date '+%Y-%m-%d %H:%M:%S') [ERROR] visionclaw not found in PATH" >&2
  exit 1
fi

echo "$(date '+%Y-%m-%d %H:%M:%S') [INFO] Starting VisionClaw daemon"
echo "  visionclaw: $(command -v visionclaw)"
exec visionclaw ${renderedArgs}
`;
}
function generatePlist() {
    return `<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
  <key>Label</key>
  <string>${LABEL}</string>

  <key>ProgramArguments</key>
  <array>
    <string>/bin/bash</string>
    <string>${escapeXml(WRAPPER_PATH)}</string>
  </array>

  <key>RunAtLoad</key>
  <true/>

  <key>KeepAlive</key>
  <false/>

  <key>StandardOutPath</key>
  <string>${escapeXml(join(LOG_DIR, "launchd-stdout.log"))}</string>

  <key>StandardErrorPath</key>
  <string>${escapeXml(join(LOG_DIR, "launchd-stderr.log"))}</string>
</dict>
</plist>
`;
}
function escapeXml(s) {
    return s
        .replace(/&/g, "&amp;")
        .replace(/</g, "&lt;")
        .replace(/>/g, "&gt;")
        .replace(/"/g, "&quot;");
}
function guiTarget() {
    return `gui/${process.getuid?.() ?? 501}`;
}
function isLoaded() {
    const result = spawnSync("launchctl", ["list", LABEL], {
        encoding: "utf-8",
        stdio: ["pipe", "pipe", "pipe"],
    });
    return result.status === 0;
}
function bootoutIfLoadedOrInstalled() {
    if (!existsSync(PLIST_PATH) && !isLoaded())
        return;
    spawnSync("launchctl", ["bootout", guiTarget(), PLIST_PATH], { stdio: "ignore" });
}
export function installLaunchAgent(options = {}) {
    if (process.platform !== "darwin") {
        fail("Daemon installation is only supported on macOS.");
        return;
    }
    console.log(`\n${BOLD}Installing VisionClaw login LaunchAgent...${RESET}\n`);
    bootoutIfLoadedOrInstalled();
    mkdirSync(LOG_DIR, { recursive: true });
    const wrapper = generateWrapperScript(options);
    writeFileSync(WRAPPER_PATH, wrapper, "utf-8");
    chmodSync(WRAPPER_PATH, 0o755);
    ok(`Wrapper script written to ${DIM}${WRAPPER_PATH}${RESET}`);
    const plist = generatePlist();
    mkdirSync(LAUNCH_AGENTS_DIR, { recursive: true });
    writeFileSync(PLIST_PATH, plist, "utf-8");
    ok(`Plist written to ${DIM}${PLIST_PATH}${RESET}`);
    const result = spawnSync("launchctl", ["bootstrap", guiTarget(), PLIST_PATH], {
        stdio: "inherit",
    });
    if (result.status === 0) {
        ok("LaunchAgent loaded successfully");
        console.log(`\n  VisionClaw will start automatically on login.`);
        console.log(`  Logs: ${DIM}~/.visionclaw/logs/launchd-*.log${RESET}`);
        console.log(`  Manage: ${DIM}visionclaw daemon status${RESET}`);
        console.log(`          ${DIM}visionclaw daemon uninstall${RESET}\n`);
    }
    else {
        fail("Failed to load LaunchAgent via launchctl");
        console.log(`  Try manually: ${DIM}launchctl bootstrap ${guiTarget()} ${PLIST_PATH}${RESET}\n`);
    }
}
export function uninstallLaunchAgent() {
    if (process.platform !== "darwin") {
        fail("Daemon uninstallation is only supported on macOS.");
        return;
    }
    console.log(`\n${BOLD}Uninstalling VisionClaw login LaunchAgent...${RESET}\n`);
    if (isLoaded()) {
        const result = spawnSync("launchctl", ["bootout", guiTarget(), PLIST_PATH], {
            stdio: "inherit",
        });
        if (result.status === 0) {
            ok("LaunchAgent unloaded from launchd");
        }
        else {
            warn("Failed to unload LaunchAgent (may already be stopped)");
        }
    }
    else {
        ok("LaunchAgent was not loaded");
    }
    if (existsSync(PLIST_PATH)) {
        unlinkSync(PLIST_PATH);
        ok(`Plist removed: ${DIM}${PLIST_PATH}${RESET}`);
    }
    else {
        ok("Plist file did not exist");
    }
    if (existsSync(WRAPPER_PATH)) {
        unlinkSync(WRAPPER_PATH);
        ok(`Wrapper script removed: ${DIM}${WRAPPER_PATH}${RESET}`);
    }
    console.log(`\n  VisionClaw will no longer start automatically on login.\n`);
}
export function printLaunchAgentStatus() {
    if (process.platform !== "darwin") {
        fail("LaunchAgent status is only available on macOS.");
        return;
    }
    const plistExists = existsSync(PLIST_PATH);
    if (plistExists) {
        ok(`LaunchAgent plist: ${DIM}${PLIST_PATH}${RESET}`);
    }
    else {
        warn("LaunchAgent plist: not installed");
    }
    if (existsSync(WRAPPER_PATH)) {
        ok(`LaunchAgent wrapper: ${DIM}${WRAPPER_PATH}${RESET}`);
        try {
            const content = readFileSync(WRAPPER_PATH, "utf-8");
            const hasDebug = content.includes("--debug");
            const profileMatch = /--profile' '([^']+)'/.exec(content) ?? /--profile\s+(\S+)/.exec(content);
            if (profileMatch)
                console.log(`    Profile: ${profileMatch[1]}`);
            if (hasDebug)
                console.log("    Debug: enabled");
        }
        catch { /* best effort */ }
    }
    else {
        warn("LaunchAgent wrapper: missing");
    }
    if (isLoaded()) {
        ok("LaunchAgent loaded with launchd");
    }
    else if (plistExists) {
        warn("LaunchAgent plist exists but is not loaded");
    }
    const stderrPath = join(LOG_DIR, "launchd-stderr.log");
    const stdoutPath = join(LOG_DIR, "launchd-stdout.log");
    if (existsSync(stdoutPath) || existsSync(stderrPath)) {
        console.log(`    Launchd logs: ${DIM}~/.visionclaw/logs/launchd-*.log${RESET}`);
    }
}
//# sourceMappingURL=launchd.js.map