#!/bin/bash

# ========================================================
# AMS 远程部署脚本（支持多服务部署）
# 功能：从FTP服务器自动下载部署脚本和JAR包，并执行部署
# ========================================================
#
# 使用方法：
#   方式1（推荐，部署所有服务）：
#     wget -O - http://transfer.sangoai.com:8081/ams/new/scripts/remote-deploy.sh | bash
#
#   方式2（管道方式指定服务，无需下载脚本）：
#     wget -O - http://transfer.sangoai.com:8081/ams/new/scripts/remote-deploy.sh | bash -s -- --service ams
#     wget -O - http://transfer.sangoai.com:8081/ams/new/scripts/remote-deploy.sh | bash -s -- -s ams -s ct
#
#   方式3（下载后指定服务）：
#     wget http://transfer.sangoai.com:8081/ams/new/scripts/remote-deploy.sh
#     chmod +x remote-deploy.sh
#     ./remote-deploy.sh --service ams
#     ./remote-deploy.sh -s ams -s gateway
#
#   方式4（查看帮助信息）：
#     wget -O - http://transfer.sangoai.com:8081/ams/new/scripts/remote-deploy.sh | bash -s -- --help
#     # 或下载后查看
#     ./remote-deploy.sh --help
#
# 命令行参数：
#   --service, -s SERVICE    指定要部署的服务名称（可多次使用）
#   --all                    部署所有服务（默认行为）
#   --help, -h               显示帮助信息
#
# 前置条件：
#   - 已安装 wget 或 curl
#   - 有 sudo 权限（需要创建 /data/deploy/ams 目录）
#   - 能访问 http://transfer.sangoai.com:8081 服务器
#   - Docker 环境（可选）：如果未安装，仅下载文件不执行部署
#   - 磁盘至少有 200MB 可用空间（用于下载 JAR 包和脚本）
#
# 服务配置：
#   在脚本的 DOWNLOAD_JARS 数组中配置需要部署的服务
#   格式：远程相对路径:本地完整绝对路径:服务标识符
#   示例：ams-1.0.0-SNAPSHOT.jar:/data/deploy/ams/temp/ams-1.0.0-SNAPSHOT.jar:ams
#   说明：第二个字段是完整的绝对路径，支持不同服务下载到不同目录
#
# FTP服务器部署清单：
#   scripts/ams 目录：.env, compose.yml, deploy-java-jar.sh,
#                     backup_mysql.sh, plugin-deploy.sh, push.sh
#   scripts/base 目录：.env, compose.yml, redis.conf（基础中间件容器配置）
#   jar 目录：各服务的 JAR 包（如 ams-1.0.0-SNAPSHOT.jar）
#
# 部署流程：
#   1. 解析命令行参数，确定部署哪些服务
#   2. 检查系统环境（wget、磁盘空间、Docker）
#   3. 创建部署目录和临时目录
#   4. 下载所有配置文件和脚本（基础容器配置 + 应用脚本）
#   5. 下载指定服务的 JAR 包到 /data/deploy/ams/temp/（每次强制更新）
#   6. 验证所有文件是否下载成功
#
#   如果 Docker 可用：
#   7. 部署基础中间件容器（MySQL、Redis、RabbitMQ、EMQX、TDengine）
#   8. 执行plugin-deploy.sh（从temp复制JAR并部署容器）
#   9. 显示部署摘要
#   10. 设置 MySQL 定时备份任务（每3小时一次）
#
#   如果 Docker 不可用：
#   7. 显示下载文件列表
#   8. 设置 MySQL 定时备份任务（提前配置）
#   9. 提示手动部署步骤
#
# 多服务部署支持：
#   - 支持一次部署多个服务（ams、ct 等）
#   - 支持选择性部署特定服务（--service 参数）
#   - 各服务独立部署，互不影响（AMS 失败不影响 CT）
#   - 各服务有独立的部署逻辑：
#     * AMS: 执行 /data/deploy/ams/plugin-deploy.sh
#     * CT: 执行 /data/deploy/ct/deploy.sh
#   - 部分服务失败不中断流程，最后统一显示结果
#
# 重复执行：
#   - 脚本支持重复执行
#   - 已存在的脚本文件会被跳过（保留用户修改）
#   - JAR包每次都会重新下载（旧包自动备份）
#
# Docker 环境处理：
#   - 无 Docker 时：仅下载文件，不执行部署
#   - 有 Docker 时：完整执行下载和部署流程
#
# 常见问题：
#   1. 磁盘空间不足：清理 Docker 容器日志
#      sudo truncate -s 0 /var/lib/docker/containers/*/*-json.log
#   2. 权限不足：确保有 sudo 权限
#   3. 下载失败：检查网络连接和 FTP 服务器可访问性
#   4. Docker 未安装：文件会正常下载，可后续手动部署
#      快速安装Docker：wget -O - http://transfer.sangoai.com:8081/ams/env/docker/install_docker_online.sh | bash
#   5. 服务名称错误：使用 --help 查看可用的服务列表
# ========================================================

