// Jenkins Pipeline配置文件
// 声明式Pipeline，适用于Jenkins 2.x

pipeline {
    agent any

    // 环境变量
    environment {
        PYTHON_VERSION = '3.12'
        VENV_DIR = '.venv'
        // 从Jenkins凭据中读取
        DB_CREDENTIALS = credentials('database-credentials')
        API_TOKEN = credentials('api-token')
    }

    // 参数化构建
    parameters {
        choice(
            name: 'TEST_ENV',
            choices: ['test', 'staging', 'prod'],
            description: '测试环境'
        )
        booleanParam(
            name: 'RUN_INTEGRATION_TESTS',
            defaultValue: true,
            description: '是否运行集成测试'
        )
        booleanParam(
            name: 'GENERATE_ALLURE_REPORT',
            defaultValue: true,
            description: '是否生成Allure报告'
        )
    }

    // 触发器
    triggers {
        // 每天凌晨2点运行
        cron('0 2 * * *')
        // 轮询SCM
        pollSCM('H/15 * * * *')
    }

    // 构建选项
    options {
        // 保留最近10次构建
        buildDiscarder(logRotator(numToKeepStr: '10'))
        // 构建超时
        timeout(time: 30, unit: 'MINUTES')
        // 禁止并发构建
        disableConcurrentBuilds()
        // 时间戳
        timestamps()
    }

    stages {
        stage('检出代码') {
            steps {
                script {
                    echo "检出代码..."
                    checkout scm
                    // 显示git信息
                    sh 'git log -1 --oneline'
                }
            }
        }

        stage('准备环境') {
            steps {
                script {
                    echo "准备Python虚拟环境和依赖..."
                    sh """
                        python${PYTHON_VERSION} -m venv ${VENV_DIR}
                        . ${VENV_DIR}/bin/activate
                        pip install --upgrade pip
                        pip install uv
                        # 同步依赖（使用 pyproject.toml）
                        uv sync
                    """
                }
            }
        }

        stage('代码质量检查') {
            parallel {
                stage('Lint检查') {
                    steps {
                        script {
                            echo "运行代码质量检查..."
                            sh """
                                . ${VENV_DIR}/bin/activate
                                pip install flake8 pylint
                                flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics || true
                                pylint src/ --exit-zero || true
                            """
                        }
                    }
                }

                stage('类型检查') {
                    steps {
                        script {
                            echo "运行类型检查..."
                            sh """
                                . ${VENV_DIR}/bin/activate
                                pip install mypy
                                mypy src/ --ignore-missing-imports || true
                            """
                        }
                    }
                }
            }
        }

        stage('单元测试') {
            steps {
                script {
                    echo "运行单元测试..."
                    sh """
                        . ${VENV_DIR}/bin/activate
                        export HTTP_BASE_URL=\${API_TOKEN_USR}
                        uv run pytest tests/unit/ \
                            --verbose \
                            --cov=src \
                            --cov-report=xml \
                            --cov-report=html \
                            --html=reports/unit-test-report.html \
                            --self-contained-html \
                            --alluredir=reports/allure-results \
                            --junitxml=reports/junit.xml
                    """
                }
            }
            post {
                always {
                    // 发布JUnit测试结果
                    junit 'reports/junit.xml'
                    // 发布HTML测试报告
                    publishHTML(target: [
                        allowMissing: false,
                        alwaysLinkToLastBuild: true,
                        keepAll: true,
                        reportDir: 'reports',
                        reportFiles: 'unit-test-report.html',
                        reportName: '单元测试报告'
                    ])
                    // 发布覆盖率报告
                    publishHTML(target: [
                        allowMissing: false,
                        alwaysLinkToLastBuild: true,
                        keepAll: true,
                        reportDir: 'htmlcov',
                        reportFiles: 'index.html',
                        reportName: '覆盖率报告'
                    ])
                }
            }
        }

        stage('集成测试') {
            when {
                expression { params.RUN_INTEGRATION_TESTS }
            }
            steps {
                script {
                    echo "运行集成测试..."
                    sh """
                        . ${VENV_DIR}/bin/activate
                        export TEST_ENV=${params.TEST_ENV}
                        export DB_URL=\${DB_CREDENTIALS_USR}
                        uv run pytest tests/integration/ \
                            --verbose \
                            --alluredir=reports/allure-results
                    """
                }
            }
        }

        stage('性能测试') {
            when {
                branch 'main'
            }
            steps {
                script {
                    echo "运行性能测试..."
                    sh """
                        . ${VENV_DIR}/bin/activate
                        uv run pytest tests/performance/ \
                            --verbose \
                            --benchmark-only \
                            --benchmark-autosave || true
                    """
                }
            }
        }

        stage('生成报告') {
            when {
                expression { params.GENERATE_ALLURE_REPORT }
            }
            steps {
                script {
                    echo "生成Allure报告..."
                    allure([
                        includeProperties: false,
                        jdk: '',
                        properties: [],
                        reportBuildPolicy: 'ALWAYS',
                        results: [[path: 'reports/allure-results']]
                    ])
                }
            }
        }

        stage('部署测试环境') {
            when {
                branch 'develop'
            }
            steps {
                script {
                    echo "部署到测试环境..."
                    // 这里添加部署逻辑
                    sh """
                        echo "部署到 ${params.TEST_ENV} 环境"
                    """
                }
            }
        }
    }

    post {
        always {
            script {
                echo "清理工作空间..."
                // 归档产物
                archiveArtifacts artifacts: 'reports/**', allowEmptyArchive: true
                // 清理虚拟环境
                sh "rm -rf ${VENV_DIR}"
            }
        }

        success {
            script {
                echo "构建成功！"
                // 发送成功通知
                emailext(
                    subject: "✅ Jenkins构建成功: ${env.JOB_NAME} #${env.BUILD_NUMBER}",
                    body: """
                        <h2>构建成功</h2>
                        <p><strong>项目</strong>: ${env.JOB_NAME}</p>
                        <p><strong>构建号</strong>: ${env.BUILD_NUMBER}</p>
                        <p><strong>分支</strong>: ${env.BRANCH_NAME}</p>
                        <p><strong>查看详情</strong>: <a href="${env.BUILD_URL}">${env.BUILD_URL}</a></p>
                    """,
                    to: '${DEFAULT_RECIPIENTS}',
                    mimeType: 'text/html'
                )

                // 发送钉钉通知
                sh """
                    curl -X POST '${DINGTALK_WEBHOOK}' \
                        -H 'Content-Type: application/json' \
                        -d '{
                            "msgtype": "markdown",
                            "markdown": {
                                "title": "构建成功",
                                "text": "### 构建成功 ✅\\n\\n**项目**: ${env.JOB_NAME}\\n\\n**构建号**: ${env.BUILD_NUMBER}\\n\\n**分支**: ${env.BRANCH_NAME}"
                            }
                        }'
                """
            }
        }

        failure {
            script {
                echo "构建失败！"
                // 发送失败通知
                emailext(
                    subject: "❌ Jenkins构建失败: ${env.JOB_NAME} #${env.BUILD_NUMBER}",
                    body: """
                        <h2>构建失败</h2>
                        <p><strong>项目</strong>: ${env.JOB_NAME}</p>
                        <p><strong>构建号</strong>: ${env.BUILD_NUMBER}</p>
                        <p><strong>分支</strong>: ${env.BRANCH_NAME}</p>
                        <p><strong>查看详情</strong>: <a href="${env.BUILD_URL}">${env.BUILD_URL}</a></p>
                        <p><strong>控制台输出</strong>: <a href="${env.BUILD_URL}console">${env.BUILD_URL}console</a></p>
                    """,
                    to: '${DEFAULT_RECIPIENTS}',
                    mimeType: 'text/html'
                )

                // 发送钉钉通知
                sh """
                    curl -X POST '${DINGTALK_WEBHOOK}' \
                        -H 'Content-Type: application/json' \
                        -d '{
                            "msgtype": "markdown",
                            "markdown": {
                                "title": "构建失败",
                                "text": "### 构建失败 ❌\\n\\n**项目**: ${env.JOB_NAME}\\n\\n**构建号**: ${env.BUILD_NUMBER}\\n\\n**分支**: ${env.BRANCH_NAME}\\n\\n**控制台**: [查看日志](${env.BUILD_URL}console)"
                            }
                        }'
                """
            }
        }

        unstable {
            script {
                echo "构建不稳定！"
            }
        }
    }
}
