#!/bin/bash
# cleanup-server - Dọn dẹp + nâng cấp server (Ubuntu/Arch), interactive, tuần tự.
# Cách dùng:
#   cleanup-server            # hiện menu chọn target (local hoặc server alias)
#   cleanup-server --run-steps   # (nội bộ) chạy thẳng 6 bước trên máy hiện tại

# -----------------------------
# Color helpers (tự tắt khi không phải TTY)
# -----------------------------
if [ -t 1 ]; then
    C_RESET=$'\033[0m'
    C_TITLE=$'\033[1;36m'   # tiêu đề
    C_OK=$'\033[1;32m'      # thành công
    C_DEL=$'\033[1;31m'     # sẽ xóa / lỗi
    C_WARN=$'\033[1;33m'    # cảnh báo
else
    C_RESET=""; C_TITLE=""; C_OK=""; C_DEL=""; C_WARN=""
fi

# -----------------------------
# Banner rainbow (giống style `cleanup`)
# -----------------------------
print_banner() {
    local use_color=0 reset="" i=0 line
    local -a lines=(
        '  ██████╗██╗   ██╗ ██████╗██╗  ██╗██╗   ██╗██████╗  ███████╗███╗   ██╗ ██████╗██╗  ██╗'
        ' ██╔════╝██║   ██║██╔════╝██║  ██║██║   ██║██╔══██╗ ██╔════╝████╗  ██║██╔═══██╗╚██╗██╔╝'
        ' ██║     ██║   ██║██║     ███████║██║   ██║██║  ██║ █████╗  ██╔██╗ ██║██║   ██║ ╚███╔╝ '
        ' ██║     ██║   ██║██║     ██╔══██║██║   ██║██║  ██║ ██╔══╝  ██║╚██╗██║██║   ██║ ██╔██╗ '
        ' ╚██████╗╚██████╔╝╚██████╗██║  ██║╚██████╔╝██████╔╝ ███████╗██║ ╚████║╚██████╔╝██╔╝ ██╗'
        '  ╚═════╝ ╚═════╝  ╚═════╝╚═╝  ╚═╝ ╚═════╝ ╚═════╝  ╚══════╝╚═╝  ╚═══╝ ╚═════╝ ╚═╝  ╚═╝'
    )
    local -a colors=()
    if [ -t 1 ]; then
        use_color=1
        reset=$'\033[0m'
        colors=(
            $'\033[1;38;5;51m' $'\033[1;38;5;87m' $'\033[1;38;5;123m'
            $'\033[1;38;5;159m' $'\033[1;38;5;220m' $'\033[1;38;5;214m'
        )
    fi
    echo ""
    for line in "${lines[@]}"; do
        if [ "$use_color" -eq 1 ]; then
            printf '%b%s%b\n' "${colors[$i]}" "$line" "$reset"
        else
            printf '%s\n' "$line"
        fi
        i=$((i + 1))
    done
    echo ""
}

# -----------------------------
# Phát hiện distro qua /etc/os-release → debian | arch | unknown
# -----------------------------
detect_distro() {
    [ -r /etc/os-release ] || { echo unknown; return; }
    local id id_like
    . /etc/os-release 2>/dev/null
    id="${ID:-}"; id_like="${ID_LIKE:-}"
    case "$id $id_like" in
        *arch*)   echo arch ;;
        *debian*) echo debian ;;
        *ubuntu*) echo debian ;;
        *)        echo unknown ;;
    esac
}

# -----------------------------
# Hỏi Y/n (Enter = Yes). Trả về 0 = đồng ý, 1 = hủy.
# -----------------------------
confirm_yn() {
    local prompt="$1" confirm
    read -r -p "    ${prompt} (Y/n): " confirm
    if [[ -n "$confirm" && ! "$confirm" =~ ^([yY]|[yY][eE][sS])$ ]]; then
        echo "    Đã hủy."
        return 1
    fi
    return 0
}

# -----------------------------
# Danh sách target fix cứng (alias từ ~/.ssh/config)
# -----------------------------
TARGETS=("local" "ta" "toc" "oc" "cse" "vrc" "aws" "tk" "od")
TARGET_CURSOR=0
TARGET=""

