#!/bin/bash

cd /root >/dev/null 2>&1

RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'

REGEX=("debian|astra" "ubuntu")
RELEASE=("Debian" "Ubuntu")
CMD=("$(grep -i pretty_name /etc/os-release 2>/dev/null | cut -d \" -f2)" "$(lsb_release -sd 2>/dev/null)")
SYS="${CMD[0]}"
[[ -n $SYS ]] || exit 1

for ((int = 0; int < ${#REGEX[@]}; int++)); do
    if [[ $(echo "$SYS" | tr '[:upper:]' '[:lower:]') =~ ${REGEX[int]} ]]; then
        SYSTEM="${RELEASE[int]}"
        [[ -n $SYSTEM ]] && break
    fi
done

if [[ "$SYSTEM" != "Debian" && "$SYSTEM" != "Ubuntu" ]]; then
    echo -e "${RED}[ERR]${NC} 此脚本仅支持 Debian 和 Ubuntu 系统"
    exit 1
fi

if [[ "$SYSTEM" == "Debian" ]]; then
    OS_VERSION=$(cat /etc/debian_version | cut -d. -f1)
elif [[ "$SYSTEM" == "Ubuntu" ]]; then
    OS_VERSION=$(grep VERSION_ID /etc/os-release | cut -d'"' -f2 | cut -d. -f1)
fi

RECOMMENDED=false
if [[ "$SYSTEM" == "Debian" && ("$OS_VERSION" == "12" || "$OS_VERSION" == "13") ]]; then
    RECOMMENDED=true
elif [[ "$SYSTEM" == "Ubuntu" && ("$OS_VERSION" == "24" || "$OS_VERSION" == "25") ]]; then
    RECOMMENDED=true
fi

if [[ "$RECOMMENDED" != "true" ]]; then
    echo -e "${YELLOW}[WARN]${NC} 当前系统: $SYSTEM $OS_VERSION"
    echo -e "${YELLOW}[WARN]${NC} 推荐使用: Debian 12/13 或 Ubuntu 24/25"
    read -rp "$(echo -e "${YELLOW}是否继续安装？(y/n) [n]：${NC}")" confirm_install
    confirm_install=${confirm_install:-n}
    if [[ ! "$confirm_install" =~ ^[yY]$ ]]; then
        echo -e "${RED}[ERR]${NC} 安装已取消"
        exit 1
    fi
fi

log() { echo -e "$1"; }
ok() { log "${GREEN}[OK]${NC} $1"; }
info() { log "${BLUE}[INFO]${NC} $1"; }
warn() { log "${YELLOW}[WARN]${NC} $1"; }
err() { log "${RED}[ERR]${NC} $1"; exit 1; }

reading() { read -rp "$(echo -e "${GREEN}$1${NC}")" "$2"; }

install_package() {
    package_name=$1
    if dpkg -l 2>/dev/null | grep -q "^ii.*$package_name"; then
        ok "$package_name 已安装"
    else
        apt-get install -y $package_name >/dev/null 2>&1
        if [ $? -ne 0 ]; then
            apt-get install -y $package_name --fix-missing >/dev/null 2>&1
        fi
        if dpkg -l 2>/dev/null | grep -q "^ii.*$package_name"; then
            ok "$package_name 已安装"
        else
            warn "$package_name 安装失败"
        fi
    fi
}

get_available_space() {
    local available_space
    available_space=$(df -BG / | awk 'NR==2 {gsub("G","",$4); print $4}')
    echo "$available_space"
}

install_lxd() {
    info "安装基础网络组件..."
    apt-get update >/dev/null 2>&1
    if ! apt-get install -y nftables; then
        warn "尝试修复并重新安装 nftables..."
        apt-get install -y nftables --fix-missing
    fi
    if ! command -v nft >/dev/null 2>&1; then
        err "nftables 安装失败，请检查网络或软件源"
    fi
    ok "nftables 安装成功"
    lxd_snap=$(dpkg -l | awk '/^[hi]i/{print $2}' | grep -ow snap)
    lxd_snapd=$(dpkg -l | awk '/^[hi]i/{print $2}' | grep -ow snapd)
    if [[ "$lxd_snap" =~ ^snap.* ]] && [[ "$lxd_snapd" =~ ^snapd.* ]]; then
        ok "snap 已安装"
    else
        info "开始安装 snap..."
        apt-get update >/dev/null 2>&1
        install_package snapd
    fi
    snap_core=$(snap list core 2>/dev/null)
    snap_lxd=$(snap list lxd 2>/dev/null)
    if [[ "$snap_core" =~ core.* ]] && [[ "$snap_lxd" =~ lxd.* ]]; then
        ok "LXD 已安装"
        lxd_lxc_detect=$(lxc list 2>/dev/null)
        if [[ "$lxd_lxc_detect" =~ "snap-update-ns failed with code1".* ]]; then
            systemctl restart apparmor
            snap restart lxd
        else
            ok "环境检测无问题"
        fi
    else
        info "开始安装 LXD..."
        snap install lxd --channel=latest/stable 2>/dev/null
        if [[ $? -ne 0 ]]; then
            snap remove lxd 2>/dev/null
            snap install core 2>/dev/null
            snap install lxd --channel=latest/stable 2>/dev/null
        fi
        snap alias lxd.lxc lxc 2>/dev/null
        snap alias lxd.lxd lxd 2>/dev/null
        if [ ! -f /etc/profile.d/snap.sh ]; then
            echo 'export PATH=$PATH:/snap/bin' > /etc/profile.d/snap.sh
        fi
        export PATH=$PATH:/snap/bin
        if ! command -v lxc >/dev/null 2>&1; then
            err 'lxc 路径有问题，请检查 snap alias'
        fi
        ok "LXD 安装完成"
    fi
    
    if dpkg -l lxcfs 2>/dev/null | grep -q "^ii"; then
        warn "检测到 deb 版 lxcfs，正在移除..."
        systemctl stop lxcfs 2>/dev/null || true
        systemctl disable lxcfs 2>/dev/null || true
        apt-get remove -y lxcfs >/dev/null 2>&1
        ok "deb 版 lxcfs 已移除"
    fi
    
    lxd_version=$(lxd --version 2>/dev/null)
    info "LXD 版本: $lxd_version"
    if [[ ! "$lxd_version" =~ ^6\. ]]; then
        warn "当前 LXD 版本 $lxd_version 不兼容，推荐使用 6.x 版本"
        reading "是否继续？(y/n) [y]：" version_confirm
        version_confirm=${version_confirm:-y}
        if [[ ! "$version_confirm" =~ ^[yY]$ ]]; then
            err "已取消安装"
        fi
    else
        ok "LXD 版本兼容"
    fi
    
    info "配置 LXD..."
    snap set lxd lxcfs.flags="-l" 2>/dev/null
    snap set lxd daemon.debug=false 2>/dev/null
    snap restart lxd 2>/dev/null
    sleep 3
    ok "LXD 已配置"
}

init_lxd_network() {
    if ! /snap/bin/lxc network show lxdbr0 &>/dev/null; then
        info "创建默认网络 lxdbr0..."
        /snap/bin/lxc network create lxdbr0
        ok "网络 lxdbr0 创建成功"
    else
        ok "网络 lxdbr0 已存在"
    fi
    
    if ! /snap/bin/lxc profile device show default 2>/dev/null | grep -q "eth0"; then
        info "配置 default profile 网络设备..."
        /snap/bin/lxc profile device add default eth0 nic network=lxdbr0 name=eth0
        ok "网络设备已添加到 default profile"
    fi
}

setup_storage() {
    info "配置存储池..."
    
    if /snap/bin/lxc storage show default &>/dev/null; then
        ok "存储池 default 已存在"
        /snap/bin/lxc storage list
        return 0
    fi
    
    available_space=$(get_available_space)
    info "当前可用磁盘空间: ${available_space}GB"
    
    while true; do
        reading "请选择存储后端 zfs/btrfs/lvm [zfs]：" storage_driver
        storage_driver=${storage_driver:-zfs}
        if [[ "$storage_driver" =~ ^(zfs|btrfs|lvm)$ ]]; then
            break
        else
            warn "请输入 zfs、btrfs 或 lvm"
        fi
    done
    
    case "$storage_driver" in
        zfs)
            if ! command -v zpool &>/dev/null; then
                info "安装 ZFS..."
                if [[ "$SYSTEM" == "Ubuntu" ]]; then
                    install_package zfsutils-linux
                else
                    bash <(curl -sL https://raw.githubusercontent.com/xkatld/lxdapi-web-server/refs/heads/v2.1.0-vpsm.link/Shell/debian_zfs.sh)
                fi
            fi
            info "配置 LXD 使用系统 ZFS..."
            snap set lxd zfs.external=true
            snap restart lxd
            sleep 3
            ;;
        btrfs)
            install_package btrfs-progs
            ;;
        lvm)
            install_package lvm2
            ;;
    esac
    
    reading "请输入存储池大小(GB) [${available_space}]：" pool_size
    pool_size=${pool_size:-$available_space}
    
    info "创建 default 存储池 (${storage_driver}, ${pool_size}GB)..."
    /snap/bin/lxc storage create default ${storage_driver} size=${pool_size}GB
    
    if [ $? -eq 0 ]; then
        ok "存储池 default 创建成功"
        if ! /snap/bin/lxc profile device show default 2>/dev/null | grep -q "root"; then
            /snap/bin/lxc profile device add default root disk path=/ pool=default
            ok "存储池已添加到 default profile"
        fi
    else
        err "存储池创建失败"
    fi
}

install_base_packages() {
    info "更新软件包列表..."
    apt-get update >/dev/null 2>&1
    apt-get autoremove -y >/dev/null 2>&1

    info "安装基础软件包..."
    DEBIAN_FRONTEND=noninteractive apt-get install -y unzip e2fsprogs bc fdisk parted curl wget >/dev/null 2>&1
    ok "软件包安装完成"
}

deploy_lxdapi() {
    info "检测系统架构..."
    sys_arch=$(uname -m)
    if [[ "$sys_arch" != "x86_64" ]]; then
        err "此安装包仅支持 amd64 架构，当前为: $sys_arch"
    fi

    arch="amd64"
    ok "检测到架构: x86_64"

    download_url="http://cccimg.com/down.php/26d5c8f2000a90d87077378e06aed883.gz"
    local_tar="/root/lxdapi-linux-amd64.tar.gz"

    info "下载 LXDAPI 安装包..."
    rm -f "$local_tar"

    if command -v wget >/dev/null 2>&1; then
        wget -O "$local_tar" "$download_url" >/dev/null 2>&1
    elif command -v curl >/dev/null 2>&1; then
        curl -L "$download_url" -o "$local_tar" >/dev/null 2>&1
    else
        err "未找到 wget 或 curl，无法下载安装包"
    fi

    if [ ! -f "$local_tar" ] || [ ! -s "$local_tar" ]; then
        err "安装包下载失败: $local_tar"
    fi

    ok "安装包下载完成"

    info "解压到 /opt/lxdapi..."
    mkdir -p /opt/lxdapi
    tar -xzf "$local_tar" -C /opt/lxdapi --strip-components=1

    ok "LXDAPI 部署完成"
}

configure_lxdapi() {
    info "配置 lxdapi..."

    config_file="/opt/lxdapi/configs/config.yaml"

    if [ ! -f "$config_file" ]; then
        err "配置文件不存在: $config_file"
    fi

    reading "请输入服务端口 [8443]：" server_port
    server_port=${server_port:-8443}

    reading "请输入API密钥 [随机生成]：" api_hash
    if [ -z "$api_hash" ]; then
        api_hash=$(openssl rand -hex 16)
        ok "API密钥已生成: $api_hash"
    fi

    reading "请输入管理员用户名 [admin]：" admin_user
    admin_user=${admin_user:-admin}

    reading "请输入管理员密码 [随机生成]：" admin_pass
    if [ -z "$admin_pass" ]; then
        admin_pass=$(openssl rand -hex 8)
        ok "管理员密码已生成: $admin_pass"
    fi

    session_secret=$(openssl rand -hex 16)

    reading "请输入流量采集间隔秒数 [20]：" traffic_interval
    traffic_interval=${traffic_interval:-20}

    reading "请输入流量批量更新数量 [10]：" traffic_batch_size
    traffic_batch_size=${traffic_batch_size:-10}

    reading "请输入任务自动清理天数 [7]：" auto_cleanup_days
    auto_cleanup_days=${auto_cleanup_days:-7}

    reading "是否启用 Nginx 反向代理插件？ y/n [y]：" nginx_enabled
    nginx_enabled=${nginx_enabled:-y}
    if [[ "$nginx_enabled" =~ ^[yY]$ ]]; then
        install_package nginx
        systemctl enable nginx >/dev/null 2>&1
        systemctl start nginx >/dev/null 2>&1
        ok "nginx 已安装并启动"
        nginx_enabled_value="true"

        reading "是否启用 ACME 证书插件？ y/n [y]：" acme_enabled
        acme_enabled=${acme_enabled:-y}
        if [[ "$acme_enabled" =~ ^[yY]$ ]]; then
            acme_enabled_value="true"
        else
            acme_enabled_value="false"
        fi
    else
        warn "Nginx 已禁用，ACME 插件将同时禁用"
        nginx_enabled_value="false"
        acme_enabled_value="false"
    fi

    task_backend="memory"
    db_type="sqlite"

    info "写入配置文件..."
    sed -i "s|__SERVER_PORT__|$server_port|g" "$config_file"
    sed -i "s|__API_HASH__|$api_hash|g" "$config_file"
    sed -i "s|__ADMIN_USER__|$admin_user|g" "$config_file"
    sed -i "s|__ADMIN_PASS__|$admin_pass|g" "$config_file"
    sed -i "s|__SESSION_SECRET__|$session_secret|g" "$config_file"
    sed -i "s|__TRAFFIC_INTERVAL__|$traffic_interval|g" "$config_file"
    sed -i "s|__TRAFFIC_BATCH_SIZE__|$traffic_batch_size|g" "$config_file"
    sed -i "s|__AUTO_CLEANUP_DAYS__|$auto_cleanup_days|g" "$config_file"
    sed -i "s|__TASK_BACKEND__|$task_backend|g" "$config_file"
    sed -i "s|__DB_TYPE__|$db_type|g" "$config_file"
    sed -i "s|__REDIS_HOST__|localhost|g" "$config_file"
    sed -i "s|__REDIS_PORT__|6379|g" "$config_file"
    sed -i "s|__REDIS_PASSWORD__||g" "$config_file"
    sed -i "s|__REDIS_DB__|0|g" "$config_file"
    sed -i "s|__MYSQL_HOST__|localhost|g" "$config_file"
    sed -i "s|__MYSQL_PORT__|3306|g" "$config_file"
    sed -i "s|__MYSQL_USER__|root|g" "$config_file"
    sed -i "s|__MYSQL_PASSWORD__||g" "$config_file"
    sed -i "s|__MYSQL_DATABASE__|lxdapi|g" "$config_file"
    sed -i "s|__POSTGRES_HOST__|localhost|g" "$config_file"
    sed -i "s|__POSTGRES_PORT__|5432|g" "$config_file"
    sed -i "s|__POSTGRES_USER__|postgres|g" "$config_file"
    sed -i "s|__POSTGRES_PASSWORD__||g" "$config_file"
    sed -i "s|__POSTGRES_DATABASE__|lxdapi|g" "$config_file"
    sed -i "s|__POSTGRES_SSLMODE__|disable|g" "$config_file"
    sed -i "s|__NGINX_ENABLED__|$nginx_enabled_value|g" "$config_file"
    sed -i "s|__ACME_ENABLED__|$acme_enabled_value|g" "$config_file"

    ok "配置文件已更新 (已固定 SQLite & Memory 模式)"
}

setup_lxdapi_service() {
    info "配置 lxdapi 系统服务..."

    config_file="/opt/lxdapi/configs/config.yaml"
    if [ ! -f "$config_file" ]; then
        err "配置文件不存在: $config_file"
    fi

    if grep -q "__SERVER_PORT__" "$config_file"; then
        err "配置文件未完成配置"
    fi

    exec_bin="/opt/lxdapi/lxdapi-amd64"

    service_file="/etc/systemd/system/lxdapi.service"

    cat > "$service_file" << EOF
[Unit]
Description=LXD API Server
After=network.target lxd.service
Wants=lxd.service

[Service]
Type=simple
User=root
WorkingDirectory=/opt/lxdapi
Environment="PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin"
ExecStart=$exec_bin
Restart=always
RestartSec=5
StandardOutput=journal
StandardError=journal

[Install]
WantedBy=multi-user.target
EOF

    ok "服务文件已创建: $service_file"

    systemctl daemon-reload
    systemctl enable lxdapi
    systemctl start lxdapi

    info "等待服务启动..."
    for i in {1..10}; do
        printf "\r[%-10s] %d/10s" "$(printf '#%.0s' $(seq 1 $i))" "$i"
        sleep 1
    done
    echo

    if systemctl is-active --quiet lxdapi; then
        ok "lxdapi 服务已启动"
    else
        warn "lxdapi 服务启动失败"
        journalctl -u lxdapi -n 20 --no-pager
    fi
}

import_lxd_images() {
    info "开始下载并导入 LXD 镜像..."

    images=(
        "debian12|https://api.gitproxy.dev/github.com/xkatld/zjmf-lxd-server/releases/download/images/debian12-amd64.tar.gz"
        "debian13|https://api.gitproxy.dev/github.com/xkatld/zjmf-lxd-server/releases/download/images/debian13-amd64.tar.gz"
        "ubuntu2404|https://api.gitproxy.dev/github.com/xkatld/zjmf-lxd-server/releases/download/images/ubuntu2404-amd64.tar.gz"
    )

    command -v lxc >/dev/null 2>&1 || {
        warn "未检测到 lxc 命令，跳过镜像导入"
        return
    }

    for entry in "${images[@]}"; do
        name="${entry%%|*}"
        url="${entry##*|}"
        file="${name}-amd64.tar.gz"

        if lxc image list | grep -q "$name"; then
            ok "镜像已存在: $name"
            continue
        fi

        info "下载镜像: $name"
        wget -O "$file" "$url" >/dev/null 2>&1 || {
            warn "$name 下载失败，跳过"
            continue
        }

        info "导入镜像: $name"
        lxc image import "$file" --alias "$name" >/dev/null 2>&1 \
            && ok "$name 镜像导入成功" \
            || warn "$name 镜像导入失败"

        rm -f "$file"
    done

    ok "LXD 镜像导入完成"
}

main() {
    echo
    echo "========================================"
    echo "        LXD + LXDAPI 完整安装脚本"
    echo "        by Github-xkatld"
    echo "========================================"
    echo

    echo "======== 第一部分: LXD 安装 ========"
    reading "是否安装 LXD？(y/n) [y]：" lxd_confirm
    lxd_confirm=${lxd_confirm:-y}
    if [[ "$lxd_confirm" =~ ^[yY]$ ]]; then
        install_lxd
        ok "LXD 安装完成"
        
        reading "是否配置网络？(y/n) [y]：" network_confirm
        network_confirm=${network_confirm:-y}
        if [[ "$network_confirm" =~ ^[yY]$ ]]; then
            init_lxd_network
            ok "网络配置完成"
        fi
        
        reading "是否配置存储？(y/n) [y]：" storage_confirm
        storage_confirm=${storage_confirm:-y}
        if [[ "$storage_confirm" =~ ^[yY]$ ]]; then
            setup_storage
            ok "存储配置完成"
        fi
    else
        info "已跳过 LXD 安装"
    fi
    echo

    echo "======== 第二部分: LXDAPI 安装 ========"
    reading "是否安装 LXDAPI？(y/n) [y]：" lxdapi_confirm
    lxdapi_confirm=${lxdapi_confirm:-y}
    if [[ "$lxdapi_confirm" =~ ^[yY]$ ]]; then
        reading "是否安装基础软件包？(y/n) [y]：" base_confirm
        base_confirm=${base_confirm:-y}
        if [[ "$base_confirm" =~ ^[yY]$ ]]; then
            install_base_packages
        fi
        
        deploy_lxdapi
        configure_lxdapi
        setup_lxdapi_service
        ok "LXDAPI 安装完成"
    else
        info "已跳过 LXDAPI 安装"
    fi
    echo

    echo "======== 第三部分: 镜像导入 ========"
    reading "是否导入 LXD 镜像？(y/n) [y]：" image_confirm
    image_confirm=${image_confirm:-y}
    if [[ "$image_confirm" =~ ^[yY]$ ]]; then
        import_lxd_images
        ok "镜像导入完成"
    else
        info "已跳过镜像导入"
    fi
    echo

    echo "========================================"
    echo "        安装全部完成"
    echo "========================================"
    echo
    if [[ "$lxdapi_confirm" =~ ^[yY]$ ]]; then
        info "LXDAPI 配置信息:"
        info "  - 服务端口: $server_port"
        info "  - API密钥: $api_hash"
        info "  - 管理员: $admin_user / $admin_pass"
        info "  - 数据库: SQLite"
        info "  - 任务队列: Memory"
        echo
    fi
    
    info "LXD 状态:"
    lxd --version 2>/dev/null | xargs echo "  - 版本: "
    lxc network list 2>/dev/null | grep lxdbr0 | xargs echo "  - 网络: "
    lxc storage list 2>/dev/null | grep default | xargs echo "  - 存储: "
    
    if [[ "$image_confirm" =~ ^[yY]$ ]]; then
        echo
        info "已导入镜像:"
        lxc image list 2>/dev/null | grep -E "debian12|debian13|ubuntu2404" | awk '{print "  - "$2" ("$4")"}' | head -3
    fi
}

main
