#!/bin/bash
# =============================================================================
# hyprland.sh — Hyprland Desktop Environment installer (legacy hyprlang config)
# =============================================================================
# Part of the Dotfiles setup system for Arch Linux.
#
# Hyprland is a dynamic tiling Wayland compositor built in C++ with a focus on
# animations, eye-candy, and a powerful plugin system (hyprpm).
#
# This is the LEGACY variant that uses hyprlang (.conf) configuration files.
# The newer hyprlua.sh uses Lua for configuration instead.  Both installers
# share a nearly identical package list; the key differences are:
#   - EWW and config source paths point to desktopenvs/hyprland/ (not hyprlua/)
#   - hypr-usr/ device-specific .conf files are placed at ~/.config/ root level
#     and sourced by hyprland.conf via 'source' directives
#   - hyprlua.sh additionally installs python-opencv and v4l-utils for the
#     webcam-based presence/idle detection daemon
#
# High-level install flow:
#   1.  System update + Flatpak
#   2.  pacman packages (compositor, audio, networking, tools, fonts)
#   3.  systemd service enablement (NetworkManager, ly display manager, udisks2)
#   4.  AUR packages via yay
#   5.  EWW status-bar (interactive form-factor selection + Rust compilation)
#   6.  Themes, icons, ly config, terminal symlink, SSH askpass
#   7.  Nordzy left-hand cursor theme
#   8.  Bluetooth / iwd wireless services
#   9.  Config file deployment from Dotfiles
#  10.  Wallpaper + resource files
#  11.  Python venv for helper scripts
#  12.  Udiskie tray-icon symlink fix
#  13.  config-updater symlinks + apply-theme.sh
#
# Prerequisites: internet access, yay (AUR helper), rustup, git, curl, cargo.
# =============================================================================

# Exit immediately if any command fails — partial DE installs can leave the
# system in a broken graphical state, so aborting early is safer.
set -e

# Load shared logging helpers (log, warn, err) from the setup library.
source "$(dirname "${BASH_SOURCE[0]}")/../lib/logging.sh"

log "Starting Hyprland installer (legacy — hyprlang config)..."

# ---------------------------------------------------------------------------
# 1. Update system and install Flatpak
# ---------------------------------------------------------------------------
# Run a full system upgrade first to avoid Arch partial-upgrade issues (on a
# rolling release, installing new packages against an un-updated system can
# cause library ABI mismatches).  Flatpak is installed early so AUR steps that
# depend on it can find it.
log "Updating system and installing Flatpak..."
sudo pacman -Syu --noconfirm --needed flatpak

