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

# collect-logs
# 收集系统信息与日志，打包为 tar.zstd 到桌面目录
# 目标输出: $DESKTOP/catos-logs-YYYYmmdd_HHMMSS.tar.zstd

TMPDIR="$(mktemp -d /tmp/collect-logs.XXXXXX)"
OUTNAME="catos-logs-$(date +%Y%m%d_%H%M%S).tar.zstd"

# Optional: accept a target username as first argument. When run via pkexec,
# this lets the script place the archive on the invoking user's Desktop and
# fix ownership so the file isn't owned by root.
TARGET_USER="${1:-}"

get_home_for_user() {
    local u="$1"
    local home
    home=$(getent passwd "$u" | cut -d: -f6 2>/dev/null || true)
    if [ -z "$home" ]; then
        home="/home/$u"
    fi
    echo "$home"
}

get_desktop() {
    if command -v xdg-user-dir >/dev/null 2>&1; then
        local d
        d=$(xdg-user-dir DESKTOP 2>/dev/null || true)
        [ -n "$d" ] && echo "$d" && return
    fi
    echo "$HOME/Desktop"
}

if [ -n "$TARGET_USER" ]; then
    HOME_DIR="$(get_home_for_user "$TARGET_USER")"
    DESKTOP="$HOME_DIR/Desktop"
    mkdir -p "$DESKTOP"
else
    DESKTOP="$(get_desktop)"
    mkdir -p "$DESKTOP"
fi

cleanup() {
    rm -rf "$TMPDIR"
}
trap cleanup EXIT

log() { printf "[collect-logs] %s\n" "$*" >&2; }

try_cmd() {
    local outfile="$1"; shift
    if "$@" >"$TMPDIR/$outfile" 2>&1; then
        log "OK: $* -> $outfile"
        return 0
    fi
    if command -v sudo >/dev/null 2>&1; then
        log "Retrying with sudo: $*"
        if sudo "$@" >"$TMPDIR/$outfile" 2>&1; then
            log "OK(sudo): $* -> $outfile"
            return 0
        fi
    fi
    log "FAILED: $* (see $TMPDIR/$outfile)"
    return 1
}

log "Creating temporary workspace: $TMPDIR"
log "TARGET_USER: ${TARGET_USER:-<none>}"

try_cmd uname.txt uname -a || true
try_cmd os-release.txt cat /etc/os-release || true
try_cmd lsb-release.txt lsb_release -a || true
try_cmd inxi.txt inxi -F || true
try_cmd lshw.txt lshw -short || true
try_cmd lsblk.txt lsblk -f || true
try_cmd df.txt df -h || true
try_cmd free.txt free -h || true
try_cmd dmesg.txt dmesg || true
try_cmd lsmod.txt lsmod || true
try_cmd modules.txt cat /proc/modules || true
try_cmd kernel-config.txt zcat /proc/config.gz || true
try_cmd mount.txt mount || true
try_cmd systemctl-units.txt systemctl list-units --no-pager || true
try_cmd pacman-explicit.txt pacman -Qe || true
try_cmd pacman-all.txt pacman -Q || true
try_cmd journalctl.txt journalctl -b --no-pager || true

# Do NOT copy entire /var/log (can be very large). Collect only specific small log files if present.
# Collect pacman log and calamares cache if available (try sudo if needed)
try_cmd pacman.log cat /var/log/pacman.log || true

if [ -d /root/.cache/calamares ]; then
    if cp -r /root/.cache/calamares "$TMPDIR/" 2>/dev/null; then
        log "Copied calamares cache"
    elif command -v sudo >/dev/null 2>&1; then
        sudo cp -r /root/.cache/calamares "$TMPDIR/" || log "failed to copy calamares cache"
    fi
fi

# Create a manifest of collected files
(
    echo "Collected on: $(date -u)";
    echo "Host: $(uname -n)";
    echo "User: $(whoami)";
    echo "Included files:";
    find . -maxdepth 3 -type f | sed 's|^\./||' || true;
) > "$TMPDIR/MANIFEST.txt"

pushd "$TMPDIR" >/dev/null
if command -v zstd >/dev/null 2>&1; then
    tar -cf - . | zstd -T0 -q -o "$DESKTOP/$OUTNAME"
    TARRC=$?
    if [ $TARRC -eq 0 ]; then
        log "Archive created: $DESKTOP/$OUTNAME"
    else
        log "zstd archive failed (exit $TARRC)"
    fi
else
    ALTNAME="${OUTNAME%.zstd}.tar.gz"
    tar -czf "$DESKTOP/$ALTNAME" .
    log "zstd not found; created gzip archive: $DESKTOP/$ALTNAME"
fi
    # If a target user was specified, ensure the created archive is owned by that user.
    if [ -n "$TARGET_USER" ]; then
        if [ -e "$DESKTOP/$OUTNAME" ]; then
            chown "$TARGET_USER":"$TARGET_USER" "$DESKTOP/$OUTNAME" 2>/dev/null || log "chown failed for $DESKTOP/$OUTNAME"
        else
            ALT="${OUTNAME%.zstd}.tar.gz"
            if [ -e "$DESKTOP/$ALT" ]; then
                chown "$TARGET_USER":"$TARGET_USER" "$DESKTOP/$ALT" 2>/dev/null || log "chown failed for $DESKTOP/$ALT"
            fi
        fi
    fi

popd >/dev/null

log "Done. The archive is on the Desktop (if creation succeeded)."

exit 0
