// 统一Jenkins构建配置 (单仓多App定制版)
// 专注 Android APK 构建，支持多应用与版本动态传参

pipeline {
    agent any

    options {
        // 超时时间
        timeout(time: 45, unit: 'MINUTES')
        // 保留构建历史
        buildDiscarder(logRotator(numToKeepStr: '20'))
        // 时间戳显示
        timestamps()
        // 彩色输出
        ansiColor('xterm')
    }

    environment {
        // 基础配置
        PROJECT_NAME = 'Web Android Shell'
        
        // 此项目不使用 Melos，但通过 dart run tool/generate_app.dart 生成 App 工程
        FVM_VERSION = '3.41.2'

        // 动态环境配置 (根据参数设置)
        ENVIRONMENT = "${params.BUILD_ENVIRONMENT}"

        // Fastlane和Flutter配置
        LC_ALL = 'en_US.UTF-8'
        LANG = 'en_US.UTF-8'
        CI = 'true'
        FLUTTER_SUPPRESS_ANALYTICS = 'true'
        FLUTTER_NO_ANALYTICS = 'true'

        // PATH配置（使用环境变量，避免硬编码用户路径）
        PATH = "${env.HOME ?: '/Users/yuanxuan'}/.pub-cache/bin:/opt/homebrew/bin:/usr/local/bin:${env.PATH}"
    }

    parameters {
        // 🎯 目标应用 (可由 tool/update_jenkins_apps.dart 动态更新内容)
        choice(
            name: 'APP_NAME',
            choices: ['aixue', 'test', 'yunxiao', 'all'],
            description: '📱 选择要打包的应用 (从 flavors 目录生成)'
        )

        // 🎯 环境选择 
        choice(
            name: 'BUILD_ENVIRONMENT',
            choices: ['development', 'preview', 'production'],
            description: '🏗️ 构建环境: development(开发测试) | preview(预发布) | production(正式发布)'
        )
        
        // 🎯 版本相关参数
        string(
            name: 'VERSION_NAME',
            defaultValue: '',
            description: '🏷️ 覆盖版本名称 (例如 1.0.0)。留空则使用默认配置中的版本名。'
        )

        string(
            name: 'BUILD_NUMBER',
            defaultValue: '',
            description: '🔢 覆盖构建编号 (例如 1)。留空则使用默认配置中的构建版本号。'
        )

        // 🧹 清理构建
        booleanParam(
            name: 'CLEAN_BUILD',
            defaultValue: true,
            description: '🧹 是否执行清理构建 (生产环境推荐开启)'
        )
    }

    stages {
        stage('🔧 环境初始化') {
            steps {
                script {
                    echo "🚀 开始构建: ${PROJECT_NAME} [${params.BUILD_ENVIRONMENT}]"
                }

                sh '''
                    #!/bin/zsh
                    set +x
                    # 静默加载环境
                    [ -f "$HOME/.zshrc" ] && source "$HOME/.zshrc" > /dev/null 2>&1
                    
                    if command -v fvm &> /dev/null; then
                        echo "  - Flutter: $(fvm flutter --version | head -1)"
                    else
                        echo "❌ 错误: 未找到FVM环境"
                        exit 1
                    fi
                '''
            }
        }

        stage('🏗️ 生成与构建') {
            steps {
                script {
                    def appsToBuild = []
                    if (params.APP_NAME == 'all') {
                        // 动态读取 flavors 目录下的所有 yaml 文件
                        def flavorFiles = sh(script: "ls flavors/*.yaml | awk -F'/' '{print \$2}' | awk -F'.' '{print \$1}'", returnStdout: true).trim().split('\n')
                        appsToBuild = flavorFiles.toList()
                    } else {
                        appsToBuild = [params.APP_NAME]
                    }

                    for (int i = 0; i < appsToBuild.size(); i++) {
                        def currentApp = appsToBuild[i]
                        if (!currentApp) continue
                        
                        echo "🤖 开始处理应用: ${currentApp}..."
                        
                        // 步骤1：生成 App 工程 (如果不存在)
                        sh """
                            #!/bin/zsh
                            set +x
                            [ -f "\\$HOME/.zshrc" ] && source "\\$HOME/.zshrc" > /dev/null 2>&1
                            
                            if [ ! -d "apps/${currentApp}" ]; then
                                echo "  - 应用目录 apps/${currentApp} 不存在，正在执行 generate_app 脚本生成项目..."
                                dart run tool/generate_app.dart ${currentApp}
                            else
                                echo "  - 应用目录 apps/${currentApp} 已存在，跳过生成工程阶段。"
                            fi
                        """

                        // 步骤2：执行 Flutter 构建
                        echo "  - 正在为 ${currentApp} 构建 Android APK..."
                        sh """
                            #!/bin/zsh
                            set +x
                            [ -f "\\$HOME/.zshrc" ] && source "\\$HOME/.zshrc" > /dev/null 2>&1
                            cd apps/${currentApp}
                            
                            # 先写入 shell 变量，避免 GString 里出现 "\${params.xxx}" 触发 Groovy 解析错误
                            CLEAN_BUILD='${params.CLEAN_BUILD}'
                            VERSION_NAME='${params.VERSION_NAME}'
                            BUILD_NUMBER='${params.BUILD_NUMBER}'
                            BUILD_ENV='${params.BUILD_ENVIRONMENT}'
                            
                            if [ "\$CLEAN_BUILD" = "true" ]; then
                                echo "  - 执行 flutter clean..."
                                fvm flutter clean
                            fi
                            
                            fvm flutter pub get
                            
                            EXTRA_ARGS=""
                            if [ -n "\$VERSION_NAME" ]; then
                                EXTRA_ARGS="\$EXTRA_ARGS --build-name=\$VERSION_NAME"
                            fi
                            if [ -n "\$BUILD_NUMBER" ]; then
                                EXTRA_ARGS="\$EXTRA_ARGS --build-number=\$BUILD_NUMBER"
                            fi
                            EXTRA_ARGS="\$EXTRA_ARGS --dart-define=APP_ENV=\$BUILD_ENV"
                            
                            echo "  - 开始构建 APK 参数: \$EXTRA_ARGS"
                            echo "  - 开始执行 flutter build apk（构建期间每30秒输出一次心跳）..."

                            run_build_with_heartbeat() {
                                (fvm flutter build apk --release \$EXTRA_ARGS) &
                                BUILD_PID=\$!
                                while kill -0 \$BUILD_PID 2>/dev/null; do
                                    echo "  - 构建仍在进行中... \$(date '+%H:%M:%S')"
                                    sleep 30
                                done
                                wait \$BUILD_PID
                                return \$?
                            }

                            if ! run_build_with_heartbeat; then
                                echo "  ⚠️ 首次构建失败，尝试清理 Gradle wrapper 缓存后重试一次..."
                                rm -rf "\$HOME/.gradle/wrapper/dists"
                                run_build_with_heartbeat
                            fi
                        """
                        echo "  ✅ ${currentApp} Android APK 构建完成"
                    }
                }
            }
        }
    }

    post {
        always {
            script {
                echo "🧹 处理构建产物"
                // 仅归档 APK 产物
                def findCount = sh(
                    script: "find apps/*/build/app/outputs/flutter-apk -name 'app-release.apk' 2>/dev/null | wc -l | tr -d ' '",
                    returnStdout: true
                ).trim()
                
                if (findCount && findCount != '0') {
                    echo "  - 归档Android Release APK..."
                    archiveArtifacts artifacts: 'apps/*/build/app/outputs/flutter-apk/app-release.apk', fingerprint: true
                    echo "  ✅ 归档完成 (找到 ${findCount} 个 APK 文件)"
                } else {
                    echo "  ⚠️ 未找到任何构建的 APK"
                }

                // 归档FVM配置便于追踪环境记录
                if (fileExists('.fvmrc')) {
                    archiveArtifacts artifacts: '.fvmrc', fingerprint: true, allowEmptyArchive: true
                }
            }
        }
        
        success {
            script {
                echo "🎉 构建流程成功完成！"
                echo "✅ 详情："
                echo "  - 目标: ${params.APP_NAME}"
                echo "  - 环境: ${params.BUILD_ENVIRONMENT}"
                if (params.VERSION_NAME) echo "  - 版本名: ${params.VERSION_NAME}"
                if (params.BUILD_NUMBER) echo "  - 构建号: ${params.BUILD_NUMBER}"
            }
        }
        
        failure {
            echo "❌ 构建流程遇到错误并终止。请检查上方日志找出失败原由。"
        }
    }
}
