#!/bin/bash
# ============================================================
# Docker 功能测试脚本
# 测试项目: pull / run / commit / export / load / push
# ============================================================

set -e

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

info()    { echo -e "${BLUE}[INFO]${NC}  $*"; }
success() { echo -e "${GREEN}[OK]${NC}    $*"; }
warn()    { echo -e "${YELLOW}[WARN]${NC}  $*"; }
error()   { echo -e "${RED}[ERROR]${NC} $*"; }
die()     { error "$*"; exit 1; }

WORK_DIR="/tmp/docker_test_$$"
TEST_IMAGE="hello-world"
COMMIT_IMAGE="hello-world-committed:test"
EXPORT_TAR="$WORK_DIR/hello-world-export.tar"
LOAD_TAR="$WORK_DIR/hello-world-load.tar"
TEST_CONTAINER="docker_test_$$"

mkdir -p "$WORK_DIR"

echo ""
echo "============================================================"
echo "   Docker 功能测试脚本"
echo "============================================================"
echo ""

# ---------- 检查 Docker 服务 ----------
info "检查 Docker 服务状态..."
if ! docker info &>/dev/null; then
    die "Docker 服务未运行, 请先启动: systemctl start docker"
fi
success "Docker 服务正常 ✓"

# ---------- 1. docker pull ----------
echo ""
echo "------------------------------------------------------------"
info "[1/5] 测试 docker pull..."
echo "------------------------------------------------------------"

# 尝试多个镜像源
PULL_OK=false
for mirror_image in \
    "hello-world" \
    "docker.mirrors.ustc.edu.cn/library/hello-world:latest" \
    "mirror.baidubce.com/library/hello-world:latest"; do

    info "尝试拉取: $mirror_image"
    if docker pull "$mirror_image" 2>&1; then
        # 如果不是标准名称，打个tag
        if [ "$mirror_image" != "hello-world" ]; then
            docker tag "$mirror_image" hello-world:latest 2>/dev/null || true
        fi
        PULL_OK=true
        success "docker pull 成功 ✓"
        break
    else
        warn "拉取 $mirror_image 失败, 尝试下一个..."
    fi
done

if [ "$PULL_OK" = false ]; then
    # 最后手段: 本地构建一个最小镜像代替
    warn "所有镜像源均无法拉取, 改用本地构建最小测试镜像..."
    SCRATCH_DIR="$WORK_DIR/scratch"
    mkdir -p "$SCRATCH_DIR"
    # 写一个静态可执行的 hello 程序 (用 shell 脚本模拟)
    cat > "$SCRATCH_DIR/hello.sh" <<'HELLO'
#!/bin/sh
echo "Hello from Docker on ARM64!"
echo "Docker pull/commit/export/load 功能测试通过"
HELLO
    chmod +x "$SCRATCH_DIR/hello.sh"
    cat > "$SCRATCH_DIR/Dockerfile" <<'DOCKERFILE'
FROM busybox:latest
COPY hello.sh /hello.sh
CMD ["/hello.sh"]
DOCKERFILE
    # 先拉 busybox
    docker pull busybox:latest 2>&1 || die "busybox 也无法拉取, 网络不可用"
    docker build -t hello-world:latest "$SCRATCH_DIR" 2>&1
    success "本地构建 hello-world 镜像成功 ✓"
fi

# ---------- 2. docker run ----------
echo ""
echo "------------------------------------------------------------"
info "[2/5] 测试 docker run..."
echo "------------------------------------------------------------"

docker run --name "$TEST_CONTAINER" "$TEST_IMAGE" 2>&1 \
    || docker run --name "$TEST_CONTAINER" hello-world:latest 2>&1 \
    || die "docker run 失败"
success "docker run 成功 ✓"

# ---------- 3. docker commit ----------
echo ""
echo "------------------------------------------------------------"
info "[3/5] 测试 docker commit..."
echo "------------------------------------------------------------"

docker commit \
    -m "测试 commit: 添加自定义标签" \
    -a "docker-test-script" \
    "$TEST_CONTAINER" \
    "$COMMIT_IMAGE" 2>&1
success "docker commit 成功 -> $COMMIT_IMAGE ✓"

# 验证 commit 的镜像存在
docker inspect "$COMMIT_IMAGE" &>/dev/null \
    || die "commit 后的镜像不存在"
success "commit 镜像验证通过 ✓"

# ---------- 4. docker export ----------
echo ""
echo "------------------------------------------------------------"
info "[4/5] 测试 docker export..."
echo "------------------------------------------------------------"

docker export "$TEST_CONTAINER" -o "$EXPORT_TAR" 2>&1
EXPORT_SIZE=$(du -sh "$EXPORT_TAR" | cut -f1)
success "docker export 成功 -> $EXPORT_TAR ($EXPORT_SIZE) ✓"

# ---------- 5. docker save + docker load ----------
echo ""
echo "------------------------------------------------------------"
info "[5/5] 测试 docker save & load..."
echo "------------------------------------------------------------"

# save committed 镜像为 tar
docker save "$COMMIT_IMAGE" -o "$LOAD_TAR" 2>&1
LOAD_SIZE=$(du -sh "$LOAD_TAR" | cut -f1)
success "docker save 成功 -> $LOAD_TAR ($LOAD_SIZE) ✓"

# 删除本地镜像再 load，验证完整性
docker rmi "$COMMIT_IMAGE" 2>&1
info "已删除本地镜像 $COMMIT_IMAGE, 准备 load..."

docker load -i "$LOAD_TAR" 2>&1
docker inspect "$COMMIT_IMAGE" &>/dev/null \
    || die "docker load 后镜像不存在"
success "docker load 成功, 镜像已恢复 ✓"

# ---------- push 说明 ----------
echo ""
echo "------------------------------------------------------------"
info "[附] docker push 说明"
echo "------------------------------------------------------------"
warn "docker push 需要登录镜像仓库, 本脚本不自动执行"
echo "  推送到 Docker Hub:"
echo "    docker login"
echo "    docker tag $COMMIT_IMAGE <你的用户名>/hello-world:test"
echo "    docker push <你的用户名>/hello-world:test"
echo ""
echo "  推送到私有仓库:"
echo "    docker tag $COMMIT_IMAGE <仓库地址>/hello-world:test"
echo "    docker push <仓库地址>/hello-world:test"

# ---------- 清理 ----------
echo ""
echo "------------------------------------------------------------"
info "清理测试资源..."
echo "------------------------------------------------------------"
docker rm "$TEST_CONTAINER" 2>/dev/null && success "容器已清理 ✓"
docker rmi "$COMMIT_IMAGE" 2>/dev/null && success "commit 镜像已清理 ✓"
rm -rf "$WORK_DIR" && success "临时文件已清理 ✓"

# ---------- 汇总 ----------
echo ""
echo "============================================================"
success "全部测试通过!"
echo "============================================================"
echo ""
echo "  测试结果汇总:"
echo "    ✓ docker pull   - 镜像拉取"
echo "    ✓ docker run    - 容器运行"
echo "    ✓ docker commit - 容器提交为镜像"
echo "    ✓ docker export - 容器导出为 tar"
echo "    ✓ docker save   - 镜像保存为 tar"
echo "    ✓ docker load   - 从 tar 加载镜像"
echo "    - docker push   - 需手动配置仓库后执行"
echo ""
