#!/usr/bin/env bash
# ssr-schedule — manage the launchd scheduled sync job.

set -euo pipefail
SSR_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
# shellcheck source=../lib/common.sh
source "$SSR_ROOT/lib/common.sh"

ssr::require_macos
ssr::load_config

LABEL="${SSR_LAUNCHD_LABEL:-de.surke.ssr.sync}"
PLIST_SRC="$SSR_ROOT/launchd/${LABEL}.plist"
PLIST_DST="$HOME/Library/LaunchAgents/${LABEL}.plist"
LOG_DIR="${SSR_LOG_DIR:-$HOME/.local/state/ssr/logs}"
INTERVAL_HOUR="${SSR_SCHEDULE_HOUR:-9}"
INTERVAL_MIN="${SSR_SCHEDULE_MINUTE:-0}"
SSR_BIN="$SSR_ROOT/bin/ssr"

# Modern launchd target. `launchctl load -w` has been deprecated since 10.11
# and is a silent no-op on recent macOS — use bootstrap/bootout against the
# GUI domain of the current user.
GUI_DOMAIN="gui/$(id -u)"
SERVICE_TARGET="${GUI_DOMAIN}/${LABEL}"

# ssr::schedule::is_loaded — exit 0 iff launchd knows the job.
# `launchctl print` is the modern check; `launchctl list <label>` is the
# legacy fallback that still works on every macOS we care about.
is_loaded() {
    launchctl print "$SERVICE_TARGET" >/dev/null 2>&1 \
        || launchctl list "$LABEL"       >/dev/null 2>&1
}

render_plist() {
    ssr::ensure_dir "$LOG_DIR"
    ssr::ensure_dir "$(dirname "$PLIST_DST")"
    # Substitute placeholders from the template into the user's LaunchAgents dir.
    sed \
        -e "s|@@LABEL@@|${LABEL}|g" \
        -e "s|@@SSR_BIN@@|${SSR_BIN}|g" \
        -e "s|@@LOG_DIR@@|${LOG_DIR}|g" \
        -e "s|@@HOUR@@|${INTERVAL_HOUR}|g" \
        -e "s|@@MINUTE@@|${INTERVAL_MIN}|g" \
        "$PLIST_SRC" > "$PLIST_DST"
    chmod 600 "$PLIST_DST"
}

# Boot the agent into the user's GUI domain, captures stderr for diagnostics.
# Falls back to the legacy `load -w` only if bootstrap fails entirely.
load_agent() {
    local err
    # Always bootout first so re-runs pick up plist changes.
    launchctl bootout "$SERVICE_TARGET" >/dev/null 2>&1 || true

    err="$(launchctl bootstrap "$GUI_DOMAIN" "$PLIST_DST" 2>&1)" || {
        ssr::warn "launchctl bootstrap failed: ${err:-no stderr}"
        ssr::warn "Falling back to legacy 'launchctl load -w'"
        launchctl load -w "$PLIST_DST" 2>&1 || true
    }
    # `enable` makes the job survive logout/reboot (parity with old `load -w`).
    launchctl enable "$SERVICE_TARGET" >/dev/null 2>&1 || true
}

unload_agent() {
    launchctl bootout "$SERVICE_TARGET" >/dev/null 2>&1 \
        || launchctl unload "$PLIST_DST" 2>/dev/null || true
}

cmd_on() {
    [[ -f "$PLIST_SRC" ]] || ssr::die "launchd template missing: $PLIST_SRC"
    render_plist
    load_agent
    if is_loaded; then
        ssr::ok "Scheduled sync enabled (${INTERVAL_HOUR}:$(printf '%02d' "$INTERVAL_MIN") daily) → $PLIST_DST"
    else
        ssr::die "launchd did not register the job. Diagnose with:
    launchctl bootstrap $GUI_DOMAIN $PLIST_DST
    launchctl print $SERVICE_TARGET"
    fi
}

cmd_off() {
    if [[ -f "$PLIST_DST" ]]; then
        unload_agent
        rm -f "$PLIST_DST"
        ssr::ok "Scheduled sync disabled"
    else
        ssr::log "Scheduled sync was not installed"
    fi
}

cmd_status() {
    if is_loaded; then
        ssr::ok "Scheduled sync: active (label=$LABEL)"
    else
        ssr::log "Scheduled sync: inactive"
    fi
}

case "${1:-status}" in
    on|enable)   cmd_on ;;
    off|disable) cmd_off ;;
    status)      cmd_status ;;
    *) ssr::die "Usage: ssr schedule [on|off|status]" ;;
esac
