#!/usr/bin/env swift
// ctm-hotkey — Global hotkey daemon for CTM
// Registers Cmd+Shift+S at the macOS event system level.
// When triggered, POSTs to CTM's screenshot API.
//
// Requirements: Accessibility permission (System Settings > Privacy > Accessibility)
// Install:      swift build -> launchd plist (see install-hotkey.sh)

import Cocoa
import Foundation

// --- Configuration ---
let CTM_PORT = ProcessInfo.processInfo.environment["CTM_PORT"] ?? "3456"
let CTM_URL = "http://localhost:\(CTM_PORT)/api/screenshot"

// --- Hotkey: Cmd+Shift+S ---
// CGEvent key codes: S = 1, modifiers: Cmd = .maskCommand, Shift = .maskShift
let TARGET_KEYCODE: Int64 = 1  // 'S' key
let TARGET_MODIFIERS: CGEventFlags = [.maskCommand, .maskShift]

func triggerScreenshot() {
    guard let url = URL(string: CTM_URL) else {
        print("[ctm-hotkey] Invalid URL: \(CTM_URL)")
        return
    }
    var request = URLRequest(url: url)
    request.httpMethod = "POST"
    request.timeoutInterval = 5

    // Fire and forget — don't block the event tap callback
    URLSession.shared.dataTask(with: request) { data, response, error in
        if let error = error {
            // CTM might not be running — that's fine, fail silently
            print("[ctm-hotkey] Request failed: \(error.localizedDescription)")
            return
        }
        if let http = response as? HTTPURLResponse, http.statusCode == 200 {
            print("[ctm-hotkey] Screenshot triggered")
        }
    }.resume()
}

// --- CGEvent Tap ---
// Store the tap globally so the callback can re-enable it
var globalTap: CFMachPort?

func eventTapCallback(proxy: CGEventTapProxy, type: CGEventType, event: CGEvent, refcon: UnsafeMutableRawPointer?) -> Unmanaged<CGEvent>? {
    // Re-enable tap if it gets disabled (macOS disables taps that take too long)
    if type == .tapDisabledByTimeout || type == .tapDisabledByUserInput {
        if let tap = globalTap {
            CGEvent.tapEnable(tap: tap, enable: true)
        }
        return Unmanaged.passRetained(event)
    }

    guard type == .keyDown else {
        return Unmanaged.passRetained(event)
    }

    let keyCode = event.getIntegerValueField(.keyboardEventKeycode)
    let flags = event.flags

    // Check: Cmd+Shift held, S key pressed
    // Mask out caps lock and other irrelevant modifiers
    let relevantFlags = flags.intersection([.maskCommand, .maskShift, .maskControl, .maskAlternate])
    if keyCode == TARGET_KEYCODE && relevantFlags == TARGET_MODIFIERS {
        triggerScreenshot()
        // Return nil to consume the event (prevent "Save As" in other apps)
        return nil
    }

    return Unmanaged.passRetained(event)
}

// --- Main ---
print("[ctm-hotkey] Starting global hotkey daemon (Cmd+Shift+S -> CTM Screenshot)")
print("[ctm-hotkey] CTM endpoint: \(CTM_URL)")

// Check Accessibility permission
let trusted = AXIsProcessTrustedWithOptions(
    [kAXTrustedCheckOptionPrompt.takeUnretainedValue(): true] as CFDictionary
)
if !trusted {
    print("[ctm-hotkey] WARNING: Accessibility permission not granted.")
    print("[ctm-hotkey] Go to: System Settings > Privacy & Security > Accessibility")
    print("[ctm-hotkey] Add this binary, then restart.")
    // Continue anyway — the tap will fail gracefully, and the permission dialog is shown
}

// Create event tap for keyDown events
let eventMask = (1 << CGEventType.keyDown.rawValue)

let machPort = CGEvent.tapCreate(
    tap: .cgSessionEventTap,
    place: .headInsertEventTap,
    options: .defaultTap,
    eventsOfInterest: CGEventMask(eventMask),
    callback: eventTapCallback,
    userInfo: nil
)

globalTap = machPort
guard let tap = machPort else {
    print("[ctm-hotkey] ERROR: Failed to create event tap.")
    print("[ctm-hotkey] This usually means Accessibility permission is not granted.")
    print("[ctm-hotkey] Go to: System Settings > Privacy & Security > Accessibility")
    exit(1)
}

let runLoopSource = CFMachPortCreateRunLoopSource(kCFAllocatorDefault, tap, 0)
CFRunLoopAddSource(CFRunLoopGetCurrent(), runLoopSource, .commonModes)
CGEvent.tapEnable(tap: tap, enable: true)

print("[ctm-hotkey] Global hotkey registered. Press Cmd+Shift+S anywhere to screenshot.")
print("[ctm-hotkey] Press Ctrl+C to stop.")

// Run the event loop (blocks forever)
CFRunLoopRun()
