#!/bin/bash
# ══════════════════════════════════════════════════════════════════
#  secubox-kiosk-setup — GUI Kiosk Mode Configuration
#  Installs minimal GUI with Chromium kiosk on SecuBox WebUI
#  Supports both X11 (VM-compatible) and Wayland (native) modes
# ══════════════════════════════════════════════════════════════════
set -euo pipefail

KIOSK_USER="secubox-kiosk"
KIOSK_HOME="/home/${KIOSK_USER}"
KIOSK_URL="https://localhost/"
MARKER="/var/lib/secubox/.kiosk-installed"
ENABLED_MARKER="/var/lib/secubox/.kiosk-enabled"
CONSOLE_MARKER="/var/lib/secubox/.console-enabled"
MODE_FILE="/var/lib/secubox/.kiosk-mode"

RED='\033[0;31m'; GREEN='\033[0;32m'; CYAN='\033[0;36m'; NC='\033[0m'
log() { echo -e "${CYAN}[kiosk]${NC} $*"; }
ok()  { echo -e "${GREEN}[  OK  ]${NC} $*"; }
err() { echo -e "${RED}[FAIL ]${NC} $*" >&2; exit 1; }

usage() {
    cat <<EOF
Usage: secubox-kiosk-setup {install|enable|disable|console|no-console|status} [--x11|--wayland]

Commands:
  install     - Install GUI packages for kiosk mode
  enable      - Enable kiosk mode autostart (GUI)
  disable     - Disable kiosk mode (return to console)
  console     - Enable console TUI mode on TTY1
  no-console  - Disable console TUI mode
  status      - Show current mode status

Options:
  --x11      Use X11/startx mode (better VM compatibility)
  --wayland  Use Cage/Wayland mode (native, requires DRM)

Default: X11 mode (recommended for VMs and most hardware)

Modes:
  - GUI Kiosk: Fullscreen Chromium displaying SecuBox WebUI
  - Console TUI: Terminal dashboard with metrics and service management
  - None: Standard console login on TTY1
EOF
    exit 0
}

# Detect if running in VM
detect_vm() {
    local virt
    virt=$(systemd-detect-virt 2>/dev/null || echo "none")
    if [[ "$virt" != "none" ]]; then
        echo "vm"
    else
        echo "bare"
    fi
}

# Get current mode (default: x11)
get_mode() {
    if [[ -f "$MODE_FILE" ]]; then
        cat "$MODE_FILE"
    else
        echo "x11"
    fi
}

# ── Install Minimal GUI Packages ────────────────────────────────────
install_kiosk() {
    local mode="${1:-x11}"
    log "Installing kiosk mode packages (${mode})..."

    # Check if already installed
    if [[ -f "$MARKER" ]]; then
        log "Kiosk packages already installed"
        # Still ensure user and scripts exist
        setup_kiosk_user "$mode"
        return 0
    fi

    apt-get update -qq

    # Common packages
    local common_pkgs="chromium fonts-dejavu-core libinput10 xdg-utils"

    if [[ "$mode" == "wayland" ]]; then
        # Wayland packages (Cage compositor)
        apt-get install -y --no-install-recommends \
            cage \
            $common_pkgs \
            libegl1 libgles2 libgbm1 libdrm2 \
            mesa-utils \
            || err "Failed to install Wayland kiosk packages"
    else
        # X11 packages (xinit + window manager)
        apt-get install -y --no-install-recommends \
            xorg xinit x11-xserver-utils \
            $common_pkgs \
            unclutter \
            || err "Failed to install X11 kiosk packages"

        # Allow non-console users to start X server (required for systemd service)
        mkdir -p /etc/X11
        cat > /etc/X11/Xwrapper.config <<'XWRAP'
allowed_users=anybody
needs_root_rights=yes
XWRAP
    fi

    # Setup user and scripts
    setup_kiosk_user "$mode"

    # Mark as installed
    mkdir -p /var/lib/secubox
    echo "installed=$(date -Iseconds)" > "$MARKER"
    echo "$mode" > "$MODE_FILE"

    ok "Kiosk mode installed (${mode})"
    log "Run 'secubox-kiosk-setup enable' to activate"
}

