pipeline {
  agent {
    label "${env.JOB_BASE_NAME?.endsWith('-prod') ? 'java-builder' : (env.JOB_BASE_NAME?.endsWith('-dev') ? 'java-dev' : 'java-test')}"
  }

  environment {
    DEVELOPMENT_COMPOSE_FILE = 'docker-compose.development.yml'
    DEVELOPMENT_COMPOSE_PROJECT = 'admin-web'
    REGISTRY_HOST = '172.31.198.7:10082'
    REGISTRY_CREDENTIALS = 'gitea-registry-token'
    NODE_BASE_IMAGE = '172.31.198.7:10082/java-project/node:22-alpine'
    NGINX_BASE_IMAGE = '172.31.198.7:10082/java-project/nginx:1.27-alpine'
    PRODUCTION_IMAGE_REPOSITORY = 'git.buggoglobal.com/html/admin-web'
  }

  options {
    timestamps()
    disableConcurrentBuilds()
  }

  stages {
    stage('确认提交版本') {
      steps {
        script {
          env.IS_DEVELOPMENT = env.JOB_BASE_NAME?.endsWith('-dev') ? 'true' : 'false'
          env.IS_PRODUCTION = env.JOB_BASE_NAME?.endsWith('-prod') ? 'true' : 'false'
          if (env.IS_PRODUCTION == 'true') {
            sh '''
              set -eu
              git fetch --no-tags origin +refs/heads/main:refs/remotes/origin/main
              test "$(git rev-parse HEAD)" = "$(git rev-parse origin/main)" || {
                echo "生产部署只允许 origin/main 当前提交；请先合并代码到 main" >&2
                exit 1
              }
            '''
          }
          env.SOURCE_TAG = sh(script: 'git rev-parse --short=12 HEAD', returnStdout: true).trim()
        }
        sh 'git log -1 --oneline'
      }
    }

    stage('构建并部署测试前端') {
      when { expression { env.IS_DEVELOPMENT != 'true' && env.IS_PRODUCTION != 'true' } }
      steps {
        withCredentials([usernamePassword(credentialsId: env.REGISTRY_CREDENTIALS, usernameVariable: 'REGISTRY_USER', passwordVariable: 'REGISTRY_PASSWORD')]) {
          sh '''
            set -eu
            export DOCKER_CONFIG="${WORKSPACE}@tmp/docker-auth"
            rm -rf "$DOCKER_CONFIG"
            mkdir -p "$DOCKER_CONFIG"
            cleanup_registry() {
              docker logout "$REGISTRY_HOST" >/dev/null 2>&1 || true
              rm -rf "$DOCKER_CONFIG"
            }
            trap cleanup_registry EXIT HUP INT TERM
            printf %s "$REGISTRY_PASSWORD" | docker login -u "$REGISTRY_USER" --password-stdin "$REGISTRY_HOST"
            docker compose -f docker-compose.test.yml build --pull=false
            docker compose -f docker-compose.test.yml up -d --remove-orphans
          '''
        }
      }
    }

    stage('构建并发布生产镜像') {
      when { expression { env.IS_PRODUCTION == 'true' } }
      steps {
        withCredentials([usernamePassword(credentialsId: env.REGISTRY_CREDENTIALS, usernameVariable: 'REGISTRY_USER', passwordVariable: 'REGISTRY_PASSWORD')]) {
          sh '''
            set -eu
            export DOCKER_CONFIG="${WORKSPACE}@tmp/docker-auth"
            rm -rf "$DOCKER_CONFIG"
            mkdir -p "$DOCKER_CONFIG"
            cleanup_registry() {
              docker logout git.buggoglobal.com >/dev/null 2>&1 || true
              rm -rf "$DOCKER_CONFIG"
            }
            trap cleanup_registry EXIT HUP INT TERM
            printf %s "$REGISTRY_PASSWORD" | docker login -u "$REGISTRY_USER" --password-stdin git.buggoglobal.com
            image="$PRODUCTION_IMAGE_REPOSITORY:$SOURCE_TAG"
            docker build \
              --build-arg NODE_IMAGE="$NODE_BASE_IMAGE" \
              --build-arg NGINX_IMAGE="$NGINX_BASE_IMAGE" \
              --build-arg VITE_CLIENT_WEB_URL=https://app.buggoglobal.com/ \
              -t "$image" .
            docker push "$image"
          '''
        }
      }
    }

    stage('确认部署生产前端') {
      when { expression { env.IS_PRODUCTION == 'true' } }
      steps {
        input message: "确认将 main 提交 ${env.SOURCE_TAG} 部署到 admin.buggoglobal.com？", ok: '确认部署'
      }
    }

    stage('部署生产前端') {
      when { expression { env.IS_PRODUCTION == 'true' } }
      steps {
        lock(resource: 'firstleg-production-admin-web-deploy', inversePrecedence: true) {
          withCredentials([
            usernamePassword(credentialsId: 'gitea-production-pull-token', usernameVariable: 'REGISTRY_USER', passwordVariable: 'REGISTRY_PASSWORD'),
            sshUserPrivateKey(credentialsId: 'firstleg-production-ssh', keyFileVariable: 'TARGET_SSH_KEY', usernameVariable: 'TARGET_SSH_USER'),
            string(credentialsId: 'firstleg-production-host', variable: 'TARGET_SSH_HOST'),
            file(credentialsId: 'firstleg-production-known-hosts', variable: 'TARGET_SSH_KNOWN_HOSTS')
          ]) {
            withEnv([
              'TARGET_DEPLOY_DIR=/data/firstleg/deploy/frontend',
              'TARGET_SSH_TARGET=' + env.TARGET_SSH_USER + '@' + env.TARGET_SSH_HOST
            ]) {
              sh "sh scripts/deploy-production.sh admin-web '${env.PRODUCTION_IMAGE_REPOSITORY}' '${env.SOURCE_TAG}' docker-compose.production.yml"
            }
          }
        }
      }
    }

    stage('构建并部署开发前端') {
      when { expression { env.IS_DEVELOPMENT == 'true' } }
      steps {
        withCredentials([usernamePassword(credentialsId: env.REGISTRY_CREDENTIALS, usernameVariable: 'REGISTRY_USER', passwordVariable: 'REGISTRY_PASSWORD')]) {
          sh '''
            set -eu
            export DOCKER_CONFIG="${WORKSPACE}@tmp/docker-auth"
            rm -rf "$DOCKER_CONFIG"
            mkdir -p "$DOCKER_CONFIG"
            cleanup_registry() {
              docker logout "$REGISTRY_HOST" >/dev/null 2>&1 || true
              rm -rf "$DOCKER_CONFIG"
            }
            trap cleanup_registry EXIT HUP INT TERM
            printf %s "$REGISTRY_PASSWORD" | docker login -u "$REGISTRY_USER" --password-stdin "$REGISTRY_HOST"
            image="admin-web-development:${SOURCE_TAG}"

            docker build \
              --build-arg NODE_IMAGE="$NODE_BASE_IMAGE" \
              --build-arg NGINX_IMAGE="$NGINX_BASE_IMAGE" \
              --build-arg VITE_CLIENT_WEB_URL="${CLIENT_WEB_URL:-https://dev-app.buggoglobal.com/}" \
              -t "$image" .
            export IMAGE_TAG="$SOURCE_TAG"
            docker compose -p "$DEVELOPMENT_COMPOSE_PROJECT" -f "$DEVELOPMENT_COMPOSE_FILE" up -d --remove-orphans --pull never
            docker compose -p "$DEVELOPMENT_COMPOSE_PROJECT" -f "$DEVELOPMENT_COMPOSE_FILE" ps
            docker compose -p "$DEVELOPMENT_COMPOSE_PROJECT" -f "$DEVELOPMENT_COMPOSE_FILE" exec -T admin-web wget -qO- http://127.0.0.1/healthz
          '''
        }
      }
    }

    stage('部署检查') {
      when { expression { env.IS_DEVELOPMENT != 'true' && env.IS_PRODUCTION != 'true' } }
      steps {
        sh '''
          set -eu
          docker compose -f docker-compose.test.yml ps
          docker compose -f docker-compose.test.yml exec -T admin-web wget -qO- http://127.0.0.1/healthz
        '''
      }
    }
  }

  post {
    failure {
      sh '''
        if [ "${IS_PRODUCTION:-false}" = "true" ]; then
          echo "生产部署失败，请查看上方远程部署日志"
        elif [ "${IS_DEVELOPMENT:-false}" = "true" ]; then
          docker logs --tail=100 admin-web-development || true
        else
          docker compose -f docker-compose.test.yml logs --tail=100 || true
        fi
      '''
    }
  }
}
