pipeline {
    agent any

    environment {
        DOCKER_HUB_USERNAME = 'aimodocker'
        // This creates DOCKER_AUTH_USR and DOCKER_AUTH_PSW
        DOCKER_AUTH = credentials('aimodocker') 
        IMAGE_NAME = 'oh-service'
        SERVICE_NAME = 'be-optimumoh'
        
        SECURITY_PREFIX = 'security' 
        VAULT_ADDR = 'http://127.0.0.1:8200'
        VAULT_KV_PATH = 'secret/data/Ep=X1qdWqzh+H&x&dRmV'
        VAULT_ENV_FILE = 'vault.env'
        TEMP_DOCKERFILE = 'Dockerfile.ci'

        // Initialize variables to be updated in script blocks
        GIT_COMMIT_HASH = ""
        IMAGE_TAG = ""
        SECONDARY_TAG = ""

    }


    stages {
        stage('Checkout & Setup') {
            steps {
                script {
                    checkout scm
                    GIT_COMMIT_HASH = sh(script: 'git rev-parse --short HEAD', returnStdout: true).trim()
                    
                    // Use env.BRANCH_NAME or logic to handle detached HEAD if necessary
                    def branch = env.BRANCH_NAME ?: 'unknown'
                    echo "Current Branch: ${branch}"

                    if (branch == 'main') {
                        IMAGE_TAG = GIT_COMMIT_HASH
                        SECONDARY_TAG = 'latest'
                    } else if (branch == 'oh_security') {
                        IMAGE_TAG = "${SECURITY_PREFIX}-${GIT_COMMIT_HASH}"
                        SECONDARY_TAG = "${SECURITY_PREFIX}-latest"
                    } else {
                        IMAGE_TAG = "temp-${GIT_COMMIT_HASH}"
                        SECONDARY_TAG = "" // Ensure it's empty for other branches
                    }

                    echo "Primary Tag: ${IMAGE_TAG}"
                }
            }
        }
        

        stage('Docker Login') {
            steps {
                // Fixed variable names based on the 'DOCKER_AUTH' environment key
                sh "echo ${DOCKER_AUTH_PSW} | docker login -u ${DOCKER_AUTH_USR} --password-stdin"
            }
        }

        stage('Setup Vault SSH Tunnel') {
            steps {
                sshagent(credentials: ['vault-server-ssh-key']) {
                    sh """#!/bin/bash
                        pkill -f 'ssh.*8200:127.0.0.1:8200' || true
                        sleep 1
                        ssh -fN \
                            -L 8200:127.0.0.1:8200 \
                            -o StrictHostKeyChecking=no \
                            -o ServerAliveInterval=30 \
                            -o ExitOnForwardFailure=yes \
                            aimo@192.168.1.105
                        for i in \$(seq 1 10); do
                            if curl -sf --connect-timeout 2 'http://127.0.0.1:8200/v1/sys/health' > /dev/null 2>&1; then
                                echo "✓ Vault tunnel is ready"
                                exit 0
                            fi
                            echo "Waiting... (\$i/10)"
                            sleep 2
                        done
                        exit 1
                    """
                }
            }
        }

        stage('Fetch Runtime Env from Vault') {
            steps {
                script {
                    withCredentials([
                        string(credentialsId: 'vault-approle-role-id', variable: 'CI_VAULT_ROLE_ID'),
                        string(credentialsId: 'vault-approle-secret-id', variable: 'CI_VAULT_SECRET_ID')
                    ]) {
                        def roleId = env.CI_VAULT_ROLE_ID
                        def secretId = env.CI_VAULT_SECRET_ID
                        def loginPayload = """{"role_id":"${roleId}","secret_id":"${secretId}"}"""

                        def loginResponse = sh(
                            script: '''curl -sS --fail --connect-timeout 10 \
                                --request POST \
                                --header 'Content-Type: application/json' \
                                --data "{\\"role_id\\":\\"${CI_VAULT_ROLE_ID}\\",\\"secret_id\\":\\"${CI_VAULT_SECRET_ID}\\"}" \
                                'http://127.0.0.1:8200/v1/auth/approle/login' ''',
                            returnStdout: true
                        ).trim()

                        def vaultToken = sh(
                            script: "echo '${loginResponse}' | python3 -c \"import json,sys; print(json.load(sys.stdin)['auth']['client_token'])\"",
                            returnStdout: true
                        ).trim()

                        def secretResponse = sh(
                            script: """curl -sS --fail --connect-timeout 10 \
                                --header "X-Vault-Token: ${vaultToken}" \
                                '${VAULT_ADDR}/v1/${VAULT_KV_PATH}'""",
                            returnStdout: true
                        ).trim()

                        def pythonScript = '''import json, os
with open('/tmp/vault_response.json') as f:
    payload = json.load(f)
data = payload.get("data", {}).get("data", {})
if not data:
    raise SystemExit("ERROR: Vault secret is empty")
def render_env_line(key, value):
    if value is None:
        return key + "="
    text = str(value)
    has_special = text == "" or " " in text or "#" in text or "\\t" in text
    if has_special:
        escaped = text.replace('"', '\\\\"')
        return key + "=" + '"' + escaped + '"'
    return key + "=" + text
workspace = os.environ.get("WORKSPACE", ".")
with open(workspace + "/vault.env", "w") as f:
    for key in sorted(data.keys()):
        f.write(render_env_line(key, data[key]) + "\\n")
print("Generated vault.env with " + str(len(data)) + " keys")
'''

                        writeFile(file: '/tmp/vault_response.json', text: secretResponse)
                        writeFile(file: '/tmp/process_vault.py', text: pythonScript)

                        sh "python3 /tmp/process_vault.py"
                        sh "chmod 600 vault.env"
                        sh "echo '=== Vault.env content ===' && cat vault.env | head -20"
                        echo "✓ vault.env ready"
                    }
                }
            }
        }

        stage('Build & Tag') {
            steps {
                script {
                    def fullImageName = "${DOCKER_HUB_USERNAME}/${IMAGE_NAME}"
                    // Build image TANPA vault.env - image tetap bersih
                    sh "docker build -t ${fullImageName}:${IMAGE_TAG} ."
                    if (SECONDARY_TAG) {
                        sh "docker tag ${fullImageName}:${IMAGE_TAG} ${fullImageName}:${SECONDARY_TAG}"
                    }
                }
            }
        }

        stage('Push to Docker Hub') {
            steps {
                script {
                    def fullImageName = "${DOCKER_HUB_USERNAME}/${IMAGE_NAME}"
                    sh "docker push ${fullImageName}:${IMAGE_TAG}"
                    if (SECONDARY_TAG) {
                        sh "docker push ${fullImageName}:${SECONDARY_TAG}"
                    }
                }
            }
        }

        stage('Deploy to Server') {
            steps {
                sshagent(credentials: ['vault-server-ssh-key']) {
                    sh """#!/bin/bash
                        # Transfer vault.env ke server deployment via SSH
                        # File disimpan di /tmp — tidak persistent
                        echo "=== SCP transferring env file ==="
                        scp -o StrictHostKeyChecking=no \
                            vault.env \
                            aimo@192.168.1.105:/tmp/${SERVICE_NAME}.env

                        # Set permission ketat
                        ssh -o StrictHostKeyChecking=no aimo@192.168.1.105 \
                            'chmod 600 /tmp/${SERVICE_NAME}.env && \
                             echo "=== Env file transferred ===" && \
                             ls -lh /tmp/${SERVICE_NAME}.env'

                        # Jalankan deploy dengan env-file dari /tmp
                        ssh -o StrictHostKeyChecking=no aimo@192.168.1.105 \
                            'cd ~ && \
                             echo "=== Checking env file ===" && \
                             ls -lh /tmp/${SERVICE_NAME}.env && \
                             echo "=== lines of env file ===" && \
                             cat /tmp/${SERVICE_NAME}.env && \
                             cp /tmp/${SERVICE_NAME}.env .env && \
                             echo "=== Copied to .env for docker compose ===" && \
                             docker compose  pull ${SERVICE_NAME} && \
                             docker rm -f ${SERVICE_NAME} || true && \
                             docker compose -p digitaltwin up -d --no-deps ${SERVICE_NAME} && \
                             rm -f /tmp/${SERVICE_NAME}.env && \
                             echo "✓ ${SERVICE_NAME} deployed, env file removed"'
                    """
                }
            }
        }
    }

    post {
        always {
            script {
                // Hapus vault.env dari Jenkins workspace
                sh 'rm -f vault.env /tmp/vault_response.json /tmp/process_vault.py || true'
                sh 'pkill -f "ssh.*8200:127.0.0.1:8200" || true'
                sh 'docker logout || true'
                def fullImageName = "${DOCKER_HUB_USERNAME}/${IMAGE_NAME}"
                sh "docker rmi ${fullImageName}:${IMAGE_TAG} || true"
                if (SECONDARY_TAG) {
                    sh "docker rmi ${fullImageName}:${SECONDARY_TAG} || true"
                }
            }
        }
    }
}
