@Library('pipeline-utils')

import com.snowflake.DevEnvUtils

List<String> prodServerPatterns = ['ci-prod-200', 'jenkinsprod']
List<String> devServerPatterns = ['sql-001']
String prodArtifactoryRepo = 'internal-production-docker-data_migration-local'
String devArtifactoryRepo = 'internal-development-docker-data_migration-local'
Boolean isProdServer
Boolean isDevServer
String artifactoryRepo
String imageName = 'data-migration-orchestrator'
String version
String imageTagAmd64
String imageTagArm64

pipeline {
    agent {
        label 'small-node-snowos'
    }
    options {
        skipDefaultCheckout()
    }
    stages {
        stage("Detect Environment") {
            steps {
                script {
                    isProdServer = prodServerPatterns.any { env.JENKINS_URL?.contains(it) }
                    isDevServer = devServerPatterns.any { env.JENKINS_URL?.contains(it) }

                    if (isProdServer) {
                        echo "Running on PRODUCTION server: ${env.JENKINS_URL}"
                        artifactoryRepo = prodArtifactoryRepo
                    } else if (isDevServer) {
                        echo "Running on DEV server: ${env.JENKINS_URL}"
                        artifactoryRepo = devArtifactoryRepo
                    } else {
                        error("Unknown server: ${env.JENKINS_URL}. Expected one of: ${prodServerPatterns + devServerPatterns}")
                    }

                    echo "Using Artifactory repository: ${artifactoryRepo}"
                }
            }
        }

        stage("Checkout") {
            steps {
                script {
                    checkout([
                        $class: 'GitSCM',
                        branches: scm.branches,
                        extensions: [],
                        userRemoteConfigs: [[
                            url: scm.userRemoteConfigs[0].url,
                            credentialsId: 'jenkins-snowflake-github-app-2-emu'
                        ]]
                    ])
                }
            }
        }

        stage("Set Environment") {
            steps {
                script {
                    echo "Extracting version from __version__.py..."
                    version = sh(
                        script: "grep -oP '__version__\\s*=\\s*\"\\K[^\"]+' dmvf/shared/__version__.py",
                        returnStdout: true
                    ).trim()

                    imageTagAmd64 = "${imageName}:${version}"
                    imageTagArm64 = "${imageName}-arm64:${version}"

                    echo "Version from __version__.py: ${version}"
                    echo "Image tag (AMD64): ${imageTagAmd64}"
                    echo "Image tag (ARM64): ${imageTagArm64}"
                }
            }
        }

        stage("Check If Images Already Exist") {
            steps {
                script {
                    new DevEnvUtils().withSfCli {
                        echo "Authenticating with OCI registry..."
                        sh "sf artifact oci auth"

                        def checkRemoteImageExists = { imagePath ->
                            return sh(
                                script: """
                                    sf artifact container-images exists \\
                                        --repository ${artifactoryRepo} \\
                                        --name ${imagePath} \\
                                        --tag ${version}
                                """,
                                returnStatus: true
                            )
                        }

                        def amd64Exists = checkRemoteImageExists(imageName) == 0
                        def arm64Exists = checkRemoteImageExists("${imageName}-arm64") == 0

                        if (amd64Exists && arm64Exists) {
                            echo "Both images already exist in ${artifactoryRepo} for version ${version}."
                            echo "Nothing to do — skipping build and push."
                            env.SKIP_BUILD = 'true'
                        } else if (amd64Exists || arm64Exists) {
                            echo "Partial state detected: AMD64=${amd64Exists}, ARM64=${arm64Exists}. Rebuilding both."
                            env.SKIP_BUILD = 'false'
                        } else {
                            echo "No images found for version ${version}. Proceeding with build and push."
                            env.SKIP_BUILD = 'false'
                        }
                    }
                }
            }
        }

        stage("Build Docker Image (AMD64)") {
            when { expression { env.SKIP_BUILD != 'true' } }
            steps {
                script {
                    sh """
                        echo "=== Building Docker Image (AMD64) on native x86 ==="
                        docker build \
                            -t "${imageTagAmd64}" \
                            -f "dmvf/data-migration-orchestrator/Dockerfile" \
                            .
                        echo "=== Docker Build Complete (AMD64) ==="
                    """
                }
            }
        }

        stage("Validate Local Images") {
            when { expression { env.SKIP_BUILD != 'true' } }
            steps {
                script {
                    def checkLocalImageExists = { imageTag ->
                        return sh(
                            script: "docker images --format '{{.Repository}}:{{.Tag}}' | grep -q '^${imageTag}\$'",
                            returnStatus: true
                        )
                    }

                    echo "Validating AMD64 Docker image exists..."
                    def imageExistsAmd64 = checkLocalImageExists(imageTagAmd64)

                    if (imageExistsAmd64 != 0) {
                        error("Docker image '${imageTagAmd64}' not found. Please ensure the image was built and tagged correctly.")
                    }

                    echo "AMD64 image validated successfully. Available Docker images:"
                    sh "docker images | grep ${imageName}"
                }
            }
        }

        stage("Push AMD64 Image to Artifactory") {
            when { expression { env.SKIP_BUILD != 'true' } }
            steps {
                script {
                    new DevEnvUtils().withSfCli {
                        echo "Pushing AMD64 image to repository: ${artifactoryRepo}"

                        sh """
                            sf artifact container-images push \\
                                --image ${imageTagAmd64} \\
                                --name ${imageName} \\
                                --repository ${artifactoryRepo} \\
                                --tag ${version}
                        """
                        echo "AMD64 image push complete."
                    }
                }
            }
        }

        stage("ARM64 Image") {
            agent { label 'regular-memory-node-aarch64' }
            when {
                beforeAgent true
                expression { env.SKIP_BUILD != 'true' }
            }
            stages {
                stage("Checkout ARM64") {
                    steps {
                        script {
                            checkout([
                                $class: 'GitSCM',
                                branches: scm.branches,
                                extensions: [],
                                userRemoteConfigs: [[
                                    url: scm.userRemoteConfigs[0].url,
                                    credentialsId: 'jenkins-snowflake-github-app-2-emu'
                                ]]
                            ])
                        }
                    }
                }

                stage("Build Docker Image (ARM64)") {
                    steps {
                        script {
                            sh """
                                echo "=== Building Docker Image (ARM64) on native aarch64 ==="
                                uname -m
                                docker build \
                                    -t "${imageTagArm64}" \
                                    -f "dmvf/data-migration-orchestrator/Dockerfile" \
                                    .
                                echo "=== Docker Build Complete (ARM64) ==="
                            """
                        }
                    }
                }

                stage("Validate ARM64 Image") {
                    steps {
                        script {
                            def checkLocalImageExists = { imageTag ->
                                return sh(
                                    script: "docker images --format '{{.Repository}}:{{.Tag}}' | grep -q '^${imageTag}\$'",
                                    returnStatus: true
                                )
                            }

                            echo "Validating ARM64 Docker image exists..."
                            def imageExistsArm64 = checkLocalImageExists(imageTagArm64)

                            if (imageExistsArm64 != 0) {
                                error("Docker image '${imageTagArm64}' not found. Please ensure the ARM64 image was built and tagged correctly.")
                            }

                            echo "ARM64 image validated successfully. Available Docker images:"
                            sh "docker images | grep ${imageName}"
                        }
                    }
                }

                stage("Push ARM64 Image to Artifactory") {
                    steps {
                        script {
                            new DevEnvUtils().withSfCli {
                                echo "Pushing ARM64 image to repository: ${artifactoryRepo}"

                                sh """
                                    sf artifact container-images push \\
                                        --image ${imageTagArm64} \\
                                        --name ${imageName}-arm64 \\
                                        --repository ${artifactoryRepo} \\
                                        --tag ${version}
                                """
                                echo "ARM64 image push complete."

                                echo "All images pushed successfully to Artifactory!"
                            }
                        }
                    }
                }
            }
            post {
                always {
                    cleanWs()
                }
            }
        }
    }
    post {
        always {
            cleanWs()
        }
    }
}
