#!/bin/bash
# ╔══════════════════════════════════════════════════════════════════════════════╗
# ║  setup/modules/lib/logging.sh — Shared logging helpers                    ║
# ║                                                                              ║
# ║  PURPOSE:                                                                    ║
# ║    Provides colored console output functions used by every module script.   ║
# ║    Source this file at the top of any module with:                         ║
# ║      source "$(dirname "${BASH_SOURCE[0]}")/lib/logging.sh"               ║
# ║                                                                              ║
# ║  WHY A SHARED LIB:                                                          ║
# ║    Centralizes formatting so all modules have consistent output. One change ║
# ║    here affects every module's output style.                               ║
# ║                                                                              ║
# ║  ALSO PROVIDES:                                                              ║
# ║    - ensure_flatpak: bootstrap Flatpak + Flathub for any app module       ║
# ║    - apply_flatpak_theme: apply the cyberqueer GTK theme to a Flatpak app ║
# ╚══════════════════════════════════════════════════════════════════════════════╝

# Shared logging helpers — source this in every module

# ── ANSI color codes ──────────────────────────────────────────────────────────
# These are escape sequences that terminal emulators interpret as colors.
# Format: \e[<code>m  where code 31=red, 32=green, 33=yellow, 0=reset.

GREEN="\e[32m"
YELLOW="\e[33m"
RED="\e[31m"
RESET="\e[0m"

# ── Logging functions ──────────────────────────────────────────────────────────
# Each function takes a message string and formats it with a colored prefix.
# WHY: Consistent, colored output makes it easy to scan install logs at a glance
#      and immediately identify success, skips, warnings, or errors.

# log: normal progress message — green [+] prefix
# Used for: "doing X now", successful completions
log()  { printf "${GREEN}[+] %s${RESET}\n" "$*"; }

# skip: indicates something was already done — yellow [~] prefix
# Used for: idempotency checks ("X already installed")
skip() { printf "${YELLOW}[~] %s${RESET}\n" "$*"; }

# warn: non-fatal warning — yellow [!] prefix to stderr
# Used for: recoverable issues that don't abort the module
warn() { printf "${YELLOW}[!] %s${RESET}\n" "$*" >&2; }

# err: fatal error — red [✖] prefix to stderr
# Used for: unrecoverable failures (caller decides whether to exit)
err()  { printf "${RED}[✖] %s${RESET}\n" "$*" >&2; }

# ── Chroot-/session-aware operation helpers ────────────────────────────────────
# Modules are frequently run inside the archiso installer's chroot, where the
# new system's systemd is NOT the running init and there is no user session bus.
# In that environment:
#   * `systemctl enable`  works (it only writes symlinks), and
#   * `systemctl start` / `--now` / `systemctl --user` / `gsettings` FAIL,
# which would abort a module running under `set -e`. These helpers make those
# operations safe so an install completes; the runtime bits take effect on first
# boot / first login instead.

# in_chroot: true when running inside a chroot (no booted system manager here).
in_chroot() { systemd-detect-virt --chroot 2>/dev/null; }

# have_user_bus: true when a user session D-Bus is reachable (needed by
# `systemctl --user`, gsettings/dconf, flatpak --user overrides, etc.).
have_user_bus() {
    [[ -n "${DBUS_SESSION_BUS_ADDRESS:-}" ]] && return 0
    [[ -S "${XDG_RUNTIME_DIR:-/run/user/$(id -u)}/bus" ]]
}

# enable_service: enable units to start at boot. Best-effort — a failure is
# warned, never fatal, so one unenroll-able unit can't abort the whole module.
enable_service() {
    sudo systemctl enable "$@" 2>/dev/null \
        || warn "Could not enable: $* — enable it after first boot."
}

# disable_service: disable units so they don't start at boot. Best-effort —
# a failure (e.g. unit absent) is warned, never fatal. Used when a DE module
# needs to turn off a greeter/service that core.sh or another module enabled
# (e.g. a ly-based DE disabling the greetd core.sh enables by default) so two
# display managers don't both try to claim tty1.
disable_service() {
    sudo systemctl disable "$@" 2>/dev/null \
        || warn "Could not disable: $* — disable it after first boot."
}

# start_service: start units only when a system manager is actually running.
# Inside the installer chroot there is none, so we skip — the unit starts on
# first boot via its enable symlink.
start_service() {
    if in_chroot; then
        skip "Not starting '$*' now (install chroot) — it starts on first boot."
        return 0
    fi
    sudo systemctl start "$@" 2>/dev/null || warn "Could not start: $*"
}

# ── ensure_flatpak ─────────────────────────────────────────────────────────────
# WHY: Many optional app modules install via Flatpak. Rather than duplicating
#      the bootstrap code in every app script, this function handles it once.
# WHAT: Installs flatpak if missing, adds Flathub remote if not already present.
ensure_flatpak() {
    # Check if flatpak binary is available; install it via pacman if not
    if ! command -v flatpak &>/dev/null; then
        log "Installing flatpak..."
        sudo pacman -S --noconfirm --needed flatpak
    fi
    # Add the Flathub remote at --system scope (global install for all users).
    # A non-root user requesting a system action triggers the
    # org.freedesktop.Flatpak SystemHelper over D-Bus + polkit, which is not
    # activatable in a chroot/bare-TTY install — the "The name is not activatable"
    # failure. Running via sudo (as root) performs the system operation directly,
    # so no helper/polkit is involved and global installs work during setup.
    if ! flatpak remotes --system 2>/dev/null | grep -q flathub; then
        log "Adding Flathub remote (system)..."
        sudo flatpak remote-add --system --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo
    fi
}

# ── apply_flatpak_theme ────────────────────────────────────────────────────────
# WHY: Flatpak apps run in sandboxes and can't access the host ~/.themes directory
#      by default. We must explicitly grant filesystem access AND set GTK_THEME.
# WHAT: Copies the cyberqueer GTK theme into ~/.themes, grants the Flatpak app
#       read-only access to that directory, and overrides the GTK_THEME env var.
#
# Usage: apply_flatpak_theme <app-id>
#   e.g. apply_flatpak_theme org.gnome.gedit
apply_flatpak_theme() {
    local app_id="$1"
    local theme_name="cyberqueer"

    # The theme lives in the dotfiles repo under gtk-themes/cyberqueer/
    local theme_src="$HOME/Dotfiles/gtk-themes/$theme_name"
    local themes_dir="$HOME/.themes"

    # Guard: if the theme source doesn't exist, skip gracefully with a warning
    if [[ ! -d "$theme_src" ]]; then
        warn "Cyberqueer theme not found at $theme_src — skipping Flatpak theme override."
        return 0
    fi

    # Copy the theme into the user's ~/.themes/ so it's accessible
    mkdir -p "$themes_dir"
    cp -r "$theme_src" "$themes_dir/$theme_name"

    # Grant the Flatpak app read-only access to ~/.themes using a per-user override.
    # This avoids needing a global system-wide Flatpak override.
    flatpak override --user --filesystem="$themes_dir":ro "$app_id"

    # Set GTK_THEME env var for this app so GTK picks up the correct theme name
    flatpak override --user --env=GTK_THEME="$theme_name" "$app_id"

    log "Cyberqueer theme applied to $app_id."
}
