#!/usr/bin/env bash
# ============================================================================
# LinuxViet Toolkit — cài đặt một lệnh
#
#   curl -fsSL https://linuxviet.vn/install.sh | bash
#
# Hoặc chạy từ bản đã tải về:
#   git clone <repo> && cd toolkit && bash install.sh
#
# Tham số dòng lệnh:
#   --profile <tên>        chọn sẵn profile
#   --non-interactive, -y  tự đồng ý mọi câu hỏi
#   --dry-run              chỉ in lệnh, không thay đổi hệ thống
#   --skip "<mod ...>"     bỏ qua module (vd "desktop hardware")
#   --list-profiles | --version | --help
# Biến môi trường tương đương: PROFILE, LV_ASSUME_YES, LV_DRY_RUN,
#   LV_SKIP_MODULES, LV_DESKTOP_USER, TOOLKIT_GIT_URL, TOOLKIT_REF.
# ============================================================================
set -euo pipefail

TOOLKIT_REPO_URL="${TOOLKIT_REPO_URL:-https://linuxviet.vn/toolkit.tar.gz}"
TOOLKIT_GIT_URL="${TOOLKIT_GIT_URL:-}"   # đặt để clone qua git thay vì tarball
TOOLKIT_REF="${TOOLKIT_REF:-main}"

# --- Xác định thư mục gốc của toolkit --------------------------------------
# Khi chạy local: dùng thư mục chứa script. Khi chạy qua pipe: tự tải về.
_find_root() {
  local src="${BASH_SOURCE[0]:-}"
  if [ -n "$src" ] && [ -f "$src" ]; then
    local d; d="$(cd "$(dirname "$src")" && pwd)"
    if [ -f "$d/lib/common.sh" ]; then echo "$d"; return 0; fi
  fi
  return 1
}

_bootstrap_download() {
  # Tự tải bộ mã về khi chạy qua `curl | bash`
  local dest="${TMPDIR:-/tmp}/linuxviet-toolkit.$$"
  mkdir -p "$dest"
  echo "[*] Tải LinuxViet Toolkit về $dest ..." >&2
  if [ -n "$TOOLKIT_GIT_URL" ] && command -v git >/dev/null 2>&1; then
    git clone --depth 1 --branch "$TOOLKIT_REF" "$TOOLKIT_GIT_URL" "$dest" >/dev/null 2>&1 \
      || { echo "[x] git clone thất bại: $TOOLKIT_GIT_URL" >&2; exit 1; }
  else
    curl -fsSL "$TOOLKIT_REPO_URL" -o "$dest/toolkit.tar.gz" \
      || { echo "[x] Không tải được $TOOLKIT_REPO_URL" >&2; exit 1; }
    tar xzf "$dest/toolkit.tar.gz" -C "$dest" --strip-components=1 \
      || { echo "[x] Giải nén thất bại" >&2; exit 1; }
  fi
  [ -f "$dest/lib/common.sh" ] || { echo "[x] Gói tải về không hợp lệ (thiếu lib/common.sh)" >&2; exit 1; }
  echo "$dest"
}

ROOT="$(_find_root || true)"
if [ -z "$ROOT" ]; then
  ROOT="$(_bootstrap_download)"
fi
export LV_TOOLKIT_ROOT="$ROOT"

# --- Nạp thư viện và module -------------------------------------------------
# shellcheck source=lib/common.sh
. "$ROOT/lib/common.sh"
# shellcheck source=lib/ui.sh
. "$ROOT/lib/ui.sh"
# shellcheck source=apps/catalog.sh
. "$ROOT/apps/catalog.sh"

