#!/bin/bash
set -euo pipefail

# MacSync — Photos-originals network mount installer (plum).
#
# Restores the pre-black architecture: the Photos.app `originals/` subtree lives
# off-disk, served on demand by `rclone mount` over DO Spaces with a bounded LRU
# cache. The SQLite core (database/) + derivatives (resources/) stay local on
# APFS. Both Photos.app and macsync's IPhotoSync read the same mounted files.
#
# Phased + idempotent. Run on plum:
#   ./install-photos-mount.sh            # deps + mount + LaunchAgent (safe)
#   ./install-photos-mount.sh --deps     # install macFUSE + rclone only
#   ./install-photos-mount.sh --link     # repoint the library symlink (GATED:
#                                        #   only after originals exist in Spaces)
#   ./install-photos-mount.sh --uninstall
#
# Secrets come from ~/.vault (0600), never the environment or in-tree.

BUNDLE_ID="com.lilith.macsync.photos-originals"
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
MOUNT_SCRIPT="$SCRIPT_DIR/photos-originals-mount.sh"
LAUNCH_AGENTS_DIR="$HOME/Library/LaunchAgents"
PLIST_FILE="$LAUNCH_AGENTS_DIR/$BUNDLE_ID.plist"

# Mount/library coordinates (override via env to match photos-originals-mount.sh).
LIBRARY="${LIBRARY:-$HOME/Pictures/Photos Library.photoslibrary}"
MOUNTPOINT="${MOUNTPOINT:-$HOME/_/photos-originals}"
VAULT="${VAULT:-$HOME/.vault}"
ACCESS_FILE="$VAULT/do-spaces-uvlava.access"
SECRET_FILE="$VAULT/do-spaces-uvlava.secret"
ORIGINALS_LINK="$LIBRARY/originals"
LINK_BACKUP="$SCRIPT_DIR/.originals-symlink.bak"   # records the prior target

RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'; BLUE='\033[0;34m'; NC='\033[0m'
print_step()    { echo -e "${GREEN}▸${NC} $1"; }
print_info()    { echo -e "${BLUE}ℹ${NC} $1"; }
print_warning() { echo -e "${YELLOW}⚠${NC} $1"; }
print_error()   { echo -e "${RED}✗${NC} $1"; }
print_success() { echo -e "${GREEN}✓${NC} $1"; }

check_macos() {
  [[ "$OSTYPE" == "darwin"* ]] || { print_error "macOS only"; exit 1; }
}

check_brew() {
  command -v brew &>/dev/null || {
    print_error "Homebrew not found — install from https://brew.sh first"; exit 1; }
}

# --- deps: macFUSE (kext, needs approval) + rclone -------------------------
install_deps() {
  check_brew

  if [[ -d /Library/Frameworks/macFUSE.framework || -d /Library/Frameworks/OSXFUSE.framework ]]; then
    print_success "macFUSE already installed"
  else
    print_step "Installing macFUSE (kernel extension — requires approval)..."
    brew install --cask macfuse
    print_warning "macFUSE needs a one-time approval:"
    print_warning "  System Settings → Privacy & Security → 'Allow' the Benjamin Fleischer kext,"
    print_warning "  then REBOOT. Re-run this installer after the reboot."
  fi

  if command -v rclone &>/dev/null; then
    print_success "rclone present: $(rclone version | head -n1)"
  else
    print_step "Installing rclone..."
    brew install rclone
  fi
}

check_vault() {
  [[ -f "$ACCESS_FILE" && -f "$SECRET_FILE" ]] || {
    print_error "Missing Spaces creds in $VAULT (do-spaces-uvlava.access/.secret)"; exit 1; }
  print_success "Spaces creds present in vault"
}

check_macfuse_ready() {
  if [[ ! -d /Library/Frameworks/macFUSE.framework ]]; then
    print_error "macFUSE not installed — run: $0 --deps  (then approve + reboot)"; exit 1
  fi
  command -v rclone &>/dev/null || { print_error "rclone missing — run: $0 --deps"; exit 1; }
}

# --- LaunchAgent: generated with resolved paths (single source of truth) ----
write_plist() {
  print_step "Writing LaunchAgent → $PLIST_FILE"
  mkdir -p "$LAUNCH_AGENTS_DIR"
  cat > "$PLIST_FILE" <<PLIST
<?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>$BUNDLE_ID</string>
  <key>ProgramArguments</key>
  <array>
    <string>/bin/bash</string>
    <string>$MOUNT_SCRIPT</string>
  </array>
  <key>EnvironmentVariables</key>
  <dict>
    <key>PATH</key><string>/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin</string>
    <key>MOUNTPOINT</key><string>$MOUNTPOINT</string>
    <key>LIBRARY</key><string>$LIBRARY</string>
  </dict>
  <key>RunAtLoad</key><true/>
  <key>KeepAlive</key>
  <dict><key>SuccessfulExit</key><false/></dict>
  <key>StandardOutPath</key><string>/tmp/macsync-photos-originals.log</string>
  <key>StandardErrorPath</key><string>/tmp/macsync-photos-originals.err</string>
</dict>
</plist>
PLIST
}

load_agent() {
  if launchctl list | grep -q "$BUNDLE_ID"; then
    print_step "Reloading LaunchAgent..."
    launchctl unload "$PLIST_FILE" 2>/dev/null || true
  fi
  launchctl load -w "$PLIST_FILE"
  print_success "LaunchAgent loaded — mount will come up at login and self-heal"
}

verify_mount() {
  print_step "Waiting for mount at $MOUNTPOINT ..."
  for _ in $(seq 1 15); do
    if mount | grep -q " $MOUNTPOINT "; then
      print_success "Mounted: $(mount | grep " $MOUNTPOINT " | head -n1)"
      return 0
    fi
    sleep 1
  done
  print_warning "Mount not visible yet — check /tmp/macsync-photos-originals.err"
  print_warning "(macFUSE kext not approved? originals prefix empty? creds wrong?)"
  return 1
}

# --- GATED: repoint the live library symlink onto the mount -----------------
# Refuses unless the mount is up AND the originals tree is non-empty, so we
# never hand Photos.app an empty library.
repoint_symlink() {
  check_macfuse_ready
  mount | grep -q " $MOUNTPOINT " || { print_error "Mount not active — bring it up first ($0)"; exit 1; }

  if [[ -z "$(ls -A "$MOUNTPOINT" 2>/dev/null)" ]]; then
    print_error "Mount is EMPTY — the originals tree isn't in Spaces yet."
    print_error "Seed it first (iCloud download → rclone copy up), then re-run --link."
    exit 1
  fi

  if [[ -L "$ORIGINALS_LINK" ]]; then
    local cur; cur="$(readlink "$ORIGINALS_LINK")"
    echo "$cur" > "$LINK_BACKUP"
    print_info "Saved prior symlink target → $LINK_BACKUP ($cur)"
  elif [[ -e "$ORIGINALS_LINK" ]]; then
    print_error "$ORIGINALS_LINK exists and is NOT a symlink — refusing to touch real data."
    exit 1
  fi

  print_warning "Quit Photos.app before repointing (it locks the library)."
  read -r -p "Repoint $ORIGINALS_LINK → $MOUNTPOINT ? [y/N] " ans
  [[ "$ans" == "y" || "$ans" == "Y" ]] || { print_info "Aborted."; exit 0; }

  rm -f "$ORIGINALS_LINK"
  ln -s "$MOUNTPOINT" "$ORIGINALS_LINK"
  print_success "Symlink repointed. Open Photos.app — originals stream on demand."
}

uninstall() {
  print_step "Unloading LaunchAgent + unmounting..."
  launchctl unload "$PLIST_FILE" 2>/dev/null || true
  rm -f "$PLIST_FILE"
  if mount | grep -q " $MOUNTPOINT "; then
    umount "$MOUNTPOINT" 2>/dev/null || diskutil unmount "$MOUNTPOINT" 2>/dev/null || true
  fi
  if [[ -f "$LINK_BACKUP" && -L "$ORIGINALS_LINK" ]]; then
    local prev; prev="$(cat "$LINK_BACKUP")"
    print_warning "Prior symlink target was: $prev (restore manually if desired)"
  fi
  print_success "Uninstalled mount + agent. Library symlink left as-is."
}

main() {
  check_macos
  echo -e "${BLUE}━━━ MacSync — Photos Originals Mount Installer ━━━${NC}"
  case "${1:-}" in
    --deps)      install_deps ;;
    --link)      repoint_symlink ;;
    --uninstall) uninstall ;;
    "" )
      install_deps
      check_vault
      check_macfuse_ready
      write_plist
      load_agent
      verify_mount || true
      echo
      print_info "Next: seed the originals tree into Spaces, then: $0 --link"
      ;;
    *) print_error "Unknown option: $1"; exit 1 ;;
  esac
}

main "$@"
