/**
 * 开发环境（deve）：Checkout -> Maven（按需模块）-> 拷贝 jar -> docker compose 启停
 *
 * Jenkins Job 配置：
 *   - Pipeline script from SCM
 *   - Repository: http://8.152.195.41:3000/alien/alien_cloud
 *   - Script Path: docs/devops/dev/java/Jenkinsfile
 *   - 分支默认 deve（构建参数 GIT_BRANCH 可覆盖）
 *
 * 宿主机目录：/deve/java（docker-compose.yml 与 gateway/store/... 子目录）
 * Jenkins 容器须能访问该路径（建议挂载 /deve/java:/deve/java）及 docker.sock
 *
 * 容器名：gateway-dev、store-dev…（compose 内 services 键仍为 gateway、store…）
 */

def getServiceDefinitions() {
    return [
            [module: 'alien-gateway',        dir: 'gateway',        composeService: 'gateway',        container: 'gateway-dev',        withLib: false],
            [module: 'alien-store',          dir: 'store',          composeService: 'store',          container: 'store-dev',          withLib: true],
            [module: 'alien-second',         dir: 'second',         composeService: 'second',         container: 'second-dev',         withLib: false],
            [module: 'alien-store-platform', dir: 'store-platform', composeService: 'store-platform', container: 'store-platform-dev', withLib: false],
            [module: 'alien-lawyer',         dir: 'lawyer',         composeService: 'lawyer',         container: 'lawyer-dev',         withLib: false],
            [module: 'alien-job',            dir: 'job',            composeService: 'job',            container: 'job-dev',            withLib: false],
            [module: 'alien-dining',         dir: 'dining',         composeService: 'dining',         container: 'dining-dev',         withLib: true],
    ]
}

def deployParamName(String composeService) {
    return 'DEPLOY_' + composeService.replace('-', '_')
}

def collectSelectedServices(Map buildParams) {
    def selected = []
    getServiceDefinitions().each { svc ->
        def paramName = deployParamName(svc.composeService)
        if (buildParams[paramName]) {
            selected.add(svc)
        }
    }
    return selected
}

def deployOneService(String workspace, String deployRoot, Map svc) {
    def sourceJar = "${workspace}/${svc.module}/target/${svc.module}-1.0.0.jar"
    def sourceLib = "${workspace}/${svc.module}/target/lib"
    def targetDir = "${deployRoot}/${svc.dir}"
    sh """
        set -e
        echo ">>> Deploy module: ${svc.module} -> ${targetDir}"
        if [ ! -f "${sourceJar}" ]; then
            echo ">>> [${svc.dir}] jar missing, skip copy"
            exit 0
        fi
        mkdir -p "${targetDir}"
        if [ "${svc.withLib}" = "true" ] && [ -d "${sourceLib}" ]; then
            rm -rf "${targetDir}/lib"
            cp -rf "${sourceLib}" "${targetDir}/lib"
        fi
        cp -f "${sourceJar}" "${targetDir}/"
        echo ">>> [${svc.dir}] jar copied"
    """
}

def composeStop(String deployRoot, List composeServices) {
    if (composeServices == null || composeServices.isEmpty()) {
        return
    }
    def svcList = composeServices.join(' ')
    sh """
        set -e
        cd "${deployRoot}"
        test -f docker-compose.yml
        echo ">>> docker compose stop ${svcList}"
        docker compose stop ${svcList}
    """
}

def startOrRestartServices(String deployRoot, List composeServices) {
    if (composeServices == null || composeServices.isEmpty()) {
        return
    }
    def svcList = composeServices.join(' ')
    sh """
        set -e
        cd "${deployRoot}"
        test -f docker-compose.yml
        echo ">>> docker compose up -d ${svcList}"
        docker compose up -d ${svcList}
        echo ">>> docker compose restart ${svcList}"
        docker compose restart ${svcList}
    """
}

