#!/bin/bash
# 飞鸽传书 Linux 启动器（随 deb 安装到 /usr/local/bin/feige；龙芯包同样走这里）
# 与 trunk/main.cpp 分层 hygiene 对齐；用户安装后点图标即可，无需手工命令。
# 龙芯 3A5000/3A6000 + 麒麟 V10/国防版（内核 5.4）：须在 exec 之前关掉 LASX。
# main() 对已加载的 glibc ifunc 来不及；本脚本与 main 内 re-exec 双保险。

ARCH="$(uname -m 2>/dev/null || echo unknown)"

apply_xcb() {
  export QT_QPA_PLATFORM=xcb
  unset WAYLAND_DISPLAY
  # 清易诱导 Wayland QPA 的残留（保留系统 XDG_RUNTIME_DIR）
  unset QT_WAYLAND_SHELL_INTEGRATION
  unset QT_WAYLAND_FORCE_DPI
  unset QT_WAYLAND_DISABLE_WINDOWDECORATION
  unset QT_WAYLAND_RECONNECT
  if [ "${XDG_SESSION_TYPE}" = "wayland" ]; then
    export XDG_SESSION_TYPE=x11
  fi
}

apply_soft_gl() {
  export QT_OPENGL=software
  export LIBGL_ALWAYS_SOFTWARE=1
  export QT_XCB_GL_INTEGRATION=none
}

is_wayland_session() {
  [ "${XDG_SESSION_TYPE}" = "wayland" ] && return 0
  case "${QT_QPA_PLATFORM}" in
    *wayland*) return 0 ;;
  esac
  [ -n "${WAYLAND_DISPLAY}" ] && return 0
  return 1
}

is_uos_like() {
  [ -r /etc/os-release ] || return 1
  grep -qiE 'uos|deepin|uniontech|kylin' /etc/os-release 2>/dev/null
}

maybe_private_xdg() {
  if [ "${FEIGE_PRIVATE_XDG_RUNTIME}" = "1" ] || [ "${FEIGE_PRIVATE_XDG_RUNTIME}" = "true" ]; then
    export XDG_RUNTIME_DIR="/tmp/runtime-feige-$(id -u)"
    mkdir -p "$XDG_RUNTIME_DIR"
    chmod 700 "$XDG_RUNTIME_DIR" 2>/dev/null || true
  fi
}

# 内核主版本 < 6（麒麟 V10/国防版常见 5.4.18）时，3A5000/3A6000 的 LASX 上下文切换不完整。
# glibc 按 HWCAP 选中 LASX 版 memcpy 后，会把整个图形会话打回登录页。
# GLIBC_TUNABLES 必须在动态链接器启动前就位，所以放在本脚本（main 内仅作 re-exec 兜底）。
#
# 龙芯 glibc（含麒麟/打包 AppImage 内嵌）的 hwcaps 语法与 x86 不同：
#   只接受正值 UAL / LSX / LASX；未列出的特性会被 &= 关掉。
#   禁止写 -LASX（x86 关特性写法）——会直接 fatal：
#   "The valid values of glibc.cpu.hwcaps is UAL, LASX, LSX!!"
# 正确关 LASX：glibc.cpu.hwcaps=LSX,UAL
apply_loongarch_old_kernel_lasx_guard() {
  case "$ARCH" in
    loongarch64|loongarch*|loong64) ;;
    *) return 0 ;;
  esac
  if [ "${FEIGE_LASX}" = "1" ] || [ "${FEIGE_LASX}" = "true" ]; then
    return 0
  fi
  rel=$(uname -r 2>/dev/null || echo 0)
  major=$(printf '%s' "$rel" | cut -d. -f1)
  case "$major" in
    ''|*[!0-9]*) major=0 ;;
  esac
  if [ "$major" -ge 6 ]; then
    return 0
  fi
  # 旧内核一律强制关 LASX：清掉既有（可能错误的）hwcaps 后再写入 LSX,UAL。
  # 需要保留 LASX 时设 FEIGE_LASX=1。
  _feige_hwcaps='glibc.cpu.hwcaps=LSX,UAL'
  _feige_cleaned=""
  _feige_old_ifs=$IFS
  IFS=':'
  # shellcheck disable=SC2086
  for _feige_part in ${GLIBC_TUNABLES-}; do
    case "${_feige_part}" in
      ''|glibc.cpu.hwcaps=*) continue ;;
    esac
    if [ -n "${_feige_cleaned}" ]; then
      _feige_cleaned="${_feige_cleaned}:${_feige_part}"
    else
      _feige_cleaned="${_feige_part}"
    fi
  done
  IFS=$_feige_old_ifs
  if [ -n "${_feige_cleaned}" ]; then
    export GLIBC_TUNABLES="${_feige_cleaned}:${_feige_hwcaps}"
  else
    export GLIBC_TUNABLES="${_feige_hwcaps}"
  fi
  unset _feige_hwcaps _feige_cleaned _feige_old_ifs _feige_part
}

