#!/bin/bash

##############################################
# Urban Lifeline - 构建和打包脚本
# 
# 功能：
# 1. 编译后端/前端项目
# 2. 构建 Docker 镜像
# 3. 导出镜像到 tar 文件
#
# 使用方法：
#   ./build.sh [target] [options]
#
# 目标(target)：
#   base       - 构建基础镜像
#   serv       - 构建所有后端服务镜像
#   web        - 构建前端镜像
#   all        - 构建所有镜像（默认）
#   gateway    - 构建单个后端服务
#   system/auth/file/ai/workcase - 同上
#
# 选项(options)：
#   compile    - 先编译代码再构建镜像
#   save       - 构建后导出镜像到 tar 文件
#   save=VERSION - 导出指定版本的镜像
#
# 示例：
#   ./build.sh all compile save    # 编译+构建+导出所有
#   ./build.sh gateway compile     # 编译+构建 gateway
#   ./build.sh serv save           # 构建+导出所有后端
#   ./build.sh web compile save    # 编译+构建+导出前端
##############################################

set -e

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

log_info() { echo -e "${GREEN}[INFO]${NC} $1"; }
log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
log_error() { echo -e "${RED}[ERROR]${NC} $1"; }
log_step() { echo -e "${BLUE}[STEP]${NC} $1"; }

# 项目路径
SCRIPT_DIR=$(cd "$(dirname "$0")" && pwd)
PROJECT_ROOT=$(cd "${SCRIPT_DIR}/.." && pwd)
DOCKER_DIR="${SCRIPT_DIR}"
BUILD_OUTPUT="${DOCKER_DIR}/output"
IMAGE_VERSION=$(date +%Y%m%d_%H%M%S)

# 服务列表
SERV_SERVICES="gateway system auth file ai workcase"

# 服务端口映射
declare -A SERVICE_PORTS=(
    ["gateway"]=8080
    ["system"]=8082
    ["auth"]=8081
    ["file"]=8084
    ["ai"]=8090
    ["workcase"]=8088
)

# 解析参数
BUILD_TARGET="${1:-all}"
shift || true

DO_COMPILE=false
DO_SAVE=false
SAVE_VERSION=""

for arg in "$@"; do
    case $arg in
        compile)
            DO_COMPILE=true
            ;;
        save)
            DO_SAVE=true
            ;;
        save=*)
            DO_SAVE=true
            SAVE_VERSION="${arg#save=}"
            ;;
    esac
done

# 确定保存版本
if [ "${DO_SAVE}" = true ] && [ -z "${SAVE_VERSION}" ]; then
    SAVE_VERSION="${IMAGE_VERSION}"
fi

echo "=========================================="
echo "Urban Lifeline - 构建脚本"
echo "=========================================="
log_info "构建目标: ${BUILD_TARGET}"
log_info "构建版本: ${IMAGE_VERSION}"
log_info "编译代码: ${DO_COMPILE}"
log_info "保存镜像: ${DO_SAVE}"
[ "${DO_SAVE}" = true ] && log_info "保存版本: ${SAVE_VERSION}"
echo "=========================================="
echo ""

mkdir -p "${BUILD_OUTPUT}"

# ================================================
# 编译函数
# ================================================

compile_serv_all() {
    log_step "编译所有后端服务"
    cd "${PROJECT_ROOT}/urbanLifelineServ"
    mvn clean package -DskipTests
    log_info "✅ 后端服务编译完成"
}

compile_serv_single() {
    local service=$1
    log_step "编译 ${service} 服务"
    cd "${PROJECT_ROOT}/urbanLifelineServ"
    mvn clean package -DskipTests -pl ${service} -am
    log_info "✅ ${service} 服务编译完成"
}

compile_web() {
    log_step "编译前端项目"
    cd "${PROJECT_ROOT}/urbanLifelineWeb"
    
    # 检查 pnpm
    if command -v pnpm &> /dev/null; then
        pnpm install
        pnpm run build:all 2>/dev/null || {
            # 如果没有 build:all 脚本，分别构建
            log_info "分别构建各前端项目..."
            cd packages/shared && pnpm run build && cd ../..
            cd packages/platform && pnpm run build && cd ../..
            cd packages/workcase && pnpm run build && cd ../..
        }
    else
        npm install
        npm run build:all 2>/dev/null || {
            cd packages/shared && npm run build && cd ../..
            cd packages/platform && npm run build && cd ../..
            cd packages/workcase && npm run build && cd ../..
        }
    fi
    log_info "✅ 前端项目编译完成"
}

# ================================================
# 构建函数
# ================================================

build_base() {
    log_step "构建基础镜像"
    cd "${PROJECT_ROOT}"
    docker build \
        -t urban-lifeline-base-serv:${IMAGE_VERSION} \
        -t urban-lifeline-base-serv:latest \
        -f docker/urbanLifeline/serv/Dockerfile.base .
    log_info "✅ 基础镜像构建完成: urban-lifeline-base-serv:${IMAGE_VERSION}"
}

build_serv_single() {
    local service=$1
    local port=${SERVICE_PORTS[$service]}
    
    log_step "构建 ${service} 服务镜像"
    
    # 检查 JAR 包
    local jar_file=$(find "${PROJECT_ROOT}/urbanLifelineServ/${service}/target" -name "*.jar" -type f 2>/dev/null | head -1)
    if [ -z "$jar_file" ]; then
        log_error "JAR 包不存在，请先编译: ./build.sh ${service} compile"
        exit 1
    fi
    
    cd "${PROJECT_ROOT}"
    docker build \
        --build-arg SERVICE_NAME=${service} \
        --build-arg SERVICE_PORT=${port} \
        -t urban-lifeline-${service}:${IMAGE_VERSION} \
        -t urban-lifeline-${service}:latest \
        -f docker/urbanLifeline/serv/Dockerfile.template .
    
    log_info "✅ ${service} 镜像构建完成: urban-lifeline-${service}:${IMAGE_VERSION}"
}