# ── Setup Kiosk User and Scripts ────────────────────────────────────
setup_kiosk_user() {
    local mode="${1:-x11}"

    # Create kiosk user with UID 1000 if not exists
    if ! id "$KIOSK_USER" &>/dev/null; then
        # Use UID 1000 to match XDG_RUNTIME_DIR in service file
        useradd -r -u 1000 -m -d "$KIOSK_HOME" -s /bin/bash \
            -G video,audio,input,render "$KIOSK_USER" 2>/dev/null || \
        useradd -r -m -d "$KIOSK_HOME" -s /bin/bash \
            -G video,audio,input,render "$KIOSK_USER"
        ok "Created kiosk user: $KIOSK_USER"
    fi

    # Le lanceur ouvre la session par `su -l` : un compte en nologin repond
    # « This account is currently not available » (#2506). Repare aussi les
    # comptes crees avant ce correctif.
    if [[ "$(getent passwd "$KIOSK_USER" | cut -d: -f7)" == */nologin ]]; then
        usermod -s /bin/bash "$KIOSK_USER"
        ok "Shell of $KIOSK_USER set to /bin/bash"
    fi

    # Get actual UID
    local KIOSK_UID
    KIOSK_UID=$(id -u "$KIOSK_USER")

    # Create kiosk scripts directory
    mkdir -p "${KIOSK_HOME}/.config"

    if [[ "$mode" == "wayland" ]]; then
        # Create Wayland start script
        create_wayland_script
    else
        # Create X11 .xinitrc
        create_x11_xinitrc
    fi

    chown -R "$KIOSK_USER":"$KIOSK_USER" "$KIOSK_HOME"

    # Update systemd service with correct UID
    update_service_file "$KIOSK_UID" "$mode"
}

# ── Create Wayland Start Script ─────────────────────────────────────
create_wayland_script() {
    cat > "${KIOSK_HOME}/start-kiosk.sh" <<'KIOSK'
#!/bin/bash
# SecuBox Kiosk Launcher (Wayland)
# Note: secubox-kiosk-launcher already waits for services before starting

# URL from environment (set by launcher) or fallback
URL="${KIOSK_URL:-https://localhost/}"

# Log startup
logger -t secubox-kiosk "Starting Chromium Wayland kiosk: $URL"

# Chromium flags for kiosk mode (native Wayland via Ozone)
CHROMIUM_FLAGS=(
    --ozone-platform=wayland
    --kiosk
    --no-first-run
    --no-sandbox
    --disable-gpu-sandbox
    --disable-translate
    --disable-infobars
    --disable-session-crashed-bubble
    --disable-restore-background-contents
    --disable-sync
    --disable-features=TranslateUI
    --ignore-certificate-errors
    --noerrdialogs
    --enable-features=OverlayScrollbar
    --start-fullscreen
    --window-position=0,0
    --check-for-update-interval=604800
    --disable-component-update
    --disable-default-apps
    --disable-extensions
    --disable-background-networking
    --disable-domain-reliability
    --disable-client-side-phishing-detection
    "$URL"
)

exec chromium "${CHROMIUM_FLAGS[@]}"
KIOSK
    chmod +x "${KIOSK_HOME}/start-kiosk.sh"
}