set -e  # 遇到错误立即退出

# ==================== 配置变量 ====================
# 远程服务器地址
REMOTE_SERVER="http://transfer.sangoai.com:8081/ams/new"
REMOTE_JAR_URL="${REMOTE_SERVER}/jar"

# 本地部署目录
LOCAL_BASE_DIR="/data/deploy/base"
#AMS
LOCAL_DEPLOY_DIR="/data/deploy/ams"
LOCAL_AMS_JAR_DIR="${LOCAL_DEPLOY_DIR}/temp"
LOCAL_AMS_WEB_DIR="${LOCAL_DEPLOY_DIR}/web/dist"
LOCAL_AMS_EAP_WEB_DIR="${LOCAL_DEPLOY_DIR}/eap-web/dist"
# CT
LOCAL_CT_DIR="/data/deploy/ct"
LOCAL_CT_WEB_DIR="${LOCAL_CT_DIR}/web/dist"
# Monitor
LOCAL_MONITOR_DIR="/data/deploy/host-monitor"

# JAR 包配置数组（类似 DOWNLOAD_FILES 格式）
# 格式：远程相对路径:本地完整绝对路径:服务标识符
DOWNLOAD_JARS=(
    "ams-1.0.0-SNAPSHOT.jar:${LOCAL_AMS_JAR_DIR}/ams-1.0.0-SNAPSHOT.jar:ams"
    "sg-ct-0.0.1-SNAPSHOT.jar:${LOCAL_CT_DIR}/sg-ct-0.0.1-SNAPSHOT.jar:ct"
    # 未来可添加更多服务到不同目录，例如：
    # "gateway-1.0.0.jar:/data/deploy/gateway/temp/gateway-1.0.0.jar:gateway"
    # "ct-debug-tool-1.0.0.jar:/data/deploy/ct/temp/ct-debug-tool-1.0.0.jar:ct"
)

# Docker 可用性标志
DOCKER_AVAILABLE=false

# 需要部署的服务列表（空数组表示部署所有服务）
DEPLOY_SERVICES=()

# 需要下载的文件列表（格式：远程相对路径:本地绝对路径）
DOWNLOAD_FILES=(
    # 基础容器配置文件
    "scripts/base/.env:${LOCAL_BASE_DIR}/.env"
    "scripts/base/compose.yml:${LOCAL_BASE_DIR}/compose.yml"
    "scripts/base/redis.conf:${LOCAL_BASE_DIR}/redis.conf"

    # 应用部署脚本
    "scripts/ams/.env:${LOCAL_DEPLOY_DIR}/.env"
    "scripts/ams/compose.yml:${LOCAL_DEPLOY_DIR}/compose.yml"
    "scripts/ams/deploy-java-jar.sh:${LOCAL_DEPLOY_DIR}/deploy-java-jar.sh"
    "scripts/ams/backup_mysql.sh:${LOCAL_DEPLOY_DIR}/backup_mysql.sh"
    "scripts/ams/plugin-deploy.sh:${LOCAL_DEPLOY_DIR}/plugin-deploy.sh"
    "scripts/ams/push.sh:${LOCAL_DEPLOY_DIR}/push.sh"

    # 调试工具
    "scripts/ct/.env:${LOCAL_CT_DIR}/.env"
    "scripts/ct/compose.yml:${LOCAL_CT_DIR}/compose.yml"
    "scripts/ct/deploy.sh:${LOCAL_CT_DIR}/deploy.sh"

    # host-monitor
    "scripts/host-monitor/compose.yml:${LOCAL_MONITOR_DIR}/compose.yml"
    "scripts/host-monitor/deploy.sh:${LOCAL_MONITOR_DIR}/deploy.sh"
)

# ==================== 颜色输出 ====================
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color

log_info() {
    echo -e "${GREEN}[INFO]${NC} $1"
}

log_warn() {
    echo -e "${YELLOW}[WARN]${NC} $1"
}

log_error() {
    echo -e "${RED}[ERROR]${NC} $1"
}

# ==================== 命令行参数解析 ====================

