#!/bin/bash

# Docker 智能安装脚本 (支持本地备用)
# 功能：支持本地docker-compose备用，优化国内安装体验
# 更新：2024-03-15

# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color

# 全局变量
USE_CHINA_SOURCE="auto"
MIRROR_CN="https://mirrors.aliyun.com/docker-ce"
COMPOSE_CN="https://get.daocloud.io/docker/compose/releases/download"
LOCAL_COMPOSE_FILE="./docker-compose"  # 本地docker-compose文件路径

# 检查 root 权限
check_root() {
    if [ "$(id -u)" -ne 0 ]; then
        echo -e "${RED}错误：请使用 root 用户运行此脚本${NC}"
        exit 1
    fi
}

# 检测中国大陆IP
detect_china_ip() {
    local is_china=false
    if ping -c 1 -W 3 ipapi.co &>/dev/null; then
        country=$(curl -s https://ipapi.co/country/ 2>/dev/null || echo "unknown")
        [ "$country" = "CN" ] && is_china=true
    elif ping -c 1 -W 3 ipinfo.io &>/dev/null; then
        country=$(curl -s https://ipinfo.io/country 2>/dev/null || echo "unknown")
        [ "$country" = "CN" ] && is_china=true
    fi
    echo "$is_china"
}

# 交互式选择安装源
select_source() {
    echo -e "${BLUE}"
    echo "=================================="
    echo " Docker 安装源选择"
    echo "=================================="
    echo -e "${NC}"
    echo "1) 自动检测最佳源 (默认)"
    echo "2) 强制使用国内镜像源 (阿里云)"
    echo "3) 强制使用国外官方源"
    read -p "请选择 [1-3] (默认1): " choice

    case $choice in
        1) USE_CHINA_SOURCE="auto";;
        2) USE_CHINA_SOURCE="yes";;
        3) USE_CHINA_SOURCE="no";;
        *) USE_CHINA_SOURCE="auto";;
    esac

    # 自动检测逻辑
    if [ "$USE_CHINA_SOURCE" = "auto" ]; then
        if [ "$(detect_china_ip)" = "true" ]; then
            echo -e "${YELLOW}检测到中国大陆IP，自动切换国内镜像${NC}"
            USE_CHINA_SOURCE="yes"
        elif ! curl -s --connect-timeout 5 https://download.docker.com >/dev/null; then
            echo -e "${YELLOW}检测到国外源连接困难，自动切换国内镜像${NC}"
            USE_CHINA_SOURCE="yes"
        else
            echo -e "${GREEN}检测到国外源连接良好，使用官方源${NC}"
            USE_CHINA_SOURCE="no"
        fi
    fi
}

# 修复基础软件源 (针对Ubuntu/Debian)
fix_base_repo() {
    if [ -f /etc/apt/sources.list ]; then
        echo -e "${YELLOW}>>> 检查并修复基础软件源${NC}"
        sed -i 's|http://.*archive.ubuntu.com|https://mirrors.aliyun.com|g' /etc/apt/sources.list
        sed -i 's|http://.*security.ubuntu.com|https://mirrors.aliyun.com|g' /etc/apt/sources.list
        sed -i 's|http://.*debian.org|https://mirrors.aliyun.com|g' /etc/apt/sources.list
    fi
}

# 安装必要依赖
install_deps() {
    echo -e "${YELLOW}>>> 正在安装必要依赖${NC}"
    
    if [ -f /etc/debian_version ]; then
        fix_base_repo
        apt update -y
        apt install -y lsb-release curl gnupg apt-transport-https ca-certificates software-properties-common
    elif [ -f /etc/redhat-release ]; then
        yum install -y curl gnupg2 ca-certificates yum-utils device-mapper-persistent-data lvm2
    elif grep -qi "alpine" /etc/os-release; then
        apk add curl gnupg
    else
        echo -e "${YELLOW}未知系统，尝试安装基础依赖${NC}"
        if command -v apt &> /dev/null; then
            apt update -y && apt install -y curl gnupg
        elif command -v yum &> /dev/null; then
            yum install -y curl gnupg2
        fi
    fi
}