# ---------------------------------------------------------------------------
# 2. Install required packages
# ---------------------------------------------------------------------------
log "Installing required packages..."
# Packages live in an array so each can carry an inline comment. A single
# backslash-continued `pacman` command cannot: bash treats the first inline
# comment as the end of the command, silently dropping every later package
# (which then get run as shell commands and abort under `set -e`).
HYPRLAND_PACKAGES=(
    hyprland              # the Wayland compositor / window manager
    hyprcursor            # hardware-accelerated cursor rendering for Hyprland
    wl-clipboard          # wl-copy / wl-paste; clipboard tools for Wayland
    hyprpaper             # wallpaper utility with per-monitor and animation support
    hyprlock              # GPU-accelerated screen locker (Hyprland-native)
    wofi                  # Wayland application launcher (rofi replacement)
    kitty                 # GPU-accelerated terminal (default terminal in this setup)
    dunst                 # lightweight, scriptable notification daemon

    nwg-dock-hyprland     # dock/taskbar with Hyprland workspace awareness
    nwg-drawer            # application drawer (grid-style launcher)
    nwg-menu              # GTK menu used in the panel's app button
    nwg-look              # GTK/cursor/icon theme picker for wlroots sessions

    # Build tools needed to compile EWW (Rust) and AUR packages (C/C++/Ruby)
    python cmake meson cpio pkgconf ruby-pkg-config

    hyprsunset            # blue-light filter / night-mode daemon for Hyprland
    hypridle              # idle daemon that triggers lock/suspend after inactivity
    ksshaskpass           # Qt SSH passphrase dialog (registered as ssh-askpass)

    nm-connection-editor   # GTK GUI for editing NetworkManager profiles
    network-manager-applet # system-tray applet showing Wi-Fi/VPN status
    blueman                # GTK Bluetooth manager with tray icon
    bluez                  # core Linux Bluetooth protocol stack

    pipewire              # modern audio/video routing daemon
    alsa-utils            # ALSA CLI tools (amixer, aplay) for low-level audio
    firefox               # web browser
    greetd-tuigreet       # TUI login greeter (text-based, no GPU needed at DM)

    grim                  # Wayland screenshot tool (outputs to file or stdout)
    slurp                 # interactive region selector (used with grim)
    gst-plugin-pipewire   # GStreamer plugin bridging through PipeWire
    imagemagick           # image processing (screenshot effects, compositing)

    nerd-fonts            # all Nerd Font patched families (icon glyphs in bar)
    otf-font-awesome      # Font Awesome icon glyphs for EWW/dunst

    # Compatibility layers: let ALSA, JACK, and PulseAudio apps route through
    # PipeWire without requiring code changes in those apps
    pipewire-alsa pipewire-jack pipewire-pulse

    qt5-wayland           # Qt5 platform plugin for native Wayland rendering
    qt6-wayland           # Qt6 platform plugin for native Wayland rendering
    swww                  # smooth animated wallpaper daemon
    ttf-jetbrains-mono    # monospace font for terminals and the EWW bar
    wireplumber           # PipeWire session/policy manager

    qt6ct                       # Qt6 colour/style configurator (run as user)
    xdg-desktop-portal-hyprland # Hyprland XDG portal (screen share, file pick)
    xdg-utils                   # xdg-open / MIME handling helpers

    xorg-server           # X server for XWayland (legacy X11 apps)
    xorg-xinit            # startx / xinitrc support for XWayland
    papirus-icon-theme    # icon theme used system-wide and by udiskie

    cool-retro-term       # retro CRT-style terminal emulator
    qalculate-gtk         # powerful GTK calculator with unit conversion
    iwd                   # Intel Wireless Daemon (lightweight Wi-Fi back-end)
    dbus                  # D-Bus inter-process communication daemon

    thunar                # lightweight GTK file manager (XFCE project)
    tumbler               # thumbnail service for Thunar
    thunar-archive-plugin # right-click archive (zip/tar) integration
    thunar-shares-plugin  # Samba share management from Thunar
    thunar-volman         # automatic volume/device mounting in Thunar

    hyprpicker            # colour picker outputting hex/rgb/hsl under Hyprland
    pcmanfm-qt            # Qt file manager kept as fallback
    udisks2               # D-Bus service for querying and managing storage devices
    ly                    # minimal TUI display manager (replaces getty on tty1)
    kew                   # terminal music player

    hyprpolkitagent         # Hyprland-native Polkit authentication agent
    pavucontrol             # PulseAudio/PipeWire volume control GUI
    playerctl               # MPRIS media player controller (play/pause CLI)
    wf-recorder             # screen recorder for wlroots compositors
    sound-theme-freedesktop # standard freedesktop sound event library
)
sudo pacman -Syu --noconfirm --needed -- "${HYPRLAND_PACKAGES[@]}"

# ---------------------------------------------------------------------------
# 3. Enable essential services
# ---------------------------------------------------------------------------
log "Enabling essential services..."

# NetworkManager must be active on boot for network connectivity.
enable_service NetworkManager.service

# getty@tty1 is the default text-mode login prompt; we replace it with ly.
# '|| true' prevents abort if the unit is already disabled or doesn't exist.
sudo systemctl disable getty@tty1.service || true

# Disable greetd, which core.sh enables by default for every install. This DE
# uses ly as its greeter, so leaving greetd enabled means two display managers
# both race to claim tty1 — and the stale greetd/tuigreet greeter can win,
# showing the old text login instead of ly. Disable it so ly is the sole greeter.
disable_service greetd.service

# ly is the TUI display manager that runs on tty1 and launches Hyprland after
# the user logs in.
enable_service ly@tty1.service

# udisks2 provides the D-Bus API for block devices; required by udiskie for
# automatic USB/external drive mounting.
enable_service udisks2.service

# ---------------------------------------------------------------------------
# 4. Install AUR packages
# ---------------------------------------------------------------------------
log "Installing AUR packages..."

# Activate the stable Rust toolchain so AUR packages that compile Rust code
# (and EWW compiled below) use a known-good toolchain version.
rustup default stable