# Vẽ menu single-select
draw_target_menu() {
    if [ "$1" = "redraw" ]; then
        printf '\033[%dA' "$(( ${#TARGETS[@]} + 2 ))"
    fi
    echo "  Chọn target (↑↓: di chuyển | Enter: chọn):"
    echo ""
    local i
    for ((i = 0; i < ${#TARGETS[@]}; i++)); do
        local prefix="  "
        if [ "$i" -eq "$TARGET_CURSOR" ]; then
            prefix="${C_TITLE}▸ ${C_RESET}"
        fi
        printf '\r\033[K%s%s\n' "$prefix" "${TARGETS[$i]}"
    done
}

# Chạy menu, đặt biến toàn cục TARGET
select_target() {
    draw_target_menu
    while true; do
        IFS= read -rsn1 key
        case "$key" in
            $'\x1b')
                read -rsn2 seq
                case "$seq" in
                    '[A') TARGET_CURSOR=$(( (TARGET_CURSOR - 1 + ${#TARGETS[@]}) % ${#TARGETS[@]} ));;
                    '[B') TARGET_CURSOR=$(( (TARGET_CURSOR + 1) % ${#TARGETS[@]} ));;
                esac
                ;;
            '')   # Enter
                echo ""
                TARGET="${TARGETS[$TARGET_CURSOR]}"
                return
                ;;
        esac
        draw_target_menu "redraw"
    done
}

# -----------------------------
# Bước 1: Nâng cấp hệ thống theo distro
# -----------------------------
step_upgrade() {
    echo "${C_TITLE}--- [System Upgrade] ---${C_RESET}"
    local distro
    distro=$(detect_distro)
    case "$distro" in
        debian)
            echo "    Distro: Debian/Ubuntu (apt)."
            sudo apt-get update || { echo "${C_DEL}    ✗ apt-get update thất bại.${C_RESET}"; echo ""; return; }
            local upgradable
            upgradable=$(apt list --upgradable 2>/dev/null | grep -c 'upgradable')
            echo "    ${C_WARN}✗ ${upgradable} package có thể nâng cấp.${C_RESET}"
            if confirm_yn "Upgrade + autoremove?"; then
                sudo apt-get upgrade -y
                sudo apt-get autoremove --purge -y
                echo "${C_OK}    ✓ Đã nâng cấp xong.${C_RESET}"
            fi
            ;;
        arch)
            echo "    Distro: Arch (pacman)."
            local helper=""
            command -v paru >/dev/null 2>&1 && helper="paru"
            [ -z "$helper" ] && command -v yay >/dev/null 2>&1 && helper="yay"
            [ -z "$helper" ] && helper="sudo pacman"
            echo "    Helper: $helper"
            if confirm_yn "Chạy $helper -Syu?"; then
                $helper -Syu
                echo "${C_OK}    ✓ Đã nâng cấp xong.${C_RESET}"
            fi
            ;;
        *)
            echo "${C_WARN}    ⚠ Distro không hỗ trợ upgrade, bỏ qua.${C_RESET}"
            ;;
    esac
    echo ""
}

# -----------------------------
# Chọn 'docker' hoặc 'sudo docker' tùy permission
# Trả về chuỗi lệnh qua echo (gán: DC=$(docker_cmd))
# -----------------------------
docker_cmd() {
    if docker info >/dev/null 2>&1; then
        echo "docker"
    elif sudo -n docker info >/dev/null 2>&1; then
        echo "sudo docker"
    else
        echo ""
    fi
}

# -----------------------------
# Bước 2: Docker — df rồi prune từng loại
# -----------------------------
step_docker() {
    echo "${C_TITLE}--- [Docker] ---${C_RESET}"
    if ! command -v docker >/dev/null 2>&1; then
        echo "${C_WARN}    ⚠ docker command not found.${C_RESET}"
        echo ""
        return
    fi
    local DC
    DC=$(docker_cmd)
    if [ -z "$DC" ]; then
        echo "${C_WARN}    ⚠ Không có quyền truy cập docker (cần group docker hoặc sudo).${C_RESET}"
        echo ""
        return
    fi
    echo "    Lệnh: $DC"
    $DC system df
    echo ""
    confirm_yn "Prune images (-a)?"  && $DC image prune -a -f
    confirm_yn "Prune containers?"   && $DC container prune -f
    confirm_yn "Prune volumes?"      && $DC volume prune -f
    confirm_yn "Prune build cache?"  && $DC builder prune -f
    confirm_yn "Prune networks?"     && $DC network prune -f
    echo "${C_OK}    ✓ Docker cleanup xong.${C_RESET}"
    echo ""
}

# -----------------------------
# Bước 3: Journal logs — vacuum log cũ hơn 7 ngày
# -----------------------------
step_journal() {
    echo "${C_TITLE}--- [Journal Logs] ---${C_RESET}"
    if ! command -v journalctl >/dev/null 2>&1; then
        echo "${C_WARN}    ⚠ journalctl not found.${C_RESET}"
        echo ""
        return
    fi
    sudo journalctl --disk-usage
    if confirm_yn "Vacuum log cũ hơn 7 ngày (--vacuum-time=7d)?"; then
        sudo journalctl --vacuum-time=7d
        echo "${C_OK}    ✓ Đã dọn journal.${C_RESET}"
    fi
    echo ""
}

# -----------------------------
# Bước 4: Package cache — apt clean+autoremove hoặc paccache/pacman -Sc
# -----------------------------
step_pkg_cache() {
    echo "${C_TITLE}--- [Package Cache] ---${C_RESET}"
    local distro
    distro=$(detect_distro)
    case "$distro" in
        debian)
            local d="/var/cache/apt/archives"
            [ -d "$d" ] && sudo du -sh "$d"
            if confirm_yn "apt clean + autoremove?"; then
                sudo apt-get clean
                sudo apt-get autoremove -y
                echo "${C_OK}    ✓ Đã dọn apt cache.${C_RESET}"
            fi
            ;;
        arch)
            local d="/var/cache/pacman/pkg"
            [ -d "$d" ] && sudo du -sh "$d"
            if command -v paccache >/dev/null 2>&1; then
                sudo paccache -dk2      # dry-run xem trước
                if confirm_yn "paccache -rk2 (giữ 2 bản)?"; then
                    sudo paccache -rk2
                    echo "${C_OK}    ✓ Đã dọn pacman cache.${C_RESET}"
                fi
            else
                if confirm_yn "Không có paccache, chạy pacman -Sc?"; then
                    sudo pacman -Sc --noconfirm
                    echo "${C_OK}    ✓ Đã dọn pacman cache.${C_RESET}"
                fi
            fi
            ;;
        *)
            echo "${C_WARN}    ⚠ Distro không hỗ trợ dọn package cache.${C_RESET}"
            ;;
    esac
    echo ""
}

