#!/bin/bash

##############################################################
# File Name: mypull
# Version: V1.0.1
# Author: cnHeaven
# Modify: cnDongyan
# Blog Site: cnHeaven
# Created Time : 2024-10-14
# Environment: Synology DS918+
##############################################################

# 检查当前用户是否为root 
if [ "$EUID" -ne 0 ]; then 
  echo "请以root用户身份运行此脚本" 
  exit 1 
fi  

# 显示帮助信息的函数
show_help() {
    echo "Usage: $0 [--help] <image_name> [mirror_choice]"
    echo "  --help: 显示此帮助信息"
    echo "  <image_name>: 要拉取的Docker镜像名称，例如 myapp:1.0 或 myapp"
    echo "  [mirror_choice]: 可选，指定从哪个镜像源序号开始尝试 (例如: 1表示从第一个镜像源开始)"
    exit 0
}

# 检查参数个数
if [ $# -eq 0 ] || [ "$1" == "--help" ]; then
    show_help
fi

# 获取镜像名称
name="$1"

# 获取第二个参数（如果有）
prechoice=$2

# 获取文件内容
proxy="https://gh.llkk.cc/"
url="${proxy}https://raw.githubusercontent.com/dongyubin/DockerHub/refs/heads/main/README.md"
content=$(curl -s "$url")

# 如果内容为空，说明无法获取文件
if [ -z "$content" ]; then
    echo "无法获取文件内容，请检查URL或代理设置。"
    exit 1
fi

# 提取 registry-mirrors 部分并格式化输出
mirror_list=$(echo "$content" | sed -n '/"registry-mirrors": \[/,/\]/p' | \
             sed 's/^[ \t]*//g' | sed 's/[",]//g' | grep -o 'https*[^"]*')

# 声明一个关联数组
declare -A mirrors

# 自定义的镜像列表（排在前面）
custom_mirrors=(
    "docker.custom1.com"
    "docker.custom2.com"
    "docker.custom3.com"
)

# 添加自定义镜像到镜像列表
count=1
for mirror in "${custom_mirrors[@]}"; do
    mirrors[$count]="$mirror"
    ((count++))
done

# 填充从README获取的镜像
for mirror in $mirror_list; do
    domain=$(echo "$mirror" | sed -E 's|https?://([^/]+).*|\1|')
    mirrors[$count]="$domain"
    ((count++))
done

# 显示可选的镜像列表
echo "请选择一个镜像源:"
keys=("${!mirrors[@]}") 
sorted_keys=($(printf '%s\n' "${keys[@]}" | sort -n)) 
for key in "${sorted_keys[@]}"; do 
    echo "$key) ${mirrors[$key]}" 
done 

# 如果用户未提供选择，默认使用从第一个镜像源开始
if [ -z "$prechoice" ] || [ "$prechoice" -eq 0 ]; then
    echo "未指定镜像源，默认从第一个镜像源开始..."
    prechoice=1
fi

# 确保第二个参数在有效范围内
if [[ "$prechoice" -lt 1 || "$prechoice" -gt "${#mirrors[@]}" ]]; then
    echo "无效的镜像源序号，请选择有效的序号。"
    exit 1
fi

# 循环直到输入有效
success=false
for ((i=$prechoice; i<=${#mirrors[@]}; i++)); do
    mirror="${mirrors[$i]}"
    echo "正在尝试从镜像源 $i: $mirror 拉取镜像..."
    docker pull "$mirror/$name"
    
    # 检查拉取是否成功
    if [ $? -eq 0 ]; then
        success=true
        echo "镜像拉取成功: $mirror/$name"
        break
    else
        echo "镜像拉取失败，正在尝试下一个镜像源..."
    fi
done

# 如果所有镜像源都拉取失败，退出
if [ "$success" = false ]; then
    echo "所有镜像源都无法拉取镜像: $name"
    exit 1
fi

# 获取镜像名称和标签
if [[ "$name" == *":"* ]]; then
    IMAGE_NAME=$(echo "$name" | cut -d ':' -f 1)
    TAG=$(echo "$name" | cut -d ':' -f 2-)
else
    IMAGE_NAME="$name"
    TAG="latest"
fi
FULL_IMAGE_NAME="$IMAGE_NAME:$TAG"

# 输出变量值
echo "你选择的代理是: $mirror"
echo "需要拉取的镜像是: $FULL_IMAGE_NAME"

# 拉取镜像后移除镜像源标签
echo "正在为镜像打标签: $TAG"
docker tag "$mirror/$FULL_IMAGE_NAME" "$IMAGE_NAME:$TAG"

# 检查标签是否成功
if [ $? -eq 0 ]; then
    echo "镜像标签打标成功: $IMAGE_NAME:$TAG"
    
    # 检查新标签是否存在
    docker images | grep "$IMAGE_NAME" | grep "$TAG" > /dev/null
    if [ $? -ne 0 ]; then
        echo "打标后找不到镜像: $IMAGE_NAME:$TAG"
        exit 1
    fi
    
    # 删除带镜像源的标签
    echo "移除镜像源标签: $mirror"
    docker rmi "$mirror/$FULL_IMAGE_NAME" > /dev/null
else
    echo "镜像标签打标失败: $IMAGE_NAME:$TAG"
    exit 1
fi

echo "脚本执行完成。"