for m in "$ROOT"/modules/*.sh; do
  # shellcheck disable=SC1090
  . "$m"
done

# Phiên bản (đọc từ file VERSION)
LV_VERSION="$(cat "$ROOT/VERSION" 2>/dev/null || echo "0.0.0")"

# Module nền tảng chạy TRƯỚC khi cài app theo profile.
LV_MODULES_PRE=(core locale fonts keyboard flathub desktop hardware cloud)
# Module chạy SAU profile: appnames (alias/discovery dựa app đã cài) + welcome + updates.
LV_MODULES_POST=(appnames welcome updates)
# Danh sách đầy đủ (cho --skip và usage)
LV_MODULES=("${LV_MODULES_PRE[@]}" "${LV_MODULES_POST[@]}")

# --- Loader profile (manifest profiles/<tên>.profile) ----------------------
run_profile() {
  local p="$1" h f
  f="$ROOT/profiles/$p.profile"
  [ -f "$f" ] || die "không tìm thấy profile: $p (xem --list-profiles)"
  unset PROFILE_LABEL PROFILE_DESC PROFILE_APPS PROFILE_POST
  # shellcheck disable=SC1090
  . "$f"
  step "Cấu hình profile: ${PROFILE_LABEL:-$p}"
  [ -n "${PROFILE_APPS:-}" ] && install_apps ${PROFILE_APPS}
  for h in ${PROFILE_POST:-}; do
    declare -F "$h" >/dev/null 2>&1 && { "$h" || warn "post-hook lỗi: $h"; }
  done
}

usage() {
  cat <<EOF
LinuxViet Toolkit v${LV_VERSION}
Dùng: bash install.sh [tuỳ chọn]

  --profile <tên>        home office creator education devops business smart-building
  --non-interactive, -y  tự đồng ý mọi câu hỏi
  --dry-run              chỉ in lệnh, không thay đổi hệ thống
  --skip "<mod ...>"     bỏ qua module: ${LV_MODULES[*]}
  --list-profiles        liệt kê profile
  --version, -V          in phiên bản
  --help, -h             trợ giúp
EOF
}

# --- Phân tích tham số dòng lệnh -------------------------------------------
parse_args() {
  while [ "$#" -gt 0 ]; do
    case "$1" in
      --dry-run)              LV_DRY_RUN=1 ;;
      --non-interactive|-y)   LV_ASSUME_YES=1 ;;
      --profile)              shift; PROFILE="${1:-}" ;;
      --profile=*)            PROFILE="${1#*=}" ;;
      --skip)                 shift; LV_SKIP_MODULES="${1:-}" ;;
      --skip=*)               LV_SKIP_MODULES="${1#*=}" ;;
      --list-profiles)        list_profiles; exit 0 ;;
      --version|-V)           echo "LinuxViet Toolkit v${LV_VERSION}"; exit 0 ;;
      --help|-h)              usage; exit 0 ;;
      *) echo "Tham số không hợp lệ: $1" >&2; usage; exit 1 ;;
    esac
    shift
  done
  export LV_DRY_RUN LV_ASSUME_YES LV_SKIP_MODULES PROFILE
}

# --- Luồng chính ------------------------------------------------------------
main() {
  parse_args "$@"
  print_banner
  detect_system
  _lv_init_sudo
  timer_start

  log "LinuxViet Toolkit v${LV_VERSION} · ${LV_OS_NAME} (${LV_ARCH})"
  [ "${LV_DRY_RUN:-0}" = "1" ] && warn "Chế độ DRY-RUN: chỉ in lệnh, không thay đổi hệ thống."
  require_apt

  if [ "$(id -u)" -ne 0 ] && [ -n "$SUDO" ]; then
    log "Sẽ dùng 'sudo' cho các bước cần quyền quản trị."
  fi

  local profile; profile="$(select_profile)"
  ok "Profile đã chọn: ${profile} — $(lv_profile_desc "$profile")"
  echo

  if ! confirm "Bắt đầu cài đặt và cấu hình hệ thống cho profile '${profile}'?"; then
    warn "Đã huỷ theo yêu cầu."; exit 0
  fi

  # 1) Module nền tảng TRƯỚC profile (bỏ qua những module trong LV_SKIP_MODULES)
  local skip="${LV_SKIP_MODULES:-}" m
  _skip() { case " $skip " in *" $1 "*) return 0;; *) return 1;; esac; }
  for m in "${LV_MODULES_PRE[@]}"; do
    _skip "$m" && { log "bỏ qua module: $m"; continue; }
    "module_${m}"
  done

  # 2) Ứng dụng theo profile (qua manifest)
  run_profile "$profile"

  # 3) Module SAU profile (appnames cần biết app nào đã cài để alias/discovery)
  for m in "${LV_MODULES_POST[@]}"; do
    _skip "$m" && { log "bỏ qua module: $m"; continue; }
    "module_${m}"
  done

  echo
  timer_report
  ok "LinuxViet Toolkit hoàn tất cho profile '${profile}'."
  log "Nhật ký: $LV_LOG_FILE"
  warn "Khuyến nghị ĐĂNG XUẤT rồi ĐĂNG NHẬP lại (hoặc khởi động lại) để áp dụng locale, bộ gõ và nhóm docker."
}

main "$@"
