#!/usr/bin/env bash
set -e

# 依赖包列表（已去掉 libgtk-3-0，避免与 24.04+ 的 libgtk-3-0t64 冲突）
REQUIRED_PACKAGES=(
  "libwebkit2gtk-4.0-37"
  "libayatana-appindicator3-1"
  "openssl"
)

JAMMY_SOURCE_FILE="/etc/apt/sources.list.d/jammy-webkit.list"
JAMMY_PREF_FILE="/etc/apt/preferences.d/webkit-jammy.pref"

DISTRO_ID=""
DISTRO_NAME=""
DISTRO_VERSION_ID=""
DISTRO_CODENAME=""

BASE_ID=""
BASE_NAME=""
BASE_VERSION_ID=""
BASE_VERSION_MAJOR=""
BASE_CODENAME=""

UBUNTU_ARCH=""

#####################################
# 通用函数
#####################################

log(){ echo -e "[INFO] $*"; }
warn(){ echo -e "[WARN] $*" >&2; }
error_exit(){ echo -e "[ERROR] $*" >&2; exit 1; }

check_root(){
  if [ "${EUID:-$(id -u)}" -ne 0 ]; then
    error_exit "请使用 root 权限运行（例如：sudo $0）"
  fi
}

need_cmd(){
  command -v "$1" >/dev/null 2>&1 || error_exit "缺少命令：$1，请先安装它"
}

backup_if_exists(){
  local f="$1"
  if [ -f "$f" ]; then
    local ts
    ts="$(date +%Y%m%d-%H%M%S)"
    cp -a "$f" "${f}.bak.${ts}"
    log "已备份：$f -> ${f}.bak.${ts}"
  fi
}

#####################################
# 识别 Ubuntu / Mint（以及其它 Ubuntu 系）
#####################################

detect_distro_and_base(){
  if [ ! -r /etc/os-release ]; then
    error_exit "无法读取 /etc/os-release，无法检测系统信息"
  fi

  # shellcheck source=/dev/null
  . /etc/os-release

  DISTRO_ID="${ID:-unknown}"
  DISTRO_NAME="${NAME:-unknown}"
  DISTRO_VERSION_ID="${VERSION_ID:-unknown}"
  DISTRO_CODENAME="${VERSION_CODENAME:-}"

  UBUNTU_ARCH="$(dpkg --print-architecture 2>/dev/null || echo unknown)"

  # 关键：尽可能拿到“Ubuntu 基础”的 codename / version
  # Linux Mint 的 /etc/os-release 往往含 UBUNTU_CODENAME / UBUNTU_VERSION_ID
  if [ "${DISTRO_ID}" = "linuxmint" ] || echo "${DISTRO_NAME}" | grep -qi "linux mint"; then
    BASE_ID="ubuntu"
    BASE_NAME="Ubuntu(base for Linux Mint)"
    BASE_CODENAME="${UBUNTU_CODENAME:-}"
    BASE_VERSION_ID="${UBUNTU_VERSION_ID:-}"

    # 兜底：如果 mint 没给 UBUNTU_CODENAME，就用自身 codename（不保证可用）
    if [ -z "${BASE_CODENAME}" ]; then
      BASE_CODENAME="${DISTRO_CODENAME:-}"
    fi
  else
    # Ubuntu / 其它 Ubuntu 系（Pop!_OS 等多数也会提供 UBUNTU_CODENAME）
    if [ -n "${UBUNTU_CODENAME:-}" ]; then
      BASE_CODENAME="${UBUNTU_CODENAME}"
    else
      BASE_CODENAME="${DISTRO_CODENAME}"
    fi

    BASE_ID="${DISTRO_ID}"
    BASE_NAME="${DISTRO_NAME}"
    BASE_VERSION_ID="${DISTRO_VERSION_ID}"
  fi

  if [ -n "${BASE_VERSION_ID}" ]; then
    BASE_VERSION_MAJOR="$(echo "${BASE_VERSION_ID}" | cut -d'.' -f1 | tr -cd '0-9')"
  else
    BASE_VERSION_MAJOR=""
  fi

  log "检测到发行版：${DISTRO_NAME} (${DISTRO_ID}) ${DISTRO_VERSION_ID} codename=${DISTRO_CODENAME:-N/A}"
  log "Ubuntu 基础信息：codename=${BASE_CODENAME:-N/A} version=${BASE_VERSION_ID:-N/A} (arch=${UBUNTU_ARCH})"

  if [ -z "${BASE_CODENAME}" ] && [ -z "${BASE_VERSION_MAJOR}" ]; then
    error_exit "无法识别 Ubuntu 基础代号/版本（BASE_CODENAME/BASE_VERSION），请检查 /etc/os-release 内容"
  fi
}

#####################################
# jammy 源 & pin
#####################################