# yay flags:
#   --answerdiff None   — skip PKGBUILD diff display (non-interactive)
#   --answerclean All   — always clean build dirs between builds
#   --noconfirm         — no confirmation prompts
#
# Packages:
#   hyprland-workspaces — EWW workspace widget reading Hyprland IPC socket
#   vicinae-bin         — pre-built vicinae (vim-like keybind layer for scripts)
#   bluetuith           — TUI Bluetooth manager (used in the menus)
#   wvkbd               — on-screen virtual keyboard for Wayland (touch)
#   iwmenu              — wofi-based Wi-Fi network picker using iwd
#   pinta               — simple image editor
#   walker-bin          — fast app launcher / runner (pre-built binary)
#   ulauncher           — extensible app launcher with plugin ecosystem
#   bzmenu              — quick Bluetooth device connect menu for the bar
#   udiskie             — automounter with tray icon (built on udisks2)
#   wofi-calc           — inline calculator pop-up inside wofi
#   bri                 — brightness control CLI helper for bar widgets
#   chamel              — theme-switching helper (applies colour palettes)
yay -Syu --answerdiff None --answerclean All --noconfirm \
    hyprland-workspaces vicinae-bin bluetuith wvkbd iwmenu pinta \
    walker-bin ulauncher bzmenu udiskie \
    wofi-calc bri chamel

# ---------------------------------------------------------------------------
# 5. EWW bar selection and compilation
# ---------------------------------------------------------------------------
# EWW (Elkowar's Wacky Widgets) is a Rust widget framework that powers the
# custom status bar.  Three layouts exist for different hardware form factors:
#   eww/            — Notebook layout (includes battery widget)
#   eww-nobattery/  — Desktop PC layout (no battery bar)
#   eww-touch/      — Tablet layout (larger touch targets)
log "Setting up EWW bar..."

# Wipe any previous EWW config to avoid stale widget definitions conflicting
# with the freshly copied one.
rm -rf ~/.config/eww

# Prompt for form factor with a single keypress (no Enter needed). In unattended
# installs (answerfile mode) or when stdin is not a terminal, skip the prompt and
# default to the desktop/no-battery layout so the install never blocks on input.
if [[ "${MARCHY_UNATTENDED:-0}" == "1" || ! -t 0 ]]; then
    doit="P"
    log "Unattended mode — installing desktop (no-battery) EWW bar."
else
    read -n1 -p "Install eww bar for PC, Notebook or Tablet [P/N/T]: " doit
    echo  # Print newline so subsequent output starts on a fresh line
fi

case $doit in
    # Notebook: copy the battery-aware layout
    n|N) cp -rf ~/Dotfiles/desktopenvs/hyprland/eww/ ~/.config/ ;;
    # Desktop PC: copy the no-battery layout
    p|P) cp -rf ~/Dotfiles/desktopenvs/hyprland/eww-nobattery/ ~/.config/eww ;;
    # Tablet: copy touch-optimised layout
    t|T) cp -rf ~/Dotfiles/desktopenvs/hyprland/eww-touch/ ~/.config/eww ;;
    # Unknown key: warn and skip; the user must copy manually later
    *)   warn "No valid choice — skipping EWW copy. Run manually later." ;;
esac

log "Compiling EWW..."
# EWW is not in the official repos so we compile from source.
# ~/install-tmp is a staging area for source trees fetched during installation.
mkdir -p ~/install-tmp
cd ~/install-tmp
git clone https://github.com/elkowar/eww
cd eww
# --release             → optimised binary (significantly faster than debug)
# --no-default-features → disable the X11 backend entirely
# --features=wayland    → enable only the Wayland backend
cargo build --release --no-default-features --features=wayland
chmod +x target/release/eww
# Install system-wide so any autostart entry or script can call 'eww' directly.
sudo cp target/release/eww /usr/bin/
cd ~  # Return home so subsequent relative-path steps work correctly

# ---------------------------------------------------------------------------
# 6. Theme and icon setup
# ---------------------------------------------------------------------------
log "Installing themes and icons..."

# Install the cyberqueer GTK theme system-wide so GTK2/3/4 apps pick it up.
sudo cp -r ~/Dotfiles/gtk-themes/cyberqueer /usr/share/themes

# Install the matching btop colour theme for the terminal system monitor.
sudo cp ~/Dotfiles/desktopenvs/hyprland/btop/themes/cyberqueer.theme /usr/share/btop/themes

# Deploy the ly display-manager config (login screen appearance, session list).
sudo cp -f ~/Dotfiles/etc-ly-config.ini /etc/ly/config.ini

# Register kitty as the system-default terminal for xdg-terminal-exec so
# file managers and scripts that call "Open Terminal Here" launch kitty.
sudo ln -sf /usr/bin/kitty /usr/bin/xdg-terminal-exec

