@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[^\"]+' data-migration-orchestrator/src/data_migration_orchestrator/__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 Images") {
            when { expression { env.SKIP_BUILD != 'true' } }
            steps {
                script {
                    sh """
                        echo "=== Setting up Docker Buildx for multi-platform builds ==="
                        docker run --rm --privileged multiarch/qemu-user-static --reset -p yes
                        docker buildx create --name multiplatform-builder --use --bootstrap

                        echo "=== Building Docker Image (AMD64) ==="
                        docker buildx build --platform linux/amd64 --load \
                            -t "${imageTagAmd64}" \
                            -f "data-migration-orchestrator/Dockerfile" \
                            .
                        echo "=== Docker Build Complete (AMD64) ==="

                        echo "=== Building Docker Image (ARM64) ==="
                        docker buildx build --platform linux/arm64 --load \
                            -t "${imageTagArm64}" \
                            -f "data-migration-orchestrator/Dockerfile" \
                            .
                        echo "=== Docker Build Complete (ARM64) ==="
                    """
                }
            }
        }

        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 Docker images exist..."
                    def imageExistsAmd64 = checkLocalImageExists(imageTagAmd64)
                    def imageExistsArm64 = checkLocalImageExists(imageTagArm64)

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

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

                    echo "All images 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("Push ARM64 Image to Artifactory") {
            when { expression { env.SKIP_BUILD != 'true' } }
            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 {
            script {
                if (env.SKIP_BUILD != 'true') {
                    sh """
                        echo "=== Cleaning up Docker Buildx ==="
                        docker buildx rm multiplatform-builder || true
                        echo "=== Buildx cleanup complete ==="
                    """
                }
            }
            cleanWs()
        }
    }
}
