// odb-dep-upgrade: Daily dependency maintenance for opendeviationbar-py.
//
// Compiled Swift launcher for LaunchD. Runs daily at 9am.
// Calls headless Claude Code to upgrade patch/minor deps, commit, push,
// and notify via Telegram at every decision point.
//
// Telegram notifications (via @ccc2026_bot, chat_id 90417581):
//   1. Job started (confirms LaunchD fired)
//   2. Per-package upgrade summary OR "all current"
//   3. Major bumps flagged for manual review (if any)
//   4. Job completed OR error notification
//
// Note: Heartbeat uses a DIFFERENT bot (@obdpy_bot) with its own token.
// This runner uses Claude Code's MCP Telegram plugin (@ccc2026_bot).
//
// Build:  ./build
// Plist:  ~/Library/LaunchAgents/com.terryli.odb-dep-upgrade.plist
//
// Maintenance:
//   - Source: scripts/maintenance/main.swift (tracked in git)
//   - Binary: scripts/maintenance/odb-dep-upgrade (gitignored, rebuild with ./build)
//   - Symlink: ~/.local/bin/odb-dep-upgrade → binary
//   - Plist: ~/Library/LaunchAgents/com.terryli.odb-dep-upgrade.plist
//   - Logs: /tmp/odb-dep-upgrade.log, /tmp/odb-dep-upgrade.err
//
// After editing main.swift, rebuild:
//   cd scripts/maintenance && ./build
//
// To install/reinstall the LaunchD timer:
//   launchctl unload ~/Library/LaunchAgents/com.terryli.odb-dep-upgrade.plist 2>/dev/null
//   cp scripts/maintenance/com.terryli.odb-dep-upgrade.plist ~/Library/LaunchAgents/
//   launchctl load ~/Library/LaunchAgents/com.terryli.odb-dep-upgrade.plist
//
// To test manually:
//   ~/.local/bin/odb-dep-upgrade

import Foundation

// MARK: - Configuration

let home = ProcessInfo.processInfo.environment["HOME"] ?? "/Users/terryli"
let repoDir = "\(home)/eon/opendeviationbar-py"
let telegramChatId = "90417581"  // @ccc2026_bot (Claude Code's Telegram bot)

// Claude Code search order: mise shims first, then local bin
let claudeSearchPaths = [
    "\(home)/.local/share/mise/shims/claude",
    "\(home)/.local/bin/claude",
    "/opt/homebrew/bin/claude",
    "/usr/local/bin/claude",
]

// MARK: - Helpers

func fail(_ msg: String) -> Never {
    fputs("odb-dep-upgrade: \(msg)\n", stderr)
    exit(1)
}

func log(_ msg: String) {
    let ts = ISO8601DateFormatter().string(from: Date())
    print("[\(ts)] odb-dep-upgrade: \(msg)")
}

// MARK: - Resolve claude

guard let claudePath = claudeSearchPaths.first(where: {
    FileManager.default.isExecutableFile(atPath: $0)
}) else {
    fail("claude not found in any of: \(claudeSearchPaths.joined(separator: ", "))")
}

// MARK: - Verify repo exists

guard FileManager.default.fileExists(atPath: "\(repoDir)/pyproject.toml") else {
    fail("repo not found: \(repoDir)/pyproject.toml")
}

// MARK: - Build environment

var env = ProcessInfo.processInfo.environment

env["PATH"] = [
    "\(home)/.local/share/mise/shims",
    "\(home)/.local/bin",
    "/opt/homebrew/bin",
    "/usr/local/bin",
    "/usr/bin",
    "/bin",
    "/usr/sbin",
    "/sbin",
].joined(separator: ":") + (env["PATH"].map { ":\($0)" } ?? "")

env["HOME"] = home

// MARK: - Prompt

let prompt = """
You are running as a daily dependency maintenance job for opendeviationbar-py.

CRITICAL: Send Telegram notifications at EVERY decision point using the \
mcp__plugin_telegram_telegram__reply tool with chat_id "\(telegramChatId)" (@ccc2026_bot).

Execute these steps IN ORDER:

STEP 1 — NOTIFY START:
Send Telegram: "🔧 ODB Dep Maintenance started at [current UTC time]"

STEP 2 — UPGRADE DEPENDENCIES:
cd \(repoDir)
Run: uv lock --upgrade
Run: uv sync --python 3.13

STEP 3 — CHECK FOR CHANGES:
Run: git diff --stat uv.lock
If NO changes:
  Send Telegram: "✅ ODB Deps: all packages current, no upgrades needed."
  Skip to STEP 5.

STEP 4 — COMMIT AND NOTIFY:
If changes exist:
  Run: git add uv.lock
  Run: git commit -m "chore(deps): daily dependency upgrade"
  Run: git push origin main
  Parse the uv lock output to list which packages were upgraded.
  Send Telegram with the full list:
    "📦 ODB Deps upgraded:
    - package1 X.Y.Z → X.Y.W
    - package2 ...
    Committed and pushed to main."

STEP 5 — CHECK MAJOR BUMPS:
Run: uv pip list --outdated --python .venv/bin/python3
If any packages show outdated (major version bumps not auto-upgraded):
  Send Telegram:
    "⚠️ ODB Major version bumps available (manual review needed):
    - package X.Y → Z.0
    These were NOT auto-upgraded. Review compatibility before bumping."

STEP 6 — NOTIFY COMPLETION:
Send Telegram: "✅ ODB Dep Maintenance completed."

If ANY step fails, send Telegram:
  "🔴 ODB Dep Maintenance FAILED at step N: [error message]"

Be concise. No questions. Execute all steps sequentially.
"""

// MARK: - Launch

log("starting dependency upgrade check")
log("using claude at: \(claudePath)")

let proc = Process()
proc.executableURL = URL(fileURLWithPath: claudePath)
proc.arguments = [
    "-p",
    "--dangerously-skip-permissions",
    "--add-dir", repoDir,
    prompt,
]
proc.environment = env
proc.currentDirectoryURL = URL(fileURLWithPath: repoDir)

do {
    try proc.run()
    proc.waitUntilExit()
    let status = proc.terminationStatus
    log("completed with exit code \(status)")
    exit(status)
} catch {
    fail("failed to launch claude: \(error)")
}
