#!/bin/bash
# ============================================================
# Troubleshoot AI Assistant — Docker 部署脚本
# 在 5.60 服务器上执行
# ============================================================
# 前置条件：
#   1. 服务器已安装 Docker
#   2. 项目代码已上传到服务器（或从构建机 scp 镜像）
#   3. /opt/troubleshoot/.env 已配置（SECRET_KEY 等）
#
# 使用方式：
#   ./docker_deploy.sh              # 构建并启动
#   ./docker_deploy.sh --build-only # 仅构建镜像
#   ./docker_deploy.sh --stop       # 停止容器
#   ./docker_deploy.sh --status     # 查看状态
#   ./docker_deploy.sh --update-fe  # 仅更新前端（替换 dist，不重建镜像）
# ============================================================

set -euo pipefail

# 配置
CONTAINER_NAME="troubleshoot"
IMAGE_NAME="troubleshoot:latest"
DATA_BASE="/opt/troubleshoot"
ENV_FILE="${DATA_BASE}/.env"
DIST_DIR="${DATA_BASE}/dist"

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

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

# ---------- 前置检查 ----------
check_prerequisites() {
    info "检查前置条件..."

    # Docker 是否安装
    if ! command -v docker &> /dev/null; then
        error "Docker 未安装，请先安装: sudo apt install docker.io"
    fi
    info "Docker: $(docker --version)"

    # 当前用户是否有 Docker 权限
    if ! docker ps &> /dev/null; then
        error "当前用户无 Docker 权限，请将用户加入 docker 组: sudo usermod -aG docker $USER"
    fi

    # .env 文件是否存在
    if [ ! -f "${ENV_FILE}" ]; then
        warn ".env 文件不存在: ${ENV_FILE}"
        warn "请创建并配置 SECRET_KEY 等环境变量"
        mkdir -p "${DATA_BASE}"
        cat > "${ENV_FILE}" << 'EOF'
# 必填
SECRET_KEY=your_secret_key_here

# Claude API（离线模式可留空）
CLAUDE_API_BASE=
CLAUDE_API_KEY=

# 离线模式（true=不调 Claude API）
OFFLINE_MODE=true

# 服务监测加密密钥（可选，不设则从 SECRET_KEY 派生）
MONITOR_ENC_KEY=
EOF
        warn "已创建模板 ${ENV_FILE}，请编辑后重新运行"
        exit 1
    fi
    info ".env 文件: ${ENV_FILE}"
}

# ---------- 准备数据目录 ----------
prepare_dirs() {
    info "准备数据目录..."

    # 监测数据目录
    mkdir -p "${DATA_BASE}/monitor-data/reports"

    # 用户数据（首次部署时初始化空文件）
    if [ ! -f "${DATA_BASE}/data/users.json" ]; then
        mkdir -p "${DATA_BASE}/data"
        echo '{"users":[]}' > "${DATA_BASE}/data/users.json"
        info "已初始化空 users.json"
    fi

    # 日志目录
    mkdir -p "${DATA_BASE}/logs"

    # 前端 dist 目录（首次部署时由镜像构建填充，volume 挂载后覆盖）
    mkdir -p "${DIST_DIR}"

    # 搜索索引（如果存在旧部署的索引，复制过来）
    if [ -f "${DATA_BASE}/搜索索引.json" ] && [ ! -f "${DATA_BASE}/data/搜索索引.json" ]; then
        cp "${DATA_BASE}/搜索索引.json" "${DATA_BASE}/data/搜索索引.json"
        info "已复制搜索索引到 data/"
    fi

    # 搜索向量（可选）
    if [ -f "${DATA_BASE}/搜索向量.json" ] && [ ! -f "${DATA_BASE}/data/搜索向量.json" ]; then
        cp "${DATA_BASE}/搜索向量.json" "${DATA_BASE}/data/搜索向量.json"
        info "已复制搜索向量到 data/"
    fi

    info "数据目录准备完成"
}

# ---------- 构建镜像 ----------
build_image() {
    info "构建 Docker 镜像（多阶段：Node 构建 Vue + Python Flask）..."
    docker build -t "${IMAGE_NAME}" .
    info "镜像构建完成: ${IMAGE_NAME}"
}

