pipeline {
  agent any

  parameters {
    choice(name: 'SERVICE', choices: ['tenant-service', 'im-service', 'push-service', 'update-service', 'demo-service', 'file-service', 'license-service'], description: '要构建的服务模块')
    string(name: 'IMAGE_TAG', defaultValue: 'latest', description: '镜像 Tag（如 v1.2.3 或 latest）')
    booleanParam(name: 'DEPLOY', defaultValue: true, description: '构建后是否自动部署到生产服务器')
  }

  environment {
    ACR_REGISTRY    = 'crpi-n44qjpuucgjt8e8c.cn-beijing.personal.cr.aliyuncs.com'
    ACR_NAMESPACE   = 'xuqmgroup'
    ACR_USERNAME    = 'xuqinmin12'
    PROD_HOST       = '106.54.23.149'
    PROD_USER       = 'ubuntu'
    COMPOSE_FILE    = '/opt/xuqm/deploy/compose.production.yaml'
    DOCKER_BUILDKIT = '1'
  }

  options {
    timeout(time: 30, unit: 'MINUTES')
    buildDiscarder(logRotator(numToKeepStr: '20'))
    disableConcurrentBuilds()
  }

  stages {
    stage('Checkout') {
      steps {
        checkout([
          $class: 'GitSCM',
          branches: [[name: 'main']],
          extensions: [[$class: 'CleanBeforeCheckout']],
          userRemoteConfigs: scm.userRemoteConfigs
        ])
      }
    }

    stage('Docker Build & Push') {
      steps {
        withCredentials([string(credentialsId: 'ACR_PASSWORD', variable: 'ACR_PASS')]) {
          script {
            // 自动递增 VERSION 文件中的构建号
            def versionFile = 'VERSION'
            if (fileExists(versionFile)) {
              def version = readFile(versionFile).trim()
              // 格式: 2026.05.20-private.3 → 递增末尾数字
              def matcher = version =~ /^(.+\.)(\d+)$/
              if (matcher.matches()) {
                def prefix = matcher.group(1)
                def buildNum = matcher.group(2).toInteger() + 1
                def newVersion = "${prefix}${buildNum}"
                writeFile file: versionFile, text: newVersion
                echo "VERSION: ${version} → ${newVersion}"
              }
            }
            def imageName = "${ACR_REGISTRY}/${ACR_NAMESPACE}/${params.SERVICE}:${params.IMAGE_TAG}"
            bat """
              docker login ${ACR_REGISTRY} -u ${ACR_USERNAME} -p %ACR_PASS%
              docker pull --platform=linux/amd64 ${imageName} || echo Pull failed, will build fresh
              docker build --platform=linux/amd64 --build-arg SERVICE_MODULE=${params.SERVICE} --build-arg BUILDKIT_INLINE_CACHE=1 --cache-from ${imageName} -t ${imageName} .
              docker push ${imageName}
              docker rmi ${imageName} || exit 0
            """
          }
        }
      }
    }

    stage('Deploy to Production') {
      when { expression { return params.DEPLOY } }
      steps {
        lock('prod-deploy') {
          withCredentials([sshUserPrivateKey(credentialsId: 'PROD_SSH_KEY', keyFileVariable: 'SSH_KEY')]) {
            script {
              def imageName = "${ACR_REGISTRY}/${ACR_NAMESPACE}/${params.SERVICE}:${params.IMAGE_TAG}"
              def remoteCmd = """
                set -e
                # 清理悬空镜像，避免 containerd 存储损坏
                docker image prune -f 2>/dev/null || true
                # 拉取镜像（失败则清理后重试）
                if ! docker pull ${imageName}; then
                  echo 'Pull failed, cleaning containerd cache and retrying...'
                  docker system prune -f
                  docker pull ${imageName}
                fi
                # 部署
                docker compose -f ${COMPOSE_FILE} up -d --no-deps --force-recreate ${params.SERVICE}
                # 清理旧镜像
                docker image prune -f
              """.stripIndent()
              retry(2) {
                bat """
                  ssh -i "%SSH_KEY%" -o StrictHostKeyChecking=no ${PROD_USER}@${PROD_HOST} "${remoteCmd}"
                """
              }
            }
          }
        }
      }
    }
  }

  post {
    success { echo "✅ ${params.SERVICE}:${params.IMAGE_TAG} 构建部署成功" }
    failure  { echo "❌ 构建失败，请检查日志" }
  }
}