write_jammy_sources(){
  log "写入 jammy 仓库源：${JAMMY_SOURCE_FILE}"
  backup_if_exists "${JAMMY_SOURCE_FILE}"

  if [ "${UBUNTU_ARCH}" = "amd64" ]; then
    cat > "${JAMMY_SOURCE_FILE}" << "EOF"
deb http://archive.ubuntu.com/ubuntu jammy main universe
deb http://archive.ubuntu.com/ubuntu jammy-updates main universe
deb http://security.ubuntu.com/ubuntu jammy-security main universe
EOF
  else
    cat > "${JAMMY_SOURCE_FILE}" << "EOF"
deb http://ports.ubuntu.com/ubuntu-ports jammy main universe
deb http://ports.ubuntu.com/ubuntu-ports jammy-updates main universe
deb http://ports.ubuntu.com/ubuntu-ports jammy-security main universe
EOF
  fi
}

write_jammy_pinning() {
  log "写入 apt 优先级策略：仅提升 libwebkit2gtk-4.0-37"
  backup_if_exists "${JAMMY_PREF_FILE}"

  cat > "${JAMMY_PREF_FILE}" << "EOF"
Package: *
Pin: release n=jammy
Pin-Priority: 100

Package: libwebkit2gtk-4.0-37
Pin: release n=jammy
Pin-Priority: 600
EOF
}

#####################################
# 自动修复 broken 相关
#####################################

fix_existing_broken_if_any(){
  local audit_output
  audit_output="$(dpkg --audit 2>/dev/null || true)"

  if [ -n "${audit_output}" ]; then
    warn "检测到系统存在未完成的安装（broken packages），尝试先自动修复..."
    echo "${audit_output}"
    apt_fix_broken
  else
    log "未发现已有 broken 状态，继续安装流程。"
  fi
}

apt_fix_broken(){
  export DEBIAN_FRONTEND=noninteractive
  log "执行：apt-get -y -f install（自动修复依赖）..."
  if ! apt-get -y -f install; then
    error_exit "自动修复依赖失败，请手动运行 'sudo apt -f install' 检查系统状态。"
  fi
}

apt_install(){
  export DEBIAN_FRONTEND=noninteractive

  log "安装软件包：$*"
  if ! apt-get install -y "$@"; then
    warn "apt-get install 失败，尝试自动修复依赖后重试..."
    apt_fix_broken
    log "依赖已修复，重新尝试安装：$*"
    if ! apt-get install -y "$@"; then
      error_exit "修复依赖后仍无法安装：$*，请手动检查依赖冲突。"
    fi
  fi
}

#####################################
# 安装流程
#####################################

install_with_jammy(){
  write_jammy_sources
  write_jammy_pinning

  apt-get update
  apt_install "${REQUIRED_PACKAGES[@]}"

  log "安装完成，验证 libwebkit2gtk-4.0-37："
  apt-cache policy libwebkit2gtk-4.0-37 || true
}

install_native(){
  log "从本机仓库安装：${REQUIRED_PACKAGES[*]}"
  apt-get update
  apt_install "${REQUIRED_PACKAGES[@]}"
}

#####################################
# 策略选择：根据 Ubuntu 基础代号/主版本
#####################################

should_use_jammy(){
  # 返回 0 表示“需要 jammy 源+pin”
  # 返回 1 表示“直接 native 安装”
  #
  # 规则：
  # - Ubuntu base 为 jammy(22.04) => native
  # - 其它：focal(20.04)、noble(24.04)、oracular(24.10)、以及 25.xx 等 => jammy
  #
  # 用 codename 优先判断；没有 codename 才用主版本号粗略判断

  if [ -n "${BASE_CODENAME}" ]; then
    case "${BASE_CODENAME}" in
      jammy)
        return 1
        ;;
      focal|noble|oracular|lunar|mantic|kinetic|plucky|questing|groovy|hirsute|impish)
        return 0
        ;;
      *)
        # 未知代号：尝试用主版本号判断
        :
        ;;
    esac
  fi

  if [ -n "${BASE_VERSION_MAJOR}" ]; then
    case "${BASE_VERSION_MAJOR}" in
      22)
        return 1
        ;;
      20|21|23|24|25|26)
        return 0
        ;;
      *)
        return 2
        ;;
    esac
  fi

  return 2
}

#####################################
# 主流程
#####################################

main(){
  check_root
  need_cmd dpkg
  need_cmd apt-get

  detect_distro_and_base
  fix_existing_broken_if_any

  if should_use_jammy; then
    log "策略：使用 jammy 源 + pin（只提升 libwebkit2gtk-4.0-37）"
    install_with_jammy
  else
    rc=$?
    if [ "$rc" -eq 1 ]; then
      log "策略：直接使用本机仓库安装（Ubuntu base = jammy/22.04）"
      install_native
    else
      error_exit "无法判断系统策略（base codename=${BASE_CODENAME:-N/A}, base version=${BASE_VERSION_ID:-N/A}）。请把 /etc/os-release 内容发我。"
    fi
  fi
}

main "$@"