# ── Create X11 .xinitrc ─────────────────────────────────────────────
create_x11_xinitrc() {
    cat > "${KIOSK_HOME}/.xinitrc" <<'XINITRC'
#!/bin/bash
# SecuBox Kiosk X11 Launcher
# Note: secubox-kiosk-launcher already waits for services before starting

# URL from environment (set by launcher) or fallback
URL="${KIOSK_URL:-https://localhost/}"

# Log startup
logger -t secubox-kiosk "Starting Chromium X11 kiosk: $URL"

# Disable screen blanking (ignore errors on headless)
xset s off 2>/dev/null || true
xset -dpms 2>/dev/null || true
xset s noblank 2>/dev/null || true

# Hide cursor after 3 seconds of inactivity
if command -v unclutter &>/dev/null; then
    unclutter -idle 3 -root &
fi

# Set background to black
xsetroot -solid black 2>/dev/null || true

# Chromium flags for kiosk mode (X11)
CHROMIUM_FLAGS=(
    --kiosk
    --no-first-run
    --no-sandbox
    --disable-gpu-sandbox
    --disable-translate
    --disable-infobars
    --disable-session-crashed-bubble
    --disable-restore-background-contents
    --disable-sync
    --disable-features=TranslateUI
    --ignore-certificate-errors
    --noerrdialogs
    --enable-features=OverlayScrollbar
    --start-fullscreen
    --window-position=0,0
    --check-for-update-interval=604800
    --disable-component-update
    --disable-default-apps
    --disable-extensions
    --disable-background-networking
    --disable-domain-reliability
    --disable-client-side-phishing-detection
    "$URL"
)

# Run Chromium - exec replaces shell process
exec chromium "${CHROMIUM_FLAGS[@]}"
XINITRC
    chmod +x "${KIOSK_HOME}/.xinitrc"
}

# ── Setup Root Autologin on TTY2 ─────────────────────────────────
setup_root_autologin_tty2() {
    # Create autologin override for tty2
    mkdir -p /etc/systemd/system/getty@tty2.service.d
    cat > /etc/systemd/system/getty@tty2.service.d/autologin.conf <<EOF
[Service]
ExecStart=
ExecStart=-/sbin/agetty --autologin root --noclear %I \$TERM
Type=idle
EOF

    # Enable getty on tty2
    systemctl enable getty@tty2.service 2>/dev/null || true
    systemctl start getty@tty2.service 2>/dev/null || true

    log "Root autologin enabled on tty2 (Ctrl+Alt+F2 to access)"
}

# ── Update Service File (using launcher script) ─────────────────────────
update_service_file() {
    local KIOSK_UID="${1:-1000}"
    local mode="${2:-x11}"

    # Use the robust launcher script that handles:
    # - Dynamic UID detection (no hardcoded values)
    # - Proper dependency waiting (nginx, network, dummy0)
    # - User creation if needed
    # - Fallback URL handling
    # - VT setup without race conditions

    cat > /etc/systemd/system/secubox-kiosk.service <<EOF
[Unit]
Description=SecuBox Kiosk Mode (${mode})
Documentation=https://secubox.in/docs/kiosk

# Proper dependency chain
After=systemd-user-sessions.service
After=plymouth-quit-wait.service
After=network-online.target
After=nginx.service
After=systemd-networkd.service
After=secubox-firstboot.service

Wants=network-online.target
Wants=nginx.service
Conflicts=getty@tty1.service
PartOf=graphical.target

[Service]
Type=simple

# Check if kiosk is enabled
ExecStartPre=+/bin/sh -c '[ -f /var/lib/secubox/.kiosk-enabled ] || exit 1'

# Use launcher script (handles all setup internally)
ExecStart=/usr/sbin/secubox-kiosk-launcher ${mode} 7

Restart=on-failure
RestartSec=10
StartLimitInterval=300
StartLimitBurst=5
TimeoutStartSec=180
TimeoutStopSec=30

MemoryMax=1G
TasksMax=200

StandardOutput=journal
StandardError=journal
SyslogIdentifier=secubox-kiosk

[Install]
WantedBy=graphical.target
EOF

    systemctl daemon-reload
    log "Service file updated (mode: ${mode}, using launcher)"
}

