#!/usr/bin/env bash
set -euo pipefail

VERSION="0.2.5c"
CONFIRM_APPLY="APPLY_SENTINELOS_THEME_BASE"
CONFIRM_RESTORE_BG="RESTORE_SENTINELOS_BACKGROUND"
CONFIRM_SNAPSHOT_BG="SNAPSHOT_SENTINELOS_BACKGROUND"

BACKUP_DIR="${HOME}/.local/share/sentinelos/theme-backups"
BG_BACKUP_DIR="${HOME}/.local/share/sentinelos/background-backups"
POLICY="/usr/share/sentinelos/theme-baseline-lock/policy.json"

usage() {
  cat <<'USAGE'
sentinelos-theme-base v0.2.5c

Commands:
  --summary
  --verify
  --current
  --preview-summary
  --apply aegis-gold|sentinel-dark|sentinel-light --confirm APPLY_SENTINELOS_THEME_BASE
  --restore-default-background --confirm RESTORE_SENTINELOS_BACKGROUND
  --snapshot-background --confirm SNAPSHOT_SENTINELOS_BACKGROUND

Policy:
  Applies only GTK theme, Marco/window theme, and icon theme.
  Background/wallpaper keys are snapshotted and restored during apply.
  Refuses apply as root.
USAGE
}

have_schema() { gsettings list-schemas | grep -qx "$1"; }
gget() { gsettings get "$1" "$2" 2>/dev/null || printf "null"; }
gset() { gsettings set "$1" "$2" "$3"; }

background_snapshot_json() {
  cat <<JSON
{
  "timestamp": "$(date -Iseconds)",
  "draw-background": $(gget org.mate.background draw-background),
  "picture-filename": $(gget org.mate.background picture-filename),
  "picture-options": $(gget org.mate.background picture-options),
  "primary-color": $(gget org.mate.background primary-color),
  "secondary-color": $(gget org.mate.background secondary-color),
  "color-shading-type": $(gget org.mate.background color-shading-type)
}
JSON
}

snapshot_background() {
  mkdir -p "$BG_BACKUP_DIR"
  local f="$BG_BACKUP_DIR/$(date +%Y%m%d-%H%M%S)-background.json"
  background_snapshot_json > "$f"
  echo "$f"
}

restore_background_from_file() {
  local f="$1"
  python3 - "$f" <<'PY'
import json, subprocess, sys, shlex
p=sys.argv[1]
data=json.load(open(p, "r", encoding="utf-8"))
schema="org.mate.background"
for key in ["draw-background","picture-filename","picture-options","primary-color","secondary-color","color-shading-type"]:
    if key not in data or data[key] is None:
        continue
    val=data[key]
    if isinstance(val, bool):
        sval="true" if val else "false"
    else:
        sval=str(val)
        if not (sval.startswith("'") and sval.endswith("'")):
            sval=repr(sval)
    subprocess.run(["gsettings","set",schema,key,sval], check=False)
PY
}

save_theme_backup() {
  mkdir -p "$BACKUP_DIR"
  local f="$BACKUP_DIR/$(date +%Y%m%d-%H%M%S)-theme-base.json"
  cat > "$f" <<JSON
{
  "timestamp": "$(date -Iseconds)",
  "gtk": $(gget org.mate.interface gtk-theme),
  "icons": $(gget org.mate.interface icon-theme),
  "marco": $(gget org.mate.Marco.general theme),
  "background": $(background_snapshot_json | python3 -c 'import json,sys; print(json.dumps(json.load(sys.stdin)))')
}
JSON
  echo "$f"
}

apply_variant() {
  local variant="$1"
  local confirm="${2:-}"
  if [ "$(id -u)" = "0" ]; then
    echo "ERROR: Refusing to apply a user desktop theme as root." >&2
    exit 2
  fi
  if [ "$confirm" != "$CONFIRM_APPLY" ]; then
    echo "ERROR: Missing confirmation. Use --confirm $CONFIRM_APPLY" >&2
    exit 2
  fi

  local gtk="" icons="" marco="" label=""
  case "$variant" in
    aegis-gold)
      gtk="SentinelOS-Dark-Gold"; marco="SentinelOS-Dark-Gold"; icons="SentinelOS-Dark"; label="AEGIS Gold"
      ;;
    sentinel-dark)
      gtk="SentinelOS-Dark-Cyan"; marco="SentinelOS-Dark-Cyan"; icons="SentinelOS-Light"; label="SentinelOS Dark"
      ;;
    sentinel-light)
      gtk="SentinelOS-Light-Cyan"; marco="SentinelOS-Light-Cyan"; icons="SentinelOS-Light"; label="SentinelOS Light"
      ;;
    *)
      echo "ERROR: Unknown variant: $variant" >&2
      exit 2
      ;;
  esac

  [ -d "/usr/share/themes/$gtk" ] || { echo "ERROR: Missing theme /usr/share/themes/$gtk" >&2; exit 1; }
  [ -d "/usr/share/themes/$marco" ] || { echo "ERROR: Missing Marco theme /usr/share/themes/$marco" >&2; exit 1; }
  [ -d "/usr/share/icons/$icons" ] || { echo "ERROR: Missing icon theme /usr/share/icons/$icons" >&2; exit 1; }

  local bg_snapshot
  bg_snapshot="$(snapshot_background)"
  local theme_backup
  theme_backup="$(save_theme_backup)"

  gset org.mate.interface gtk-theme "$gtk"
  gset org.mate.interface icon-theme "$icons"
  if have_schema org.mate.Marco.general; then
    gset org.mate.Marco.general theme "$marco"
  fi

  # Hard background preservation: restore every background key immediately after theme apply.
  restore_background_from_file "$bg_snapshot"

  echo "backup: $theme_backup"
  echo "background_backup: $bg_snapshot"
  echo "applied: $variant ($label)"
  echo "wallpaper/background: preserved"
}

