// Webhook + Gitlab git pull + Vapor

// def payload = readJSON text: "${payload}"
// String userName = payload.user_name
// String userEmail = payload.user_email
// String httpUrl = payload.project.http_url


pipeline {
    agent {
        docker {
            args '--network ci-net --group-add 992 -v /var/run/docker.sock:/var/run/docker.sock'
            image '303644228504.dkr.ecr.ap-southeast-1.amazonaws.com/jenkins-pipeline-agent-php-8.3-node-22:latest'
            registryCredentialsId "ecr:ap-southeast-1:aws-ec2-instance-iam-role"
            registryUrl "https://303644228504.dkr.ecr.ap-southeast-1.amazonaws.com"
        }
    }
    environment {
        HOME = '.'
    }
    stages {
        stage('Download source code from Git') {
            steps {
                script{
                    currentBuild.description = 'Step 1 of 6 Completed'
                    def pusherKeyCredId
                    def pusherCluster
                    switch(GIT_BRANCH) {
                        case "vapor/production":
                            pusherKeyCredId = 'pusher-prod-key'
                            pusherCluster   = 'ap1'
                            git(
                                url: 'https://gitlab.com/CIEFWorldwideSdnBhd/exchange-2.0.git',
                                credentialsId: 'gitlab-jenkins-localhost',
                                branch: GIT_BRANCH
                            )
                        break
                        case "vapor/staging":
                            pusherKeyCredId = 'pusher-staging-key'
                            pusherCluster   = 'ap1'
                            git(
                                url: 'https://gitlab.com/CIEFWorldwideSdnBhd/exchange-2.0.git',
                                credentialsId: 'gitlab-jenkins-localhost',
                                branch: GIT_BRANCH
                            )
                        break
                        case "vapor/development":
                            pusherKeyCredId = 'pusher-dev-key'
                            pusherCluster   = 'ap1'
                            git(
                                url: 'https://gitlab.com/CIEFWorldwideSdnBhd/exchange-2.0.git',
                                credentialsId: 'gitlab-jenkins-localhost',
                                branch: GIT_BRANCH
                            )
                        break
                        case "vapor/test":
                            pusherKeyCredId = 'pusher-test-key'
                            pusherCluster   = 'ap1'
                            git(
                                url: 'https://gitlab.com/CIEFWorldwideSdnBhd/exchange-2.0.git',
                                credentialsId: 'gitlab-jenkins-localhost',
                                branch: GIT_BRANCH
                            )
                        break
                        case "origin/dillon/34-jenkins-vapor":
                            git(
                                url: 'https://gitlab.com/CIEFWorldwideSdnBhd/exchange-2.0.git',
                                credentialsId: 'gitlab-jenkins-localhost',
                                branch: 'dillon/34-jenkins-vapor'
                            )
                        break
                    }
                    withCredentials([string(credentialsId: pusherKeyCredId, variable: 'PUSHER_KEY')]) {
                        env.MIX_PUSHER_APP_KEY     = PUSHER_KEY
                        env.MIX_PUSHER_APP_CLUSTER = pusherCluster
                        env.VITE_PUSHER_APP_KEY     = PUSHER_KEY
                        env.VITE_PUSHER_APP_CLUSTER = pusherCluster

                        println "Pusher cluster  : ${env.MIX_PUSHER_APP_CLUSTER}"
                        println "Pusher key set  : ${env.MIX_PUSHER_APP_KEY}"
                        println "Vite Pusher cluster  : ${env.VITE_PUSHER_APP_CLUSTER}"
                        println "Vite Pusher key set  : ${env.VITE_PUSHER_APP_KEY}"
                    }
                    currentBuild.description = 'Step 2 of 6 Completed'
                }
            }
        }

        stage('Install') {
            steps {
                sh 'composer update'
                script{
                    currentBuild.description = 'Step 3 of 6 Completed'
                }
            }
        }

        stage('Tests') {
            steps {
                // sh 'vendor/bin/phpunit tests/Unit'
                sh '''
                    set -e

                    export APP_ENV=testing
                    # export APP_KEY=$(php -r "echo 'base64:'.base64_encode(random_bytes(32));")
                    # export JWT_SECRET=$(php -r "echo bin2hex(random_bytes(32));")

                    # Show which PHP binary is used
                    which php
                    php -v

                    # List PHP modules to confirm pdo_mysql
                    php -m | grep pdo_mysql || echo "pdo_mysql not loaded"

                    # Show DB environment variables
                    echo "DB_CONNECTION=$DB_CONNECTION"
                    echo "DB_HOST=$DB_HOST"
                    echo "DB_PORT=$DB_PORT"
                    echo "DB_DATABASE=$DB_DATABASE"
                    echo "DB_USERNAME=$DB_USERNAME"
                    # Do NOT echo password in logs

                    php artisan migrate:fresh --force

                    vendor/bin/phpunit -c phpunit.ci.xml --group ok_to_run
                    # vendor/bin/phpunit --filter AuthenticationTest
                    # vendor/bin/phpunit -c phpunit.ci.xml --filter ListOrderTrackingLogicTest
                '''
                script{
                    currentBuild.description = 'Step 4 of 6 Completed'
                }
            }
        }

        stage('Deploy') {
            steps {
                script{
                    String gitCommitMessage = getCommitMessage()
                    println("GIT CommitMessage: " + gitCommitMessage)
                    println("GIT GIT_BRANCH: " + GIT_BRANCH)
                    switch(GIT_BRANCH) {
                        case "vapor/production":
                            sh "vendor/bin/vapor deploy production --message='${gitCommitMessage}'"
                        break
                        case "vapor/staging":
                            sh "vendor/bin/vapor deploy staging --message='${gitCommitMessage}'"
                        break
                        case "vapor/development":
                            sh "vendor/bin/vapor deploy development --message='${gitCommitMessage}'"
                        break
                        case "vapor/test":
                            sh "vendor/bin/vapor deploy test --message='${gitCommitMessage}'"
                        break
                        case "origin/dillon/34-jenkins-vapor":
                            sh "vendor/bin/vapor deploy development --message='${gitCommitMessage}'"
                        break
                    }
                    currentBuild.description = 'Step 5 of 6 Completed'
                }
            }
        }

        stage('Cleanup') {
            steps {
                script {
                    try {
                        sh '''
                            echo "Starting Docker cleanup..."

                            # Remove stopped containers
                            docker container prune -f

                            # Remove unused networks
                            docker network prune -f

                            # Remove unused images
                            docker image prune -a -f

                            # Remove unused build cache
                            docker builder prune -f

                            echo "Docker cleanup completed."

                            docker system df
                        '''
                    } catch (Exception e) {
                        echo "Error during cleanup: ${e.message}"
                    }

                    currentBuild.description = 'Step 6 of 6 Completed'
                }
            }
        }
    }
}

@NonCPS
String getCommitMessage(){
    commitMessage = " "
    for ( changeLogSet in currentBuild.changeSets){
        for (entry in changeLogSet.getItems()){
            commitMessage = entry.msg
        }
    }
    commitMessage = commitMessage.replace("'", "`")
    return commitMessage
}
