pipeline {
    agent any

    environment {
        IMAGE_NAME = 'myservice'
        IMAGE_TAG = "1.0.0-qa.${env.BUILD_NUMBER}"
        HARBOR_HOST = 'harbor.hostname.com'
        HARBOR_PROJECT = 'myproject'
        ENV_FILE = '.env'
        SECRET_PATH = 'env/data/myservice/stg' // ปรับตาม path ที่ใช้ใน Vault
        VAULT_ADDR = 'https://vault.hostname.com' // ปรับตาม URL ของ Vault
        VAULT_CREDENTIALS_ID = 'jenkins-vault' // ปรับตาม credential ID ที่ตั้งไว้ใน Jenkins
        DOCKER_FILE = 'Dockerfile' // ปรับตามชื่อ Dockerfile ถ้าไม่ใช่ชื่อมาตรฐาน
    }

    stages {
        stage('Load ENV from Vault') {
            steps {
                withCredentials([
                    usernamePassword(
                        credentialsId: env.VAULT_CREDENTIALS_ID,
                        usernameVariable: 'VAULT_ROLE_ID',
                        passwordVariable: 'VAULT_SECRET_ID'
                    )
                ]) {
                    script {
                        def vaultAddr = env.VAULT_ADDR // ปรับตาม URL ของ Vault
                        def roleId = env.VAULT_ROLE_ID
                        def secretId = env.VAULT_SECRET_ID

                        // 1️⃣ Login ด้วย AppRole
                        echo '🟠 Vault Login with AppRole'
                        def loginResponse = sh(
                            script: """
                            curl -s --request POST \
                            --data '{"role_id":"${roleId}","secret_id":"${secretId}"}' \
                            ${vaultAddr}/v1/auth/approle/login
                            """,
                            returnStdout: true
                        ).trim()

                        def loginJson = readJSON(text: loginResponse)

                        if (!loginJson?.auth?.client_token) {
                            error "❌ Vault login failed: ${loginResponse}"
                        }

                        def vaultToken = loginJson.auth.client_token

                        // 2️⃣ ดึง secret
                        echo '🟠 Read Secret Kv'
                        def secretResponse = sh(
                            script: """
                            curl -s \
                            -H "X-Vault-Token: ${vaultToken}" \
                            ${vaultAddr}/v1/${SECRET_PATH}
                            """,
                            returnStdout: true
                        ).trim()

                        def secretJson = readJSON(text: secretResponse)

                        if (!secretJson?.data?.data) {
                            error "❌ Secret not found or permission denied: ${secretResponse}"
                        }

                        def secretData = secretJson.data.data

                        // 3️⃣ สร้าง .env file
                        echo '🟠 Write ENV File'
                        def envContent = ''
                        secretData.each { key, value ->
                            envContent += "${key}=${value}\n"
                        }

                        writeFile file: env.ENV_FILE, text: envContent

                        echo "✅  ${env.ENV_FILE} generated from Vault"

                        echo '======= Revoke Vault Token ======='

                        sh """
                            curl -s -X POST \
                            -H "X-Vault-Token: ${vaultToken}" \
                            ${vaultAddr}/v1/auth/token/revoke-self
                        """
                    }
                }
            }
        }
        stage('Verify ENV file') {
            steps {
                script {
                    if (!fileExists(env.ENV_FILE)) {
                        error "❌ ${env.ENV_FILE} not found"
                    }

                    def lineCount = sh(
                        script: "wc -l < ${env.ENV_FILE}",
                        returnStdout: true
                    ).trim()

                    if (lineCount == '0') {
                        error "❌ ${env.ENV_FILE} is empty"
                    }

                    echo "======= ${env.ENV_FILE} exists with ${lineCount} variables"
                }
            }
        }
        stage('Build Docker image') {
            steps {
                sh """
                    docker build -f ${env.DOCKER_FILE} -t ${HARBOR_HOST}/${HARBOR_PROJECT}/${env.IMAGE_NAME}:${env.IMAGE_TAG} .
                """
            }
        }
        stage('Push Docker image to Harbor') {
            steps {
                withCredentials([
                    usernamePassword(
                        credentialsId: 'robot-harbor-ci',
                        usernameVariable: 'HARBOR_USER',
                        passwordVariable: 'HARBOR_TOKEN'
                    )
                ]) {
                    sh '''
                        echo "🔐 Logging into Harbor... ${HARBOR_HOST}"
                        echo "$HARBOR_TOKEN" | docker login ${HARBOR_HOST} -u "$HARBOR_USER" --password-stdin

                        echo "📦 Pushing image to Harbor..."
                        docker push ${HARBOR_HOST}/${HARBOR_PROJECT}/${IMAGE_NAME}:${IMAGE_TAG}

                        echo "🗑️  Removing local Docker image (if exists)..."
                        docker rmi ${HARBOR_HOST}/${HARBOR_PROJECT}/${IMAGE_NAME}:${IMAGE_TAG} || echo "Image not found, skipping."

                        echo "🚪 Logging out from Harbor..."
                        docker logout ${HARBOR_HOST}
                    '''
                }
            }
        }
    }

    post {
        always {
            echo 'Cleaning up...'
            deleteDir()
        }
    }
}
