#!/bin/bash
set -euo pipefail

### ===== 参数 =====
dockersize=${1:-"1T"}
mountpoint="/var/lib/docker"
loopfile="/var/lib/docker-loop.xfs"
backupdir="/var/lib/docker.bak.$(date +%F-%H%M%S)"

log() { echo "[INFO] $*"; }
err() { echo "[ERROR] $*" >&2; }

### ===== 容量解析 =====
parse_size_to_gb() {
    local size=$1
    if [[ $size == *T ]]; then
        echo $(( ${size%T} * 1024 ))
    elif [[ $size == *G ]]; then
        echo ${size%G}
    elif [[ $size == *M ]]; then
        echo $(( ${size%M} / 1024 ))
    else
        err "不支持的单位: $size"
        exit 1
    fi
}
size_gb=$(parse_size_to_gb "$dockersize")

### ===== 幂等检查 =====
if mount | grep -q "on $mountpoint "; then
    log "$mountpoint 已挂载，退出"
    exit 0
fi

### ===== Docker 检测 =====
if command -v docker >/dev/null 2>&1; then
    docker_installed=1
    log "检测到 Docker"
else
    docker_installed=0
    log "未检测到 Docker"
fi

### ===== 停止 + 备份 =====
if [ "$docker_installed" -eq 1 ]; then
    log "停止 Docker"
    systemctl stop docker || true

    if [ -d "$mountpoint" ] && [ "$(ls -A $mountpoint 2>/dev/null)" ]; then
        log "备份数据 -> $backupdir"
        mkdir -p "$backupdir"
        rsync -aHAX "$mountpoint"/ "$backupdir"/
    fi
fi

### ===== 回滚机制 =====
rollback() {
    err "发生错误，执行回滚..."

    umount -f "$mountpoint" 2>/dev/null || true

    if [ -d "$backupdir" ]; then
        log "恢复数据"
        mkdir -p "$mountpoint"
        rsync -aHAX "$backupdir"/ "$mountpoint"/ || true
    fi

    systemctl start docker 2>/dev/null || true
    err "回滚完成"
}
trap rollback ERR

### ===== 判断 LVM =====
root_dev=$(df / | tail -1 | awk '{print $1}')
is_lvm=0

if lsblk -no TYPE "$root_dev" | grep -q lvm; then
    is_lvm=1
fi

### ===== LVM 方案 =====
if [ "$is_lvm" -eq 1 ]; then
    log "使用 LVM 方案"

    vg_name=$(vgs --noheadings -o vg_name | head -1 | awk '{print $1}')
    free_gb=$(vgs --noheadings -o vg_free --units g --nosuffix "$vg_name" | awk '{print int($1)}')

    log "VG: $vg_name 剩余: ${free_gb}G"

    if [ "$free_gb" -lt "$size_gb" ]; then
        err "LVM 空间不足，需要 ${size_gb}G"
        exit 1
    fi

    lv_path="/dev/$vg_name/docker-lv"

    if [ ! -e "$lv_path" ]; then
        log "创建 LV"
        lvcreate -L "$dockersize" -n docker-lv "$vg_name"
        mkfs.xfs "$lv_path"
    else
        log "LV 已存在，跳过创建"
    fi

    mkdir -p "$mountpoint"

    log "挂载"
    mount -o pquota "$lv_path" "$mountpoint"

    grep -q "$lv_path" /etc/fstab || \
    echo "$lv_path $mountpoint xfs defaults,pquota 0 0" >> /etc/fstab

### ===== loop 方案 =====
else
    log "使用 loop 方案"

    if [ ! -f "$loopfile" ]; then
        log "创建镜像文件"
        fallocate -l "$dockersize" "$loopfile"
        mkfs.xfs -f "$loopfile"
    else
        log "loop 文件已存在"
    fi

    mkdir -p "$mountpoint"

    grep -q "$loopfile" /etc/fstab || \
    echo "$loopfile $mountpoint xfs loop,rw,auto,pquota 0 0" >> /etc/fstab

    log "挂载"
    mount -a
fi

### ===== 校验 =====
#if ! mount | grep "$mountpoint" | grep -q pquota; then
#    err "pquota 未生效"
#    exit 1
#fi

### ===== 恢复数据 =====
if [ "$docker_installed" -eq 1 ] && [ -d "$backupdir" ]; then
    log "恢复数据"
    rsync -aHAX "$backupdir"/ "$mountpoint"/
fi

### ===== 启动 Docker =====
if [ "$docker_installed" -eq 1 ]; then
    log "启动 Docker"
    systemctl start docker
fi

log "✅ Docker 存储已就绪（支持 size 限制）"