build_serv_all() {
    for service in ${SERV_SERVICES}; do
        build_serv_single ${service}
    done
    log_info "✅ 所有后端服务镜像构建完成"
}

build_web() {
    build_platform
    build_workcase_web
    log_info "✅ 所有前端镜像构建完成"
}

build_platform() {
    log_step "构建 platform 镜像"
    
    if [ ! -d "${PROJECT_ROOT}/urbanLifelineWeb/packages/platform/dist" ]; then
        log_error "platform dist 不存在，请先编译: ./build.sh platform compile"
        exit 1
    fi
    
    cd "${PROJECT_ROOT}"
    docker build \
        --build-arg WEB_NAME=platform \
        -t urban-lifeline-platform:${IMAGE_VERSION} \
        -t urban-lifeline-platform:latest \
        -f docker/urbanLifeline/web/Dockerfile .
    
    log_info "✅ platform 镜像构建完成: urban-lifeline-platform:${IMAGE_VERSION}"
}

build_workcase_web() {
    log_step "构建 workcase-web 镜像"
    
    if [ ! -d "${PROJECT_ROOT}/urbanLifelineWeb/packages/workcase/dist" ]; then
        log_error "workcase dist 不存在，请先编译: ./build.sh workcase-web compile"
        exit 1
    fi
    
    cd "${PROJECT_ROOT}"
    docker build \
        --build-arg WEB_NAME=workcase \
        -t urban-lifeline-workcase-web:${IMAGE_VERSION} \
        -t urban-lifeline-workcase-web:latest \
        -f docker/urbanLifeline/web/Dockerfile .
    
    log_info "✅ workcase-web 镜像构建完成: urban-lifeline-workcase-web:${IMAGE_VERSION}"
}

# ================================================
# 导出函数
# ================================================

save_image() {
    local image_name=$1
    local version=${SAVE_VERSION}
    local output_file="${BUILD_OUTPUT}/${image_name}_${version}.tar"
    
    log_info "导出镜像: ${image_name}:${version}"
    
    if ! docker images | grep -q "${image_name}.*${version}"; then
        log_error "镜像不存在: ${image_name}:${version}"
        return 1
    fi
    
    docker save -o "${output_file}" ${image_name}:${version}
    local size=$(du -h "${output_file}" | cut -f1)
    log_info "✅ 镜像已导出: ${output_file} (${size})"
}

save_serv_all() {
    for service in ${SERV_SERVICES}; do
        save_image "urban-lifeline-${service}"
    done
}

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

main() {
    # 编译
    if [ "${DO_COMPILE}" = true ]; then
        case ${BUILD_TARGET} in
            base)
                # 基础镜像不需要编译
                ;;
            serv)
                compile_serv_all
                ;;
            web)
                compile_web
                ;;
            all)
                compile_serv_all
                compile_web
                ;;
            gateway|system|auth|file|ai|workcase)
                compile_serv_single ${BUILD_TARGET}
                ;;
            *)
                log_error "未知目标: ${BUILD_TARGET}"
                exit 1
                ;;
        esac
    fi
    
    # 构建镜像
    case ${BUILD_TARGET} in
        base)
            build_base
            ;;
        serv)
            build_serv_all
            ;;
        web)
            build_web
            ;;
        platform)
            build_platform
            ;;
        workcase-web)
            build_workcase_web
            ;;
        all)
            # 检查基础镜像
            if ! docker images | grep -q "urban-lifeline-base-serv.*latest"; then
                log_warn "基础镜像不存在，先构建基础镜像"
                build_base
            fi
            build_serv_all
            build_web
            ;;
        gateway|system|auth|file|ai|workcase)
            build_serv_single ${BUILD_TARGET}
            ;;
        *)
            log_error "未知目标: ${BUILD_TARGET}"
            echo ""
            echo "可用目标: base, serv, web, all, gateway, system, auth, file, ai, workcase, platform, workcase-web"
            exit 1
            ;;
    esac
    
    # 导出镜像
    if [ "${DO_SAVE}" = true ]; then
        case ${BUILD_TARGET} in
            base)
                save_image "urban-lifeline-base-serv"
                ;;
            serv)
                save_serv_all
                ;;
            web)
                save_image "urban-lifeline-platform"
                save_image "urban-lifeline-workcase-web"
                ;;
            platform)
                save_image "urban-lifeline-platform"
                ;;
            workcase-web)
                save_image "urban-lifeline-workcase-web"
                ;;
            all)
                save_image "urban-lifeline-base-serv"
                save_serv_all
                save_image "urban-lifeline-platform"
                save_image "urban-lifeline-workcase-web"
                ;;
            gateway|system|auth|file|ai|workcase)
                save_image "urban-lifeline-${BUILD_TARGET}"
                ;;
        esac
        
        echo ""
        log_info "导出文件列表:"
        ls -lh "${BUILD_OUTPUT}"/*.tar 2>/dev/null || true
    fi
    
    # 显示镜像列表
    echo ""
    log_info "Docker 镜像列表:"
    docker images | grep "urban-lifeline" | head -20
    
    echo ""
    echo "=========================================="
    log_info "✅ 构建完成！"
    echo "=========================================="
}

main