# ---------- 启动容器 ----------
start_container() {
    # 检查是否有同名容器在运行
    if docker ps -a --format '{{.Names}}' | grep -q "^${CONTAINER_NAME}$"; then
        info "停止并移除旧容器..."
        docker stop "${CONTAINER_NAME}" 2>/dev/null || true
        docker rm "${CONTAINER_NAME}" 2>/dev/null || true
    fi

    info "启动容器..."
    docker run -d \
        --name "${CONTAINER_NAME}" \
        --restart unless-stopped \
        -p 8088:80 \
        -v "${DATA_BASE}/monitor-data:/app/web/service_monitor/data" \
        -v "${DATA_BASE}/data/users.json:/app/web/users.json" \
        -v "${DATA_BASE}/data/搜索索引.json:/app/data/搜索索引.json:ro" \
        -v "${DATA_BASE}/data/搜索向量.json:/app/data/搜索向量.json:ro" \
        -v "${DIST_DIR}:/data/dist" \
        -v "${DATA_BASE}/logs:/app/web/logs" \
        --env-file "${ENV_FILE}" \
        -e FLASK_DEBUG=0 \
        -e TROUBLESHOOT_ROOT=/app \
        -e PYTHONIOENCODING=utf-8 \
        --memory=1g \
        --cpus=1.0 \
        "${IMAGE_NAME}"

    info "容器已启动: ${CONTAINER_NAME}"
}

# ---------- 仅更新前端 ----------
update_frontend() {
    if ! docker ps --format '{{.Names}}' | grep -q "^${CONTAINER_NAME}$"; then
        error "容器 ${CONTAINER_NAME} 未运行，请先部署"
    fi

    info "从容器中提取前端 dist..."
    # 先从镜像中复制最新的 dist 到宿主机
    docker cp "${CONTAINER_NAME}:/data/dist/." "${DIST_DIR}/"

    info "前端已更新（volume 挂载，无需重启容器）"
    info "如需强制刷新，可重启 nginx: docker exec ${CONTAINER_NAME} nginx -s reload"
}

# ---------- 健康检查 ----------
health_check() {
    info "等待服务启动..."
    local max_retries=15
    local count=0

    while [ $count -lt $max_retries ]; do
        if curl -sf http://localhost:8088/api/health > /dev/null 2>&1; then
            info "服务健康检查通过！"
            echo ""
            curl -s http://localhost:8088/api/health | python3 -m json.tool 2>/dev/null || \
                curl -s http://localhost:8088/api/health
            echo ""
            info "访问地址: http://$(hostname -I 2>/dev/null | awk '{print $1}' || echo '192.168.5.60')"
            return 0
        fi
        count=$((count + 1))
        echo "  等待中... ($count/$max_retries)"
        sleep 2
    done

    error "健康检查失败，请查看日志: docker logs ${CONTAINER_NAME}"
}

# ---------- 查看状态 ----------
show_status() {
    info "容器状态:"
    docker ps -f "name=${CONTAINER_NAME}" --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}" 2>/dev/null || \
        warn "容器 ${CONTAINER_NAME} 不存在"
    echo ""
    info "服务健康:"
    curl -sf http://localhost:8088/api/health | python3 -m json.tool 2>/dev/null || \
        warn "服务未响应"
}

# ---------- 停止容器 ----------
stop_container() {
    info "停止容器 ${CONTAINER_NAME}..."
    docker stop "${CONTAINER_NAME}" 2>/dev/null || warn "容器未在运行"
    docker rm "${CONTAINER_NAME}" 2>/dev/null || true
    info "容器已停止并移除"
}

# ---------- 主流程 ----------
main() {
    local action="${1:-deploy}"

    case "${action}" in
        --build-only)
            check_prerequisites
            build_image
            ;;
        --stop)
            stop_container
            ;;
        --status)
            show_status
            ;;
        --update-fe)
            update_frontend
            ;;
        deploy|"")
            check_prerequisites
            prepare_dirs
            build_image
            start_container
            health_check
            ;;
        *)
            echo "用法: $0 [--build-only|--stop|--status|--update-fe]"
            exit 1
            ;;
    esac
}

main "$@"