# 显示使用说明
show_usage() {
    cat << EOF
========================================================
AMS 远程部署脚本
========================================================

用法: $0 [选项]

选项:
  --service, -s SERVICE    指定要部署的服务名称（可多次使用）
  --all                    部署所有服务（默认行为）
  --help, -h               显示此帮助信息

示例:
  # 部署所有服务
  $0
  wget -O - http://transfer.sangoai.com:8081/ams/new/scripts/remote-deploy.sh | bash

  # 管道方式部署单个服务（无需下载脚本）
  wget -O - http://transfer.sangoai.com:8081/ams/new/scripts/remote-deploy.sh | bash -s -- --service ams

  # 管道方式部署多个服务
  wget -O - http://transfer.sangoai.com:8081/ams/new/scripts/remote-deploy.sh | bash -s -- -s ams -s ct

  # 下载后部署指定服务
  $0 --service ams
  $0 -s ams -s gateway

可用服务列表:
EOF
    for jar_mapping in "${DOWNLOAD_JARS[@]}"; do
        IFS=':' read -r _ _ service_name <<< "$jar_mapping"
        echo "  - ${service_name}"
    done
    echo ""
}

# 解析命令行参数
parse_arguments() {
    while [[ $# -gt 0 ]]; do
        case $1 in
            --service|-s)
                if [ -z "$2" ]; then
                    log_error "选项 --service 需要一个参数"
                    show_usage
                    exit 1
                fi
                DEPLOY_SERVICES+=("$2")
                shift 2
                ;;
            --all)
                DEPLOY_SERVICES=()  # 清空，表示全部部署
                shift
                ;;
            --help|-h)
                show_usage
                exit 0
                ;;
            *)
                log_error "未知参数: $1"
                show_usage
                exit 1
                ;;
        esac
    done
}