pipeline {
    agent any

    options {
        buildDiscarder(logRotator(numToKeepStr: '2', artifactNumToKeepStr: '2'))
        disableConcurrentBuilds()
        timestamps()
        timeout(time: 60, unit: 'MINUTES')
    }

    parameters {
        string(
                name: 'GIT_BRANCH',
                defaultValue: 'deve',
                trim: true,
                description: '构建分支，默认 deve，可在「Build with Parameters」中修改'
        )
        booleanParam(
                name: 'STOP_ALL',
                defaultValue: false,
                description: '为 true 时：先停止全部 dev 微服务，再按下方勾选部署；此时 gateway 必须勾选'
        )
        // 多选复选框（Declarative 须逐项声明，不可用 each 动态生成）
        booleanParam(name: 'DEPLOY_gateway', defaultValue: true, description: 'alien-gateway -> gateway-dev')
        booleanParam(name: 'DEPLOY_store', defaultValue: true, description: 'alien-store -> store-dev')
        booleanParam(name: 'DEPLOY_second', defaultValue: true, description: 'alien-second -> second-dev')
        booleanParam(name: 'DEPLOY_store_platform', defaultValue: false, description: 'alien-store-platform -> store-platform-dev')
        booleanParam(name: 'DEPLOY_lawyer', defaultValue: false, description: 'alien-lawyer -> lawyer-dev')
        booleanParam(name: 'DEPLOY_job', defaultValue: false, description: 'alien-job -> job-dev')
        booleanParam(name: 'DEPLOY_dining', defaultValue: false, description: 'alien-dining -> dining-dev')
    }

    environment {
        MAVEN_HOME = tool '3.6.3'
        PATH = "${MAVEN_HOME}/bin:${env.PATH}"
        GIT_URL = 'http://8.152.195.41:3000/alien/alien_cloud'
        GIT_CREDENTIALS = '5e058e17-8089-45e0-a802-596d91758b4d'
        DEPLOY_ROOT = '/deve/java'
        MAVEN_LOCAL_REPO = '/var/jenkins_home/.m2/repository'
    }

    stages {
        stage('Validate') {
            steps {
                script {
                    def selected = collectSelectedServices(params)
                    if (selected.isEmpty()) {
                        error('请至少勾选一个微服务')
                    }
                    if (params.STOP_ALL && !params.DEPLOY_gateway) {
                        error('STOP_ALL=true 时 gateway 必须勾选')
                    }
                    env.SELECTED_COMPOSE_SERVICES = selected.collect { it.composeService }.join(' ')
                    env.SELECTED_MAVEN_MODULES = selected.collect { it.module }.join(',')
                    echo ">>> Branch: ${params.GIT_BRANCH}"
                    echo ">>> STOP_ALL: ${params.STOP_ALL}"
                    echo ">>> Selected compose services: ${env.SELECTED_COMPOSE_SERVICES}"
                }
            }
        }

        stage('Checkout') {
            steps {
                script {
                    def branch = (params.GIT_BRANCH ?: 'deve').trim()
                    if (!branch) {
                        error('GIT_BRANCH is required')
                    }
                    env.GIT_BRANCH = branch
                    echo ">>> Checkout branch: ${env.GIT_BRANCH}"
                    git branch: "${env.GIT_BRANCH}",
                            credentialsId: "${env.GIT_CREDENTIALS}",
                            url: "${env.GIT_URL}"
                    sh """
                        set -e
                        git fetch origin
                        git reset --hard origin/${env.GIT_BRANCH}
                        git log -1 --oneline
                    """
                }
            }
        }

        stage('Stop All Dev Services') {
            when {
                expression { return params.STOP_ALL }
            }
            steps {
                script {
                    def allServices = getServiceDefinitions().collect { it.composeService }
                    composeStop(env.DEPLOY_ROOT, allServices)
                }
            }
        }

        stage('Maven Build') {
            steps {
                sh """
                    set -e
                    cat > settings.xml <<'EOF'
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 https://maven.apache.org/xsd/settings-1.0.0.xsd">
  <mirrors>
    <mirror>
      <id>aliyunmaven</id>
      <mirrorOf>*</mirrorOf>
      <name>Aliyun Maven</name>
      <url>https://maven.aliyun.com/repository/public</url>
    </mirror>
  </mirrors>
</settings>
EOF
                    echo ">>> Maven modules: ${SELECTED_MAVEN_MODULES}"
                    mvn clean package -DskipTests -s settings.xml -pl ${SELECTED_MAVEN_MODULES} -am
                """
            }
        }

        stage('Deploy Services') {
            steps {
                script {
                    def selected = collectSelectedServices(params)
                    selected.each { svc ->
                        deployOneService(env.WORKSPACE, env.DEPLOY_ROOT, svc)
                    }
                }
            }
        }

        stage('Start Dev Services') {
            steps {
                script {
                    def selected = collectSelectedServices(params)
                    def composeServices = selected.collect { it.composeService }
                    startOrRestartServices(env.DEPLOY_ROOT, composeServices)
                }
            }
        }
    }

    post {
        always {
            sh 'rm -f settings.xml || true'
            echo '>>> 开发环境构建结束'
        }
        failure {
            echo '>>> 构建失败，已部署的 jar 不会自动回滚，请检查日志'
        }
    }
}