# ── Enable Kiosk Mode ─────────────────────────────────────────────
enable_kiosk() {
    local mode="${1:-$(get_mode)}"

    # Check if packages are installed
    if [[ "$mode" == "wayland" ]]; then
        if ! command -v cage >/dev/null 2>&1; then
            log "Wayland packages not installed, installing..."
            install_kiosk wayland
        fi
    else
        if ! command -v startx >/dev/null 2>&1; then
            log "X11 packages not installed, installing..."
            install_kiosk x11
        fi
    fi

    # Ensure user exists and scripts are in place
    setup_kiosk_user "$mode"

    log "Enabling kiosk mode (${mode})..."

    # Create enabled marker
    mkdir -p /var/lib/secubox
    touch "${ENABLED_MARKER}"
    echo "$mode" > "$MODE_FILE"

    # Setup root autologin on tty2 (so user can still access console)
    setup_root_autologin_tty2

    # Disable getty on tty1 (kiosk uses it)
    systemctl disable getty@tty1.service 2>/dev/null || true

    # Enable graphical target
    systemctl set-default graphical.target

    # Enable kiosk service
    systemctl enable secubox-kiosk.service

    # Start kiosk in the background so this caller doesn't block. The
    # service has Conflicts=getty@tty7.service + TTYPath=/dev/tty7 and
    # systemd will sometimes wait for /dev/tty7 to release / sync up,
    # which deadlocks a synchronous `systemctl start` invoked from
    # firstboot.sh (firstboot runs from inside the autologin shell on
    # tty1 itself — observed live USB hang where kiosk-setup ran for
    # 5+ minutes and the service stayed `inactive (dead)`).
    systemctl --no-block start secubox-kiosk.service \
        || log "Kiosk will start on next boot"

    ok "Kiosk mode enabled (${mode})"
    log "SecuBox WebUI will display on the connected screen"
}

# ── Disable Kiosk Mode ────────────────────────────────────────────
disable_kiosk() {
    log "Disabling kiosk mode..."

    # Remove enabled marker
    rm -f "${ENABLED_MARKER}"

    # Stop and disable kiosk service
    systemctl stop secubox-kiosk.service 2>/dev/null || true
    systemctl disable secubox-kiosk.service 2>/dev/null || true

    # Return to multi-user (console) target
    systemctl set-default multi-user.target

    # Re-enable console login
    systemctl enable getty@tty1.service 2>/dev/null || true

    ok "Kiosk mode disabled"
    log "System will boot to console"
}

# ── Enable Console TUI Mode ──────────────────────────────────────
enable_console() {
    log "Enabling console TUI mode..."

    # Disable GUI kiosk if active
    if [[ -f "$ENABLED_MARKER" ]]; then
        log "Disabling GUI kiosk mode first..."
        disable_kiosk
    fi

    # Check if secubox-console package is installed
    if ! command -v secubox-console >/dev/null 2>&1; then
        log "Installing secubox-console package..."
        apt-get update -qq
        apt-get install -y secubox-console || err "Failed to install secubox-console"
    fi

    # Create console enabled marker
    mkdir -p /var/lib/secubox
    touch "${CONSOLE_MARKER}"
    echo "console" > "$MODE_FILE"

    # Disable getty on tty1 (console TUI uses it)
    systemctl disable getty@tty1.service 2>/dev/null || true

    # Enable console TUI service
    systemctl enable secubox-console.service 2>/dev/null || true

    # Setup root autologin on tty2 for emergency access
    setup_root_autologin_tty2

    # Start console TUI
    systemctl start secubox-console.service || log "Console TUI will start on next boot"

    ok "Console TUI mode enabled"
    log "SecuBox console dashboard will display on TTY1"
    log "Root console access available on TTY2 (Ctrl+Alt+F2)"
}