# Register ksshaskpass as the SSH passphrase helper.
# When SSH needs a passphrase in a non-terminal context (e.g. git push from a
# script), it invokes /usr/lib/ssh/ssh-askpass; this link provides a GUI dialog.
sudo ln -sf /usr/bin/ksshaskpass /usr/lib/ssh/ssh-askpass

# ---------------------------------------------------------------------------
# 7. Cursor setup
# ---------------------------------------------------------------------------
# Nordzy-cursors-lefthand is a Nord-palette left-handed cursor theme.
# Downloaded from GitHub Releases rather than the AUR because the AUR build
# may lag behind the upstream release schedule.
log "Installing cursor theme..."
mkdir -p ~/.icons
curl -fL -o ~/install-tmp/Nordzy-cursors-lefthand.tar.gz \
    https://github.com/guillaumeboehm/Nordzy-cursors/releases/download/v2.3.0/Nordzy-cursors-lefthand.tar.gz
# Extract directly into ~/.icons/ so the theme is immediately discoverable by
# Hyprland (via hyprcursor) and by GTK applications.
tar -zxf ~/install-tmp/Nordzy-cursors-lefthand.tar.gz -C ~/.icons/

# ---------------------------------------------------------------------------
# 8. Enable Bluetooth and wireless services
# ---------------------------------------------------------------------------
log "Enabling Bluetooth and wireless services..."

# bluez: core Bluetooth protocol stack (powers and manages adapters on boot)
enable_service bluez
# bluetooth.service: high-level service handling pairing and profiles
enable_service bluetooth.service
# iwd: modern Wi-Fi daemon from Intel; used by iwmenu for the bar Wi-Fi picker
enable_service iwd.service

# ---------------------------------------------------------------------------
# 9. Hyprland plugins (must be run from inside a live Hyprland session)
# ---------------------------------------------------------------------------
# hyprpm links against the exact compositor binary, so it cannot run from the
# installer.  Execute these commands manually after first login:
#   hyprpm update
#   hyprpm add https://github.com/hyprwm/hyprland-plugins

# ---------------------------------------------------------------------------
# 10. Copy configs
# ---------------------------------------------------------------------------
log "Copying configs..."

# Each entry in CONFIGS maps to a sub-directory (or file) inside
# desktopenvs/hyprland/ that is deployed verbatim to ~/.config/.
# Old copies are wiped first to prevent stale files from prior installs
# interfering with the fresh deployment.
CONFIGS=(kitty mimeapps.list vicinae walker ulauncher hypr xfce4 wofi dunst alacritty nwg-dock-hyprland nwg-drawer nwg-panel scripts btop gtk-3.0)
for cfg in "${CONFIGS[@]}"; do
    rm -rf ~/.config/"$cfg"
    cp -r ~/Dotfiles/desktopenvs/hyprland/"$cfg" ~/.config/
done

# Vicinae loads NAMED custom themes only from ~/.local/share/vicinae/themes/*.toml,
# NOT from ~/.config/vicinae/. The cyberqueer.toml copied above lands in the
# config dir where Vicinae never looks, so settings.json's
# theme.dark.name="cyberqueer" silently falls back to the stock dark theme.
# Deploy the theme where Vicinae actually scans so the named theme resolves.
mkdir -p ~/.local/share/vicinae/themes
cp -f ~/Dotfiles/desktopenvs/hyprland/vicinae/cyberqueer.toml \
      ~/.local/share/vicinae/themes/cyberqueer.toml