# 安装 Docker
install_docker() {
    echo -e "${GREEN}>>> 正在安装 Docker${NC}"
    
    if [ -f /etc/os-release ]; then
        source /etc/os-release
        case $ID in
            ubuntu|debian)
                if [ "$USE_CHINA_SOURCE" = "yes" ]; then
                    # 国内阿里云源
                    curl -fsSL ${MIRROR_CN}/linux/$ID/gpg | gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
                    echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] ${MIRROR_CN}/linux/$ID $(lsb_release -cs) stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null
                else
                    # 国外官方源
                    curl -fsSL https://download.docker.com/linux/$ID/gpg | gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
                    echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/$ID $(lsb_release -cs) stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null
                fi
                apt update -y
                apt install -y docker-ce docker-ce-cli containerd.io
                ;;
            centos|rhel|fedora)
                yum install -y yum-utils
                if [ "$USE_CHINA_SOURCE" = "yes" ]; then
                    yum-config-manager --add-repo ${MIRROR_CN}/linux/centos/docker-ce.repo
                else
                    yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
                fi
                yum install -y docker-ce docker-ce-cli containerd.io
                ;;
            alpine)
                apk add docker
                ;;
            *)
                echo -e "${YELLOW}不支持的发行版，尝试通用安装方法${NC}"
                if [ "$USE_CHINA_SOURCE" = "yes" ]; then
                    curl -fsSL https://get.daocloud.io/docker | sh
                else
                    curl -fsSL https://get.docker.com | sh
                fi
                ;;
        esac
    else
        echo -e "${YELLOW}无法检测发行版，尝试通用安装方法${NC}"
        if [ "$USE_CHINA_SOURCE" = "yes" ]; then
            curl -fsSL https://get.daocloud.io/docker | sh
        else
            curl -fsSL https://get.docker.com | sh
        fi
    fi
}

# 检查本地docker-compose文件
check_local_compose() {
    if [ -f "$LOCAL_COMPOSE_FILE" ]; then
        echo -e "${GREEN}>>> 检测到本地docker-compose文件${NC}"
        chmod +x "$LOCAL_COMPOSE_FILE"
        if "$LOCAL_COMPOSE_FILE" --version &>/dev/null; then
            echo -e "${GREEN}本地docker-compose文件验证通过${NC}"
            return 0
        else
            echo -e "${YELLOW}本地docker-compose文件验证失败${NC}"
            return 1
        fi
    fi
    return 1
}

# 使用本地docker-compose文件
use_local_compose() {
    echo -e "${YELLOW}>>> 使用本地docker-compose文件安装${NC}"
    cp "$LOCAL_COMPOSE_FILE" /usr/local/bin/docker-compose
    chmod +x /usr/local/bin/docker-compose
    ln -sf /usr/local/bin/docker-compose /usr/bin/docker-compose
    echo -e "${GREEN}本地docker-compose安装完成${NC}"
}