# 过滤需要部署的服务
filter_services() {
    if [ ${#DEPLOY_SERVICES[@]} -eq 0 ]; then
        # 部署所有服务
        log_info "将部署所有服务"
        return 0
    fi

    # 验证指定的服务是否存在
    local valid_services=()
    for jar_mapping in "${DOWNLOAD_JARS[@]}"; do
        IFS=':' read -r _ _ service_name <<< "$jar_mapping"
        valid_services+=("$service_name")
    done

    # 检查用户指定的服务是否有效
    for target_service in "${DEPLOY_SERVICES[@]}"; do
        local found=false
        for valid_service in "${valid_services[@]}"; do
            if [ "$target_service" = "$valid_service" ]; then
                found=true
                break
            fi
        done

        if [ "$found" = false ]; then
            log_error "未找到服务: ${target_service}"
            log_info "可用服务列表:"
            for service in "${valid_services[@]}"; do
                log_info "  - ${service}"
            done
            exit 1
        fi
    done

    log_info "将部署以下服务: ${DEPLOY_SERVICES[*]}"
}

# 检查 JAR 包是否需要部署
should_deploy_jar() {
    local service_name=$1

    # 如果 DEPLOY_SERVICES 为空，部署所有服务
    if [ ${#DEPLOY_SERVICES[@]} -eq 0 ]; then
        return 0
    fi

    # 检查服务是否在部署列表中
    for target_service in "${DEPLOY_SERVICES[@]}"; do
        if [ "$service_name" = "$target_service" ]; then
            return 0
        fi
    done

    return 1
}


# ==================== 函数定义 ====================

# 检查磁盘空间
check_disk_space() {
    log_info "========================================================="
    log_info "检查磁盘空间..."
    log_info "========================================================="

    # 获取根分区可用空间（MB）
    local available_space=$(df -m / | awk 'NR==2 {print $4}')
    local used_percent=$(df -h / | awk 'NR==2 {print $5}' | tr -d '%')
    local total_space=$(df -h / | awk 'NR==2 {print $2}')
    local used_space=$(df -h / | awk 'NR==2 {print $3}')

    log_info "磁盘使用情况："
    log_info "  总空间: ${total_space}"
    log_info "  已使用: ${used_space} (${used_percent}%)"
    log_info "  可用空间: ${available_space} MB"

    # 检查是否有足够空间（至少需要 200MB）
    local required_space=200
    if [ "${available_space}" -lt "${required_space}" ]; then
        log_error "磁盘空间不足！"
        log_error "  需要至少: ${required_space} MB"
        log_error "  当前可用: ${available_space} MB"
        log_error ""
        log_error "解决方案："
        log_error "  1. 清理 Docker 容器日志："
        log_error "     sudo truncate -s 0 /var/lib/docker/containers/*/*-json.log"
        log_error "  2. 清理 Docker 未使用的资源："
        log_error "     docker system prune -a --volumes"
        log_error "  3. 查看占用空间最大的目录："
        log_error "     sudo du -h --max-depth=1 / 2>/dev/null | sort -hr | head -20"
        return 1
    fi

    # 如果空间小于 1GB，给出警告
    if [ "${available_space}" -lt 1024 ]; then
        log_warn "磁盘可用空间较少 (${available_space} MB)，建议清理"
    else
        log_info "✓ 磁盘空间充足"
    fi

    return 0
}

# 创建本地目录
create_local_directories() {
    log_info "创建本地部署目录..."
    sudo mkdir -p "${LOCAL_DEPLOY_DIR}"
    sudo mkdir -p "${LOCAL_AMS_JAR_DIR}"
    sudo mkdir -p "${LOCAL_AMS_WEB_DIR}"
    sudo mkdir -p "${LOCAL_AMS_EAP_WEB_DIR}"
    sudo mkdir -p "${LOCAL_BASE_DIR}"
    sudo mkdir -p "${LOCAL_CT_DIR}"
    sudo mkdir -p "${LOCAL_CT_WEB_DIR}"
    sudo mkdir -p "${LOCAL_MONITOR_DIR}"

    # 修改目录权限为当前用户
    local current_user=$(whoami)
    sudo chown -R "${current_user}:${current_user}" "${LOCAL_DEPLOY_DIR}"
    sudo chown -R "${current_user}:${current_user}" "${LOCAL_BASE_DIR}"
    sudo chown -R "${current_user}:${current_user}" "${LOCAL_CT_DIR}"
    sudo chown -R "${current_user}:${current_user}" "${LOCAL_MONITOR_DIR}"
    sudo chmod -R 755 "${LOCAL_DEPLOY_DIR}"
    sudo chmod -R 755 "${LOCAL_BASE_DIR}"
    sudo chmod -R 755 "${LOCAL_CT_DIR}"
    sudo chmod -R 755 "${LOCAL_MONITOR_DIR}"

    log_info "目录创建完成: ${LOCAL_DEPLOY_DIR}"
    log_info "JAR临时目录: ${LOCAL_AMS_JAR_DIR}"
    log_info "AMS前端目录: ${LOCAL_AMS_WEB_DIR}"
    log_info "AMS EAP前端目录: ${LOCAL_AMS_EAP_WEB_DIR}"
    log_info "基础容器目录: ${LOCAL_BASE_DIR}"
    log_info "CT基础容器目录: ${LOCAL_CT_DIR}"
    log_info "CT前端目录: ${LOCAL_CT_WEB_DIR}"
    log_info "MONITOR基础容器目录: ${LOCAL_MONITOR_DIR}"
    log_info "✓ 已修改目录权限为当前用户: ${current_user}"
}

# 通用下载文件函数
download_files() {
    log_info "========================================================="
    log_info "开始下载配置文件和脚本..."
    log_info "========================================================="

    local download_count=0
    local skip_count=0
    local failed_count=0

    for file_mapping in "${DOWNLOAD_FILES[@]}"; do
        # 解析 "远程相对路径:本地绝对路径"
        local remote_path="${file_mapping%%:*}"
        local local_path="${file_mapping##*:}"
        local filename=$(basename "${local_path}")

        # 如果文件已存在，跳过下载
        if [ -f "${local_path}" ]; then
            log_warn "文件已存在，跳过下载: ${filename}"
            ((skip_count++))

            # 为 .sh 脚本添加执行权限（如果尚未添加）
            if [[ "${filename}" == *.sh ]]; then
                chmod +x "${local_path}"
            fi
        else
            log_info "下载: ${filename}"
            log_info "  从: ${REMOTE_SERVER}/${remote_path}"
            log_info "  到: ${local_path}"

            # 确保目标目录存在
            local_dir=$(dirname "${local_path}")
            sudo mkdir -p "${local_dir}"

            # 下载文件
            if wget -q --show-progress -O "${local_path}" "${REMOTE_SERVER}/${remote_path}"; then
                log_info "✓ ${filename} 下载成功"
                ((download_count++))

                # 为 .sh 脚本添加执行权限
                if [[ "${filename}" == *.sh ]]; then
                    chmod +x "${local_path}"
                    log_info "  已添加执行权限"
                fi
            else
                log_error "✗ ${filename} 下载失败"
                ((failed_count++))
            fi
        fi
        echo ""
    done

    log_info "下载完成统计:"
    log_info "  新下载: ${download_count} 个文件"
    log_info "  已跳过: ${skip_count} 个文件"

    if [ ${failed_count} -gt 0 ]; then
        log_error "  失败: ${failed_count} 个文件"
        return 1
    fi

    log_info "✓ 所有配置文件和脚本下载完成"
    return 0
}

# 部署 Host Monitor 服务
deploy_monitor_service() {
    log_info "开始部署 Host Monitor 服务..."
    log_info "  部署目录: ${LOCAL_MONITOR_DIR}"
    log_info "  部署脚本: deploy.sh"

    cd "${LOCAL_MONITOR_DIR}"

    if [ ! -f "deploy.sh" ]; then
        log_error "✗ Host Monitor 部署脚本不存在: ${LOCAL_MONITOR_DIR}/deploy.sh"
        return 1
    fi

    # 执行部署脚本
    if bash ./deploy.sh; then
        log_info "✓ Host Monitor 服务部署成功"
        return 0
    else
        log_error "✗ Host Monitor 服务部署失败"
        return 1
    fi
}

# 部署基础中间件容器
deploy_base_containers() {
    log_info "========================================================="
    log_info "开始部署基础中间件容器..."
    log_info "========================================================="

    cd "${LOCAL_BASE_DIR}"

    # 检查必要文件是否存在
    if [ ! -f "compose.yml" ]; then
        log_error "缺少 compose.yml 文件，无法部署基础容器"
        return 1
    fi

    log_info "执行: docker compose up -d"
    log_info "  即将部署: MySQL、Redis、RabbitMQ、EMQX、TDengine"

    # 使用 docker compose 部署容器
    if docker compose up -d; then
        log_info "✓ 基础中间件容器部署成功"

        # 显示容器状态
        echo ""
        log_info "容器状态:"
        docker compose ps

        echo ""
        log_info "等待容器启动完成..."
        sleep 5

    else
        log_error "✗ 基础中间件容器部署失败"
        return 1
    fi

    return 0
}

# 下载 JAR 包（支持多个 JAR 包到不同目录）
download_jars() {
    log_info "========================================================="
    log_info "开始下载 JAR 包..."
    log_info "========================================================="

    local total_jars=${#DOWNLOAD_JARS[@]}
    local download_count=0
    local skip_count=0
    local failed_count=0
    local failed_services=()

    for jar_mapping in "${DOWNLOAD_JARS[@]}"; do
        # 解析 "远程相对路径:本地完整绝对路径:服务标识符"
        IFS=':' read -r remote_path local_full_path service_name <<< "$jar_mapping"

        # 检查是否需要下载此 JAR 包
        if ! should_deploy_jar "$service_name"; then
            log_warn "跳过服务: ${service_name}"
            ((skip_count++))
            continue
        fi

        # 从完整路径中提取目录和文件名
        local target_dir=$(dirname "$local_full_path")
        local filename=$(basename "$local_full_path")

        log_info "下载服务: ${service_name}"
        log_info "  JAR 包: ${filename}"
        log_info "  从: ${REMOTE_JAR_URL}/${remote_path}"
        log_info "  到: ${local_full_path}"

        # 创建目标目录（如果不存在）
        if [ ! -d "$target_dir" ]; then
            sudo mkdir -p "$target_dir"
            local current_user=$(whoami)
            sudo chown -R "${current_user}:${current_user}" "$target_dir"
            sudo chmod -R 755 "$target_dir"
            log_info "  ✓ 已创建目录: ${target_dir}"
        fi

        # 如果已存在旧JAR包，先备份
        if [ -f "$local_full_path" ]; then
            timestamp=$(date +"%Y%m%d_%H%M%S")
            backup_name="${target_dir}/${filename%.jar}.${timestamp}.jar.old"
            sudo mv "$local_full_path" "$backup_name"
            log_warn "  已备份旧 JAR 包为: ${backup_name}"
        fi

        # 下载新JAR包到指定的完整路径
        if sudo wget -q --show-progress -O "$local_full_path" "${REMOTE_JAR_URL}/${remote_path}"; then
            log_info "✓ ${filename} 下载成功"

            # 修改JAR包权限为当前用户
            local current_user=$(whoami)
            sudo chown "${current_user}:${current_user}" "$local_full_path"
            sudo chmod 644 "$local_full_path"
            log_info "  ✓ 已修改 JAR 包权限为当前用户: ${current_user}"

            # 显示 JAR 包信息
            jar_size=$(du -h "$local_full_path" | cut -f1)
            log_info "  文件大小: ${jar_size}"

            # 显示 MD5 值（如果有md5sum命令）
            if command -v md5sum &> /dev/null; then
                jar_md5=$(md5sum "$local_full_path" | cut -d' ' -f1)
                log_info "  MD5: ${jar_md5}"
            fi

            ((download_count++))
        else
            log_error "✗ ${filename} 下载失败"
            failed_services+=("${service_name}")
            ((failed_count++))
        fi
        echo ""
    done

    log_info "下载完成统计:"
    log_info "  总 JAR 包数: ${total_jars}"
    log_info "  成功下载: ${download_count} 个"
    log_info "  跳过: ${skip_count} 个"

    if [ ${failed_count} -gt 0 ]; then
        log_error "  失败: ${failed_count} 个"
        log_error "  失败服务: ${failed_services[*]}"
        return 1
    fi

    echo ""
    log_info "✓ JAR 包下载完成"
    return 0
}

# 验证下载的文件
verify_downloads() {
    log_info "========================================================="
    log_info "验证下载的文件..."
    log_info "========================================================="

    local all_ok=true

    # 验证配置文件和脚本
    log_info "验证配置文件和脚本..."
    for file_mapping in "${DOWNLOAD_FILES[@]}"; do
        local local_path="${file_mapping##*:}"
        local filename=$(basename "${local_path}")

        if [ ! -f "${local_path}" ]; then
            log_error "缺少文件: ${filename} (${local_path})"
            all_ok=false
        fi
    done

    # 验证所有需要部署的 JAR 包
    echo ""
    log_info "验证 JAR 包..."
    for jar_mapping in "${DOWNLOAD_JARS[@]}"; do
        IFS=':' read -r _ local_full_path service_name <<< "$jar_mapping"

        # 只验证需要部署的 JAR 包
        if ! should_deploy_jar "$service_name"; then
            continue
        fi

        if [ ! -f "${local_full_path}" ]; then
            log_error "缺少 JAR 包: ${service_name} - ${local_full_path}"
            all_ok=false
        else
            log_info "✓ ${service_name}: ${local_full_path}"
        fi
    done

    if [ "$all_ok" = true ]; then
        echo ""
        log_info "✓ 所有文件验证通过"
        return 0
    else
        echo ""
        log_error "✗ 文件验证失败"
        return 1
    fi
}

# 检查 Docker 环境
check_docker_environment() {
    log_info "========================================================="
    log_info "检查 Docker 环境..."
    log_info "========================================================="

    # 检查 docker 命令是否存在
    if ! command -v docker &> /dev/null; then
        log_warn "未安装 Docker！"
        log_warn "文件将正常下载，但不会执行部署操作"
        log_warn ""
        log_warn "如需部署功能，可使用以下方式安装 Docker："
        log_warn ""
        log_warn "方式1（推荐，一键安装）："
        log_warn "  wget -O - http://transfer.sangoai.com:8081/ams/env/docker/install_docker_and_newgrp.sh | bash"
        log_warn ""
        log_warn "方式2（手动安装）："
        log_warn "  - CentOS/RHEL: curl -fsSL https://get.docker.com | bash"
        log_warn "  - Ubuntu/Debian: curl -fsSL https://get.docker.com | bash"
        log_warn "  - 官方文档: https://docs.docker.com/engine/install/"
        DOCKER_AVAILABLE=false
        return 0  # 返回成功，不中断流程
    fi

    log_info "✓ Docker 已安装"

    # 检查 docker 服务是否运行
    if ! sudo docker info &> /dev/null; then
        log_warn "Docker 服务未运行！"
        log_warn "文件将正常下载，但不会执行部署操作"
        log_warn ""
        log_warn "如需部署功能，请启动 Docker 服务："
        log_warn "  - systemctl start docker"
        log_warn "  - service docker start"
        DOCKER_AVAILABLE=false
        return 0  # 返回成功，不中断流程
    fi

    log_info "✓ Docker 服务正在运行"

    # 显示 Docker 版本信息
    docker_version=$(docker --version 2>/dev/null || echo "未知版本")
    log_info "  Docker 版本: ${docker_version}"

    # 检查 docker compose 是否可用
    if docker compose version &> /dev/null; then
        compose_version=$(docker compose version --short 2>/dev/null || echo "未知版本")
        log_info "✓ Docker Compose 可用 (${compose_version})"
        DOCKER_AVAILABLE=true
    elif command -v docker-compose &> /dev/null; then
        compose_version=$(docker-compose --version 2>/dev/null || echo "未知版本")
        log_info "✓ Docker Compose 可用 (${compose_version})"
        DOCKER_AVAILABLE=true
    else
        log_warn "未检测到 Docker Compose，部署可能失败"
        DOCKER_AVAILABLE=false
    fi

    if [ "$DOCKER_AVAILABLE" = true ]; then
        log_info "✓ Docker 环境检查通过"
    else
        log_warn "⚠ Docker 环境不完整，仅执行文件下载操作"
    fi
    return 0
}

# 执行部署脚本
execute_deployment() {
    log_info "========================================================="
    log_info "开始执行部署..."
    log_info "========================================================="

    local total_services=0
    local success_count=0
    local failed_count=0
    local skip_count=0
    local failed_services=()

    # 遍历所有服务进行部署
    for jar_mapping in "${DOWNLOAD_JARS[@]}"; do
        IFS=':' read -r _ _ service_name <<< "$jar_mapping"

        ((total_services++))

        # 检查是否需要部署此服务
        if ! should_deploy_jar "$service_name"; then
            log_warn "跳过部署服务: ${service_name}"
            ((skip_count++))
            continue
        fi

        log_info "========================================================="
        log_info "部署服务: ${service_name}"
        log_info "========================================================="

        # 根据服务名称调用不同的部署函数
        case "$service_name" in
            ams)
                if deploy_ams_service; then
                    ((success_count++))
                else
                    ((failed_count++))
                    failed_services+=("ams")
                fi
                ;;
            ct)
                if deploy_ct_service; then
                    ((success_count++))
                else
                    ((failed_count++))
                    failed_services+=("ct")
                fi
                ;;
            *)
                log_error "未知服务: ${service_name}，跳过部署"
                ((failed_count++))
                failed_services+=("${service_name}")
                ;;
        esac

        echo ""
    done

    # 显示部署统计
    log_info "========================================================="
    log_info "部署完成统计"
    log_info "========================================================="
    log_info "总服务数: ${total_services}"
    log_info "成功: ${success_count}"
    log_info "跳过: ${skip_count}"
    log_info "失败: ${failed_count}"

    if [ ${failed_count} -gt 0 ]; then
        log_error "失败服务: ${failed_services[*]}"
        log_error "========================================================="
        return 1
    fi

    log_info "✓ 所有服务部署成功！"
    log_info "========================================================="
    return 0
}

# 部署 AMS 服务
deploy_ams_service() {
    log_info "开始部署 AMS 服务..."
    log_info "  部署目录: ${LOCAL_DEPLOY_DIR}"

    cd "${LOCAL_DEPLOY_DIR}"

    local backend_success=false
    local frontend_success=false

    # ============ 步骤1: 部署后端 JAR 包 ============
    log_info "步骤1: 部署 AMS 后端服务（JAR包）..."

    if [ ! -f "plugin-deploy.sh" ]; then
        log_error "✗ AMS 部署脚本不存在: ${LOCAL_DEPLOY_DIR}/plugin-deploy.sh"
    else
        export JAR_NAME="ams-1.0.0-SNAPSHOT.jar"

        if bash ./plugin-deploy.sh; then
            log_info "✓ AMS 后端服务部署成功"
            backend_success=true
        else
            log_error "✗ AMS 后端服务部署失败"
        fi
    fi

    echo ""

    # ============ 步骤2: 部署前端项目（无论后端是否成功） ============
    log_info "步骤2: 部署 AMS 前端项目（ams-front）..."

    if docker compose up ams-front -d; then
        log_info "✓ AMS 前端项目部署成功"
        frontend_success=true
    else
        log_error "✗ AMS 前端项目部署失败"
    fi

    # ============ 判断整体结果 ============
    if [ "$backend_success" = true ] && [ "$frontend_success" = true ]; then
        log_info "✓ AMS 服务（后端+前端）全部部署成功"
        return 0
    elif [ "$backend_success" = true ] || [ "$frontend_success" = true ]; then
        log_warn "⚠ AMS 服务部分部署成功（后端:${backend_success} 前端:${frontend_success}）"
        return 0  # 部分成功也算成功
    else
        log_error "✗ AMS 服务（后端+前端）全部部署失败"
        return 1  # 全部失败才返回错误
    fi
}

# 部署 CT 服务
deploy_ct_service() {
    log_info "开始部署 CT 服务..."
    log_info "  部署目录: ${LOCAL_CT_DIR}"
    log_info "  部署脚本: deploy.sh"

    cd "${LOCAL_CT_DIR}"

    if [ ! -f "deploy.sh" ]; then
        log_error "✗ CT 部署脚本不存在: ${LOCAL_CT_DIR}/deploy.sh"
        return 1
    fi

    # 执行部署脚本
    if bash ./deploy.sh; then
        log_info "✓ CT 服务部署成功"
        return 0
    else
        log_error "✗ CT 服务部署失败"
        return 1
    fi
}

# 显示部署摘要
show_summary() {
    log_info "========================================================="
    log_info "部署摘要"
    log_info "========================================================="
    log_info "部署目录: ${LOCAL_DEPLOY_DIR}"
    log_info "JAR 包: ${JAR_NAME}"
    log_info "远程服务器: ${REMOTE_SERVER}"
    log_info ""
    log_info "部署的文件列表:"
    ls -lh "${LOCAL_DEPLOY_DIR}" | grep -E '\.(sh|yml|env|jar)$' || true
    log_info "========================================================="
}

# 设置 MySQL 定时备份任务
setup_mysql_backup_cron() {
    log_info "========================================================="
    log_info "设置 MySQL 定时备份任务..."
    log_info "========================================================="

    local backup_script="${LOCAL_DEPLOY_DIR}/backup_mysql.sh"
    local cron_schedule="0 */3 * * *"
    local cron_job="${cron_schedule} ${backup_script}"

    # 检查备份脚本是否存在
    if [ ! -f "${backup_script}" ]; then
        log_warn "备份脚本不存在: ${backup_script}"
        log_warn "跳过 cron 任务设置"
        return 0
    fi

    # 检查当前 crontab 中是否已存在该任务
    if crontab -l 2>/dev/null | grep -q "${backup_script}"; then
        log_warn "MySQL 备份任务已存在于 crontab 中"

        # 显示现有的相关任务
        log_info "现有的备份任务:"
        crontab -l 2>/dev/null | grep "${backup_script}" | while read -r line; do
            log_info "  ${line}"
        done

        return 0
    fi

    # 添加 cron 任务
    log_info "添加定时任务: ${cron_job}"
    log_info "执行频率: 每3小时一次"

    if (crontab -l 2>/dev/null; echo "${cron_job}") | crontab -; then
        log_info "✓ MySQL 定时备份任务添加成功"

        # 验证任务已添加
        echo ""
        log_info "当前 crontab 任务列表:"
        crontab -l | while read -r line; do
            log_info "  ${line}"
        done
    else
        log_error "✗ 添加 cron 任务失败"
        return 1
    fi

    return 0
}

# ==================== 主流程 ====================

main() {
    log_info "========================================================="
    log_info "AMS 远程自动部署脚本"
    log_info "========================================================="
    log_info "开始时间: $(date '+%Y-%m-%d %H:%M:%S')"
    log_info ""

    # 解析命令行参数
    parse_arguments "$@"

    # 检查 wget 是否安装
    if ! command -v wget &> /dev/null; then
        log_error "未安装 wget 命令，请先安装: yum install -y wget 或 apt-get install -y wget"
        exit 1
    fi

    # 0. 检查磁盘空间
    check_disk_space || exit 1
    echo ""

    # 1. 检查 Docker 环境（不会中断流程）
    check_docker_environment
    echo ""

    # 2. 创建本地目录
    create_local_directories || exit 1
    echo ""

    # 3. 过滤需要部署的服务
    filter_services
    echo ""

    # 4. 下载配置文件和脚本（基础容器 + 应用脚本）
    download_files || exit 1
    echo ""

    # 5. 下载 JAR 包（总是执行下载）
    download_jars || exit 1
    echo ""

    # 6. 验证下载的文件
    verify_downloads || exit 1
    echo ""

    # ========== 以下为需要 Docker 的部署操作 ==========
    if [ "$DOCKER_AVAILABLE" = true ]; then
        log_info "开始执行容器部署操作..."
        echo ""

        # 优先部署 Host Monitor（失败不影响后续流程）
        log_info "========================================================="
        log_info "优先部署: Host Monitor 监控服务"
        log_info "========================================================="
        if deploy_monitor_service; then
            log_info "✓ Host Monitor 部署成功"
        else
            log_warn "⚠ Host Monitor 部署失败，继续后续流程"
        fi
        echo ""

        # 6. 部署基础中间件容器
        deploy_base_containers || exit 1
        echo ""

        # 7. 执行 Java 应用部署
        execute_deployment || exit 1
        echo ""

        # 8. 显示摘要
        show_summary
        echo ""

        # 9. 设置 MySQL 定时备份任务
        setup_mysql_backup_cron
        echo ""

        log_info "结束时间: $(date '+%Y-%m-%d %H:%M:%S')"
        log_info "========================================================="
        log_info "✓ 部署流程全部完成！"
        log_info "========================================================="
    else
        # Docker 不可用时的摘要
        log_info "========================================================="
        log_info "下载摘要"
        log_info "========================================================="
        log_info "下载目录: ${LOCAL_DEPLOY_DIR}"
        log_info "JAR 包: ${JAR_NAME}"
        log_info "远程服务器: ${REMOTE_SERVER}"
        log_info ""
        log_info "已下载的文件列表:"
        ls -lh "${LOCAL_DEPLOY_DIR}" | grep -E '\.(sh|yml|env|jar)$' || true
        log_info ""
        log_info "基础容器配置文件:"
        ls -lh "${LOCAL_BASE_DIR}" | grep -E '\.(yml|env|conf)$' || true
        log_info "========================================================="
        echo ""

        # 设置 MySQL 定时备份任务（即使 Docker 不可用也可以提前设置）
        setup_mysql_backup_cron
        echo ""

        log_warn "结束时间: $(date '+%Y-%m-%d %H:%M:%S')"
        log_warn "========================================================="
        log_warn "⚠ 文件下载完成！由于 Docker 环境不可用，未执行部署操作"
        log_warn ""
        log_warn "⚠ 快速安装 Docker（推荐）："
        log_warn "   wget -O - http://transfer.sangoai.com:8081/ams/env/docker/install_docker_online.sh | bash"
        log_warn ""
        log_warn "⚠ 安装 Docker 后，可以手动执行以下命令进行部署："
        log_warn "   1. 部署基础容器: cd ${LOCAL_BASE_DIR} && docker compose up -d"
        log_warn "   2. 部署应用: cd ${LOCAL_DEPLOY_DIR} && bash plugin-deploy.sh"
        log_warn "========================================================="
    fi
}

# 执行主流程
main "$@"