summary() {
  cat <<EOF
SentinelOS Theme Base Reframe + Background Guard
version: $VERSION
gold_first_baseline: yes
official_dark: SentinelOS-Dark-Cyan / display SentinelOS Dark
official_light: SentinelOS-Light-Cyan / display SentinelOS Light
aegis_gold: SentinelOS-Dark-Gold / display AEGIS Gold
aegis_gold_policy: install-only-with-aegis
background_preservation_guard: enabled
background_changes_on_theme_apply: no
managed_background_keys: picture-filename picture-options draw-background primary-color secondary-color color-shading-type
withdrawn_v0_1_9b_theme_reuse: blocked
unsafe_legacy_theme_root: /usr/share/themes/SentinelOS-Dark
sentinel-dark: theme=$([ -d /usr/share/themes/SentinelOS-Dark-Cyan ] && echo present || echo missing) icons=$([ -d /usr/share/icons/SentinelOS-Light ] && echo present || echo missing)
sentinel-light: theme=$([ -d /usr/share/themes/SentinelOS-Light-Cyan ] && echo present || echo missing) icons=$([ -d /usr/share/icons/SentinelOS-Light ] && echo present || echo missing)
aegis-gold: theme=$([ -d /usr/share/themes/SentinelOS-Dark-Gold ] && echo present || echo missing) icons=$([ -d /usr/share/icons/SentinelOS-Dark ] && echo present || echo missing)
theme_baseline_lock_policy: $([ -f "$POLICY" ] && echo present || echo missing)
EOF
}

verify() {
  local ok=1
  for d in /usr/share/themes/SentinelOS-Dark-Gold /usr/share/themes/SentinelOS-Dark-Cyan /usr/share/themes/SentinelOS-Light-Cyan; do
    if [ ! -d "$d" ]; then echo "missing: $d"; ok=0; fi
  done
  for d in /usr/share/icons/SentinelOS-Dark /usr/share/icons/SentinelOS-Light; do
    if [ ! -d "$d" ]; then echo "missing: $d"; ok=0; fi
  done
  if [ -d /usr/share/themes/SentinelOS-Dark ]; then
    echo "ERROR: withdrawn unsafe legacy root present: /usr/share/themes/SentinelOS-Dark"
    ok=0
  fi
  if ! have_schema org.mate.background; then
    echo "missing gsettings schema: org.mate.background"
    ok=0
  fi
  [ -f "$POLICY" ] || { echo "missing policy: $POLICY"; ok=0; }
  if [ "$ok" = "1" ]; then echo "verify: ok"; else echo "verify: failed"; exit 1; fi
}

current() {
  echo "gtk: $(gget org.mate.interface gtk-theme)"
  echo "icons: $(gget org.mate.interface icon-theme)"
  echo "marco: $(gget org.mate.Marco.general theme)"
  echo "background_picture: $(gget org.mate.background picture-filename)"
  echo "background_options: $(gget org.mate.background picture-options)"
}

preview_summary() {
  for t in SentinelOS-Dark-Gold SentinelOS-Dark-Cyan SentinelOS-Light-Cyan; do
    echo "$t preview=$([ -f /usr/share/themes/$t/preview.png ] && echo present || echo missing) thumbnail=$([ -f /usr/share/themes/$t/thumbnail.png ] && echo present || echo missing)"
  done
}

restore_default_bg() {
  local confirm="${1:-}"
  if [ "$(id -u)" = "0" ]; then
    echo "ERROR: Refusing to modify user desktop background as root." >&2
    exit 2
  fi
  if [ "$confirm" != "$CONFIRM_RESTORE_BG" ]; then
    echo "ERROR: Missing confirmation. Use --confirm $CONFIRM_RESTORE_BG" >&2
    exit 2
  fi
  local p="/usr/share/backgrounds/sentinelos/default-desktop.png"
  [ -f "$p" ] || { echo "ERROR: missing $p"; exit 1; }
  snapshot_background >/dev/null
  gset org.mate.background draw-background true
  gset org.mate.background picture-filename "$p"
  gset org.mate.background picture-options "zoom"
  echo "restored_background: $p"
  echo "picture-options: zoom"
}

snapshot_bg_cmd() {
  local confirm="${1:-}"
  if [ "$confirm" != "$CONFIRM_SNAPSHOT_BG" ]; then
    echo "ERROR: Missing confirmation. Use --confirm $CONFIRM_SNAPSHOT_BG" >&2
    exit 2
  fi
  echo "background_backup: $(snapshot_background)"
}

if [ $# -eq 0 ]; then usage; exit 0; fi
case "$1" in
  --summary) summary ;;
  --verify) verify ;;
  --current) current ;;
  --preview-summary) preview_summary ;;
  --apply)
    variant="${2:-}"; shift 2 || true
    confirm=""
    if [ "${1:-}" = "--confirm" ]; then confirm="${2:-}"; fi
    apply_variant "$variant" "$confirm"
    ;;
  --restore-default-background)
    shift
    confirm=""
    if [ "${1:-}" = "--confirm" ]; then confirm="${2:-}"; fi
    restore_default_bg "$confirm"
    ;;
  --snapshot-background)
    shift
    confirm=""
    if [ "${1:-}" = "--confirm" ]; then confirm="${2:-}"; fi
    snapshot_bg_cmd "$confirm"
    ;;
  --help|-h) usage ;;
  *) usage; exit 2 ;;
esac
