def isProductionDeploy() {
  return params.DEPLOY_ENV == "production"
}

def isTestDeploy() {
  def branch = env.BRANCH_NAME ?: ""
  return params.DEPLOY_ENV == "test" && !params.SKIP_DEPLOY && branch == env.TEST_BRANCH
}

@NonCPS
boolean isUserTriggeredBuild() {
  return currentBuild.rawBuild.getCauses().any { cause ->
    cause.class.name == "hudson.model.Cause\$UserIdCause"
  }
}

pipeline {
  agent any

  options {
    timestamps()
    disableConcurrentBuilds()
    buildDiscarder(logRotator(numToKeepStr: "30", artifactNumToKeepStr: "10"))
  }

  parameters {
    choice(
      name: "DEPLOY_ENV",
      choices: ["test", "production"],
      description: "test: develop 合并后自动部署测试环境；production: 仅允许手动输入 Tag 部署"
    )
    string(name: "RELEASE_TAG", defaultValue: "", description: "生产部署必填，必须是 Gitea 中已存在的 Tag")
    booleanParam(name: "SKIP_DEPLOY", defaultValue: false, description: "只构建检查，不执行部署")
  }

  environment {
    PROJECT_NAME = "role-user"
    TEST_BRANCH = "develop"
    DEPLOY_BASE_DIR = "/srv/www"
  }

  stages {
    stage("Validate deploy policy") {
      steps {
        script {
          if (isProductionDeploy()) {
            if (!isUserTriggeredBuild()) {
              error("生产环境禁止自动触发，只能在 Jenkins 手动 Build With Parameters。")
            }
            if (!params.RELEASE_TAG?.trim()) {
              error("生产环境部署必须填写 RELEASE_TAG，且只能从项目 Tag 部署。")
            }
          }

          if (params.DEPLOY_ENV == "test" && env.BRANCH_NAME && env.BRANCH_NAME != env.TEST_BRANCH) {
            echo "当前分支 ${env.BRANCH_NAME} 不是 ${env.TEST_BRANCH}，本次只构建检查，不自动部署测试环境。"
          }
        }
      }
    }

    stage("Checkout production tag") {
      when {
        expression { isProductionDeploy() }
      }
      steps {
        sh '''
          set -euo pipefail
          git fetch --tags --force origin '+refs/tags/*:refs/tags/*'
          tag_commit="$(git rev-parse -q --verify "refs/tags/${RELEASE_TAG}^{commit}")"
          if [ -z "${tag_commit}" ]; then
            echo "Tag not found: ${RELEASE_TAG}" >&2
            exit 1
          fi
          git checkout -f "${tag_commit}"
          git log -1 --oneline
        '''
      }
    }

    stage("Install") {
      steps {
        sh '''
          corepack enable || true
          pnpm install --frozen-lockfile
        '''
      }
    }

    stage("Verify") {
      steps {
        sh '''
          pnpm typecheck
          pnpm lint
        '''
      }
    }

    stage("Build") {
      steps {
        script {
          sh isProductionDeploy() ? "pnpm build:prod" : "pnpm build:test"
        }
      }
    }

    stage("Package standalone") {
      steps {
        sh '''
          set -euo pipefail
          rm -rf .deploy/role-user
          mkdir -p .deploy/role-user/.next
          cp -R .next/standalone/. .deploy/role-user/
          cp -R .next/static .deploy/role-user/.next/static
          cp -R public .deploy/role-user/public
        '''
      }
    }

    stage("Deploy test") {
      when {
        expression { isTestDeploy() }
      }
      steps {
        sh "bash deploy/jenkins/deploy-standalone.sh test .deploy/role-user"
      }
    }

    stage("Deploy production") {
      when {
        expression { isProductionDeploy() && !params.SKIP_DEPLOY }
      }
      steps {
        sh "bash deploy/jenkins/deploy-standalone.sh production .deploy/role-user"
      }
    }
  }
}