case "$ARCH" in
  aarch64|arm64|armv7l|armv7*|armv8*)
    # 海思 Kirin 等：全量强制 xcb + 软 GL（会话常注入 wayland）
    apply_xcb
    apply_soft_gl
    maybe_private_xdg
    ;;
  loongarch64|loongarch*|loong64|mips64|mips64el|mips*)
    # 龙芯 / MIPS：默认硬件 GL。软光栅只在显式 FEIGE_SOFT_GL=1 时打开。
    # Wayland 只切 xcb，不再套 llvmpipe（3A6000 + 麒麟 5.4 上会打满内存并注销会话）。
    if [ "${FEIGE_SOFT_GL}" = "1" ] || [ "${FEIGE_SOFT_GL}" = "true" ]; then
      apply_soft_gl
    fi
    if is_wayland_session; then
      apply_xcb
    fi
    maybe_private_xdg
    ;;
  sw_64|sw64|riscv64|riscv*)
    # 申威 / RISC-V：统信麒麟默认软 GL；Wayland 切 xcb
    if is_uos_like; then
      apply_soft_gl
    fi
    if is_wayland_session; then
      apply_xcb
      apply_soft_gl
    fi
    maybe_private_xdg
    ;;
  x86_64|amd64|i386|i686)
    # x86：仅统信/麒麟 + Wayland 时切 xcb；统信麒麟默认软 GL 更稳
    if is_uos_like; then
      apply_soft_gl
      if is_wayland_session; then
        apply_xcb
      fi
    elif is_wayland_session; then
      apply_xcb
    fi
    maybe_private_xdg
    ;;
  *)
    if is_wayland_session; then
      apply_xcb
      apply_soft_gl
    fi
    maybe_private_xdg
    ;;
esac

# 日志目录由 main.cpp 负责轮转（feige-logs.txt → feige-logs-bak.txt 后新建）；
# 此处只保证目录存在，并用环境变量标记走了本启动器（指纹里 viaLauncher=1）
LOG_DIR="${HOME}/.local/share/feige"
if [ -n "${HOME}" ]; then
  mkdir -p "${LOG_DIR}" 2>/dev/null || true
fi
export FEIGE_VIA_LAUNCHER=1
apply_loongarch_old_kernel_lasx_guard

APPIMAGE="/usr/local/lib/feige/feige.AppImage"
if [ ! -x "$APPIMAGE" ]; then
  if [ -x "/usr/share/feige/Feige" ]; then
    APPIMAGE="/usr/share/feige/Feige"
  elif [ -x "/usr/local/bin/feige.bin" ]; then
    APPIMAGE="/usr/local/bin/feige.bin"
  else
    echo "飞鸽传书：找不到程序文件 /usr/local/lib/feige/feige.AppImage" >&2
    exit 1
  fi
fi
# 国防包直跑 /usr/share/feige/Feige 时，包内 HarfBuzz 必须先于系统库。
# 麒麟 4.0.2 的 libharfbuzz 1.0.x 没有 hb_font_funcs_set_font_h_extents_func。
if [ "$APPIMAGE" = "/usr/share/feige/Feige" ] && [ -d /usr/share/feige/lib ]; then
  export LD_LIBRARY_PATH="/usr/share/feige/lib${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}"
fi
exec "$APPIMAGE" "$@"