# hypr-usr/ holds device-specific overrides (monitor layout, keybinds, envvars).
# In the legacy hyprlang setup these are .conf files at the ~/.config/ root
# level; hyprland.conf sources them with 'source = ~/.config/monitors.conf' etc.
cp ~/Dotfiles/desktopenvs/hyprland/hypr-usr/* ~/.config/

# colors.conf defines the shared colour palette used by EWW, dunst, and scripts.
cp ~/Dotfiles/colors.conf ~/.config/colors.conf

# ---------------------------------------------------------------------------
# 11. Wallpaper and resources
# ---------------------------------------------------------------------------
log "Copying wallpaper and resources..."
mkdir -p ~/Pictures

# Firefox logo SVG used as the dock/launcher shortcut icon.
cp ~/Dotfiles/resources/fflogo.svg ~/Pictures/fflogo.svg

# Download the personalised wallpaper from the owner's Nextcloud instance.
# ?v=15 is a cache-buster version parameter on the Nextcloud theming API.
curl -fL "https://cloud.abdelbaki.eu/apps/theming/image/background?v=15" -o ~/Pictures/background.jpg

# ---------------------------------------------------------------------------
# 12. Python venv for scripts
# ---------------------------------------------------------------------------
# Many EWW and Hyprland helper scripts are written in Python and need these
# third-party libraries.  An isolated venv avoids polluting the system Python
# and prevents conflicts with pacman-managed Python packages.
log "Setting up Python venv for scripts..."
python -m venv ~/.config/python-script
~/.config/python-script/bin/pip install \
    speedtest-cli   `# Internet speed test widget for the EWW bar` \
    requests        `# HTTP client used by various widgets and scripts` \
    pint            `# Unit conversion library for the calculator script` \
    simpleeval      `# Safe maths expression evaluator (wofi-calc backend)` \
    parsedatetime   `# Natural-language date/time parser for timer scripts`

# ---------------------------------------------------------------------------
# 13. Udiskie icon fix
# ---------------------------------------------------------------------------
# udiskie uses freedesktop icon names (udiskie-checkbox-checked, etc.) that
# most icon themes do not ship.  We symlink them from Papirus-Dark's existing
# checkbox icons as a close visual match.  Placing symlinks in the hicolor
# theme ensures every GTK app can find them as hicolor is the last-resort
# fallback in the icon theme lookup chain.
log "Applying Udiskie icon fix..."
PAPIRUS_DIR="/usr/share/icons/Papirus-Dark/status"
HICOLOR_DIR="/usr/share/icons/hicolor/scalable/status"
if [ -d "$PAPIRUS_DIR" ]; then
    sudo ln -sf "$PAPIRUS_DIR/checkbox-checked.svg"   "$HICOLOR_DIR/udiskie-checkbox-checked.svg"
    sudo ln -sf "$PAPIRUS_DIR/checkbox-unchecked.svg" "$HICOLOR_DIR/udiskie-checkbox-unchecked.svg"
    # Rebuild the icon cache so GTK discovers the new symlinked entries without
    # requiring a full logout/login.
    sudo gtk-update-icon-cache -f -t /usr/share/icons/hicolor
else
    warn "Papirus-Dark not found — skipping udiskie icon fix."
fi

# ---------------------------------------------------------------------------
# 14. Enable udiskie
# ---------------------------------------------------------------------------
# udiskie is the auto-mounter / tray-icon daemon that surfaces mounted volumes.
# Enable the systemd user unit and start it immediately so this session already
# benefits from auto-mounting without requiring a reboot.
log "Enabling udiskie service..."
enable_service udiskie.service
start_service udiskie.service

# ---------------------------------------------------------------------------
# 15. Install config updater and theme script
# ---------------------------------------------------------------------------
# config-updater is a lightweight mechanism that re-syncs selected config files
# from the Dotfiles repo without running the full installer again.
# updater.conf lists which files to keep in sync; update-configs.sh performs
# the actual copy operation.
#
# Symlinks (ln -sf) are used so that 'git pull' in ~/Dotfiles immediately takes
# effect the next time update-configs.sh is run.
log "Installing config updater and theme script..."
mkdir -p ~/.config/config-updater
ln -sf ~/Dotfiles/desktopenvs/hyprland/config-updater/updater.conf ~/.config/config-updater/updater.conf
ln -sf ~/Dotfiles/desktopenvs/hyprland/config-updater/update-configs.sh ~/update-configs.sh

# apply-theme.sh applies the cyberqueer colour palette across all running apps
# (sets GTK/Qt themes, reloads dunst config, refreshes EWW colour variables).
# Copied (not symlinked) to ~ so it works even if ~/Dotfiles is unmounted.
cp ~/Dotfiles/apply-theme.sh ~/apply-theme.sh
chmod +x ~/apply-theme.sh

# ---------------------------------------------------------------------------
# 16. WallRizz (run manually after login — requires a running desktop session)
# ---------------------------------------------------------------------------
# WallRizz generates a colour scheme from the active wallpaper and applies it
# to EWW, dunst, and terminals.  It requires a live Wayland session and cannot
# be safely run from this installer script.
# Uncomment and run manually after your first login:
# curl -sL "$(curl -s https://api.github.com/repos/5hubham5ingh/WallRizz/releases/latest \
#     | grep -Po '"browser_download_url": "\K[^"]+' | grep WallRizz)" | tar -xz \
#     && sudo mv WallRizz /usr/bin/

log "Hyprland installation complete. Reboot to start."