# -----------------------------
# Chạy tuần tự 6 bước (stub — các bước thêm ở Task 4-9)
# -----------------------------
run_all_steps() {
    step_upgrade
    step_docker
    step_journal
    step_pkg_cache
}

# -----------------------------
# Chạy trên target đã chọn.
#   local → chạy tại chỗ.
#   alias → self-bootstrap: base64 script qua argv, giữ stdin=terminal
#           để read/màu tương tác hoạt động qua PTY của `ssh -t`.
# -----------------------------
run_on_target() {
    local target="$1"
    if [ "$target" = "local" ]; then
        run_all_steps
        return $?
    fi
    local b64
    b64=$(base64 < "$0" | tr -d '\n') || {
        echo "${C_DEL}    ✗ Không mã hóa được script.${C_RESET}"
        return 1
    }
    # Giải mã ra file tạm trên remote rồi chạy; stdin không bị redirect → read OK.
    ssh -t "$target" \
        "umask 077; t=\$(mktemp); printf '%s' '$b64' | base64 -d > \"\$t\" && bash \"\$t\" --run-steps; r=\$?; rm -f \"\$t\"; exit \$r" \
        || { echo "${C_DEL}    ✗ ssh tới $target thất bại.${C_RESET}"; return 1; }
}

# -----------------------------
# Main (phân nhánh theo argv)
# -----------------------------
main() {
    if [ "${1:-}" = "--run-steps" ]; then
        echo "${C_TITLE}===== 🧹 Cleanup-server (--run-steps) =====${C_RESET}"
        echo ""
        run_all_steps
        echo ""
        echo "${C_OK}===== ✅ Cleanup-server hoàn tất =====${C_RESET}"
        return
    fi
    print_banner
    echo "${C_TITLE}===== 🧹 Cleanup-server =====${C_RESET}"
    echo ""
    select_target
    echo ""
    run_on_target "$TARGET"
}

main "$@"