# 安装 Docker Compose
install_compose() {
    echo -e "${GREEN}>>> 正在安装 Docker Compose${NC}"
    
    # 定义多个镜像源 (国内优先)
    declare -a MIRRORS=(
        "https://github.com/docker/compose/releases/download"  # 官方源
    )

    # 获取最新版本
    COMPOSE_VERSION=$(curl -s https://api.github.com/repos/docker/compose/releases/latest | grep 'tag_name' | cut -d\" -f4 || echo "v2.24.7")
    
    # 根据源选择优先顺序
    if [ "$USE_CHINA_SOURCE" = "yes" ]; then
        MIRRORS=(
            "https://github.com/docker/compose/releases/download"
        )
    fi

    # 尝试多个下载源
    for mirror in "${MIRRORS[@]}"; do
        echo -e "${YELLOW}尝试从 ${mirror} 下载...${NC}"
        if curl -L "${mirror}/${COMPOSE_VERSION}/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose --connect-timeout 20; then
            echo -e "${GREEN}下载成功！${NC}"
            chmod +x /usr/local/bin/docker-compose
            ln -sf /usr/local/bin/docker-compose /usr/bin/docker-compose
            return 0
        else
            echo -e "${YELLOW}下载失败，尝试下一个镜像源...${NC}"
            rm -f /usr/local/bin/docker-compose 2>/dev/null
        fi
    done

    # 所有下载源尝试失败后，检查本地文件
    if check_local_compose; then
        use_local_compose
        return 0
    fi

    echo -e "${RED}错误：所有镜像源尝试失败且无有效的本地docker-compose文件！${NC}"
    echo -e "${YELLOW}请手动下载并执行以下命令：${NC}"
    echo "curl -L https://github.com/docker/compose/releases/download/v2.24.7/docker-compose-$(uname -s)-$(uname -m) -o /usr/local/bin/docker-compose"
    echo "chmod +x /usr/local/bin/docker-compose"
    echo "ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose"
    exit 1
}

# 启动 Docker 服务
start_docker() {
    echo -e "${YELLOW}>>> 启动 Docker 服务${NC}"
    
    # 检测初始化系统
    if [ -e /proc/1/comm ]; then
        INIT_SYSTEM=$(cat /proc/1/comm)
    else
        INIT_SYSTEM=$(ps -p 1 -o comm=)
    fi

    case $INIT_SYSTEM in
        systemd)
            systemctl enable --now docker
            systemctl restart docker
            ;;
        init|upstart)
            service docker start
            if command -v chkconfig &> /dev/null; then
                chkconfig docker on
            else
                update-rc.d docker defaults
            fi
            ;;
        *)
            echo -e "${YELLOW}非常规初始化系统，尝试直接启动 dockerd${NC}"
            nohup dockerd > /var/log/dockerd.log 2>&1 &
            sleep 5
            ;;
    esac
}

# 配置镜像加速 (仅国内源)
setup_mirror() {
    if [ "$USE_CHINA_SOURCE" = "yes" ]; then
        echo -e "${YELLOW}>>> 配置国内镜像加速${NC}"
        mkdir -p /etc/docker
        if [ -f /etc/docker/daemon.json ]; then
            echo -e "${YELLOW}检测到已存在的 daemon.json 配置，将合并 registry-mirrors${NC}"
            jq '.registry-mirrors |= [
                "https://registry.docker-cn.com",
                "https://hub-mirror.c.163.com",
                "https://mirror.baidubce.com"
            ]' /etc/docker/daemon.json > /tmp/daemon.json && mv /tmp/daemon.json /etc/docker/daemon.json
        else
            cat > /etc/docker/daemon.json <<EOF
{
  "registry-mirrors": [
    "https://registry.docker-cn.com",
    "https://hub-mirror.c.163.com",
    "https://mirror.baidubce.com"
  ],
  "exec-opts": ["native.cgroupdriver=systemd"],
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "100m"
  },
  "storage-driver": "overlay2"
}
EOF
        fi
        systemctl restart docker
    fi
}


# 主函数
main() {
    check_root
    echo -e "${BLUE}"
    echo "=================================="
    echo " Docker 智能安装脚本 (支持本地备用)"
    echo "=================================="
    echo -e "${NC}"
    
    # 选择安装源
    select_source
    
    # 安装流程
    install_deps
    install_docker
    install_compose
    start_docker
    setup_mirror
    
    # 非 systemd 提示
    if [ "$INIT_SYSTEM" != "systemd" ]; then
        echo -e "${YELLOW}注意：检测到您使用的是非 systemd 系统${NC}"
        echo -e "${YELLOW}每次重启后可能需要手动运行: nohup dockerd &${NC}"
    fi
    
    echo -e "${BLUE}"
    echo "=================================="
    echo " 安装完成"
    echo "=================================="
    echo -e "${NC}"
}

main