# ── Disable Console TUI Mode ─────────────────────────────────────
disable_console() {
    log "Disabling console TUI mode..."

    # Remove console marker
    rm -f "${CONSOLE_MARKER}"

    # Stop and disable console service
    systemctl stop secubox-console.service 2>/dev/null || true
    systemctl disable secubox-console.service 2>/dev/null || true

    # Re-enable console login on tty1
    systemctl enable getty@tty1.service 2>/dev/null || true

    ok "Console TUI mode disabled"
    log "Standard console login restored on TTY1"
}

# ── Show Status ──────────────────────────────────────────────────
show_status() {
    echo ""
    echo "SecuBox Display Mode Status"
    echo "==========================="

    # Determine current mode
    local current_mode="none"
    if [[ -f "$ENABLED_MARKER" ]]; then
        current_mode="kiosk"
    elif [[ -f "$CONSOLE_MARKER" ]]; then
        current_mode="console"
    fi

    echo "Current Mode: $current_mode"

    # Kiosk status
    echo ""
    echo "GUI Kiosk:"
    if [[ -f "$MARKER" ]]; then
        echo "  Installed: yes"
    else
        echo "  Installed: no"
    fi

    local kiosk_mode="x11"
    if [[ -f "$MODE_FILE" ]]; then
        kiosk_mode=$(cat "$MODE_FILE")
    fi

    if [[ -f "$ENABLED_MARKER" ]]; then
        echo "  Enabled: yes ($kiosk_mode)"
    else
        echo "  Enabled: no"
    fi

    local kiosk_active="inactive"
    if systemctl is-active secubox-kiosk.service &>/dev/null; then
        kiosk_active="active"
    fi
    echo "  Service: $kiosk_active"

    # Console TUI status
    echo ""
    echo "Console TUI:"
    if command -v secubox-console >/dev/null 2>&1; then
        echo "  Installed: yes"
    else
        echo "  Installed: no"
    fi

    if [[ -f "$CONSOLE_MARKER" ]]; then
        echo "  Enabled: yes"
    else
        echo "  Enabled: no"
    fi

    local console_active="inactive"
    if systemctl is-active secubox-console.service &>/dev/null; then
        console_active="active"
    fi
    echo "  Service: $console_active"

    # System info
    echo ""
    echo "System:"
    local default_target
    default_target=$(systemctl get-default)
    echo "  Default target: $default_target"

    local platform
    platform=$(detect_vm)
    echo "  Platform: $platform"

    # State summary
    echo ""
    if [[ "$kiosk_active" == "active" ]]; then
        echo "State: KIOSK (GUI on TTY7)"
    elif [[ "$console_active" == "active" ]]; then
        echo "State: CONSOLE TUI (TTY1)"
    else
        echo "State: CONSOLE LOGIN (TTY1)"
    fi

    # Check tty2 autologin
    if [[ -f /etc/systemd/system/getty@tty2.service.d/autologin.conf ]]; then
        echo "Emergency: TTY2 (Ctrl+Alt+F2)"
    fi

    echo ""
}

# ── Main ────────────────────────────────────────────────────────
MODE=""
CMD=""

# Parse arguments
while [[ $# -gt 0 ]]; do
    case "$1" in
        install|enable|disable|console|no-console|status)
            CMD="$1"
            shift
            ;;
        --x11)
            MODE="x11"
            shift
            ;;
        --wayland)
            MODE="wayland"
            shift
            ;;
        -h|--help|help)
            usage
            ;;
        *)
            usage
            ;;
    esac
done

# Default mode: x11 (more compatible)
if [[ -z "$MODE" ]]; then
    MODE="x11"
fi

case "${CMD:-}" in
    install)
        install_kiosk "$MODE"
        ;;
    enable)
        enable_kiosk "$MODE"
        ;;
    disable)
        disable_kiosk
        ;;
    console)
        enable_console
        ;;
    no-console)
        disable_console
        ;;
    status)
        show_status
        ;;
    *)
        usage
        ;;
esac
