pipeline {
    parameters {
        string(
            name: 'IMAGE_VERSION',
            defaultValue: '',
            description: 'Optional override for the Docker image tag (e.g., stable, release, 0.0.2). Leave empty to use the commit hash.'
        )
        string(
            name: 'GIT_REF',
            defaultValue: '',
            description: 'Branch or tag to build. Leave empty to use Jenkins-provided branch or default to main.'
        )
        booleanParam(
            name: 'CLEAN_BUILD',
            defaultValue: false,
            description: 'Run docker build --pull --no-cache when true.'
        )
    }

    agent any

    environment {
        GIT_URL = 'https://gitea.mindboost.team/mindboost/education-flagger.git'
        HEADER_IMAGE_NAME = 'mindboost/education-flagger-header'
        UPDATER_IMAGE_NAME = 'mindboost/education-flagger-updater'
        LOCAL_HEADER_IMAGE_NAME = 'education_flagger_header_image'
        LOCAL_UPDATER_IMAGE_NAME = 'education_flagger_updater_image'
        GIT_CREDENTIALS_ID = 'b5f383be-8c74-40f9-b7e1-3a9c5856df0e'
        REGISTRY_CREDENTIALS_ID = '62d300cc-d8c6-437a-8699-c58b9e1edcb0'
        REGISTRY_SCHEME = 'https'
        REGISTRY_HOST = 'gitea.mindboost.team'
    }

    stages {
        stage('Checkout') {
            steps {
                script {
                    def selectedRef = params?.GIT_REF?.trim()
                    if (!selectedRef) {
                        selectedRef = env.CHANGE_BRANCH ?: env.BRANCH_NAME ?: env.GIT_BRANCH
                    }
                    if (!selectedRef) {
                        selectedRef = 'main'
                        echo "No GIT_REF supplied. Falling back to 'main'."
                    }

                    def normalizedRef = selectedRef.replaceFirst('^origin/', '')
                    def branchSpec = normalizedRef.startsWith('refs/') ? normalizedRef : "*/${normalizedRef}"
                    echo "Checking out '${branchSpec}' from ${env.GIT_URL}"

                    checkout([
                        $class: 'GitSCM',
                        branches: [[name: branchSpec]],
                        userRemoteConfigs: [[
                            url: env.GIT_URL,
                            credentialsId: env.GIT_CREDENTIALS_ID
                        ]]
                    ])
                }
            }
        }

        stage('Check Repository') {
            steps {
                script {
                    sh 'pwd'
                    sh 'ls -la'
                    sh 'git status'
                }
            }
        }

        stage('Determine Version') {
            steps {
                script {
                    def imageVersion = ''

                    if (params?.IMAGE_VERSION) {
                        imageVersion = params.IMAGE_VERSION.trim()
                        echo "Using build parameter IMAGE_VERSION=${imageVersion}"
                    }

                    if (!imageVersion) {
                        def longSha = sh(
                            script: 'git rev-parse HEAD',
                            returnStdout: true
                        ).trim()
                        imageVersion = "sha256-${longSha}"
                        echo "No IMAGE_VERSION provided. Falling back to commit hash: ${imageVersion}"
                    }

                    def sanitized = imageVersion.replaceAll('[^A-Za-z0-9_.-]', '-')
                    if (sanitized != imageVersion) {
                        echo "Sanitized version value from '${imageVersion}' to '${sanitized}' for Docker tag compatibility."
                    }

                    env.IMAGE_TAG = sanitized
                    echo "Resolved image tag: ${env.IMAGE_TAG}"
                }
            }
        }

        stage('Get Commit Hash') {
            steps {
                script {
                    env.GIT_COMMIT_SHORT = sh(
                        script: 'git rev-parse --short HEAD',
                        returnStdout: true
                    ).trim()
                    echo "Commit Hash: ${env.GIT_COMMIT_SHORT}"
                }
            }
        }

        stage('Check Docker Images with the same tag') {
            steps {
                script {
                    def cleanBuild = params?.CLEAN_BUILD == true
                    def headerImageExists = sh(
                        script: "docker images -q ${env.LOCAL_HEADER_IMAGE_NAME}:${env.IMAGE_TAG} || true",
                        returnStdout: true
                    ).trim()
                    def updaterImageExists = sh(
                        script: "docker images -q ${env.LOCAL_UPDATER_IMAGE_NAME}:${env.IMAGE_TAG} || true",
                        returnStdout: true
                    ).trim()

                    if (cleanBuild) {
                        echo "CLEAN_BUILD=true: ignoring existing local images for tag ${env.IMAGE_TAG}."
                    } else if (headerImageExists && updaterImageExists) {
                        echo "Both Docker images with tag ${env.IMAGE_TAG} already exist locally. Skipping build."
                        currentBuild.result = 'SUCCESS'
                        return
                    } else {
                        echo 'At least one local Docker image is missing. Building fresh images.'
                    }
                }
            }
        }

        stage('Build Docker Images') {
            when {
                expression { currentBuild.result == null }
            }
            steps {
                script {
                    def cleanBuild = params?.CLEAN_BUILD == true
                    def buildFlags = cleanBuild ? '--pull --no-cache ' : ''
                    sh "docker build ${buildFlags}-t ${env.LOCAL_HEADER_IMAGE_NAME}:${env.IMAGE_TAG} ."
                    sh "docker build ${buildFlags}-t ${env.LOCAL_UPDATER_IMAGE_NAME}:${env.IMAGE_TAG} ./asn-updater"
                }
            }
        }

        stage('Push Docker Images') {
            when {
                expression { currentBuild.result == null }
            }
            steps {
                script {
                    withCredentials([
                        usernamePassword(
                            credentialsId: env.REGISTRY_CREDENTIALS_ID,
                            usernameVariable: 'REGISTRY_USER',
                            passwordVariable: 'REGISTRY_PASS'
                        )
                    ]) {
                        def registryAuthority = env.REGISTRY_HOST
                        def registryEndpoint = "${env.REGISTRY_SCHEME}://${registryAuthority}"
                        def remoteHeaderImageTag = "${registryAuthority}/${env.HEADER_IMAGE_NAME}:${env.IMAGE_TAG}"
                        def remoteUpdaterImageTag = "${registryAuthority}/${env.UPDATER_IMAGE_NAME}:${env.IMAGE_TAG}"

                        withEnv([
                            "REGISTRY_AUTHORITY=${registryAuthority}",
                            "REGISTRY_ENDPOINT=${registryEndpoint}",
                            "REMOTE_HEADER_IMAGE_TAG=${remoteHeaderImageTag}",
                            "REMOTE_UPDATER_IMAGE_TAG=${remoteUpdaterImageTag}"
                        ]) {
                            sh '''
                              set -eux
                              if [ -z "${IMAGE_TAG:-}" ]; then
                                echo "IMAGE_TAG is empty. Did the Determine Version stage run?" >&2
                                exit 1
                              fi
                              if [ -z "${REGISTRY_USER:-}" ]; then
                                echo "REGISTRY_USER is empty. Check Jenkins credentials mapping." >&2
                                exit 1
                              fi
                              if [ -z "${REGISTRY_PASS:-}" ]; then
                                echo "REGISTRY_PASS is empty. Check Jenkins credentials mapping." >&2
                                exit 1
                              fi
                              if [ -z "${REGISTRY_AUTHORITY:-}" ]; then
                                echo "REGISTRY_AUTHORITY is empty. Registry authority not resolved." >&2
                                exit 1
                              fi
                              if [ -z "${REGISTRY_ENDPOINT:-}" ]; then
                                echo "REGISTRY_ENDPOINT is empty. Registry endpoint not resolved." >&2
                                exit 1
                              fi
                              if [ -z "${REMOTE_HEADER_IMAGE_TAG:-}" ]; then
                                echo "REMOTE_HEADER_IMAGE_TAG is empty. Derived header Docker tag missing." >&2
                                exit 1
                              fi
                              if [ -z "${REMOTE_UPDATER_IMAGE_TAG:-}" ]; then
                                echo "REMOTE_UPDATER_IMAGE_TAG is empty. Derived updater Docker tag missing." >&2
                                exit 1
                              fi

                              docker --version
                              docker info
                              docker image inspect "$LOCAL_HEADER_IMAGE_NAME:$IMAGE_TAG" >/dev/null
                              docker image inspect "$LOCAL_UPDATER_IMAGE_NAME:$IMAGE_TAG" >/dev/null

                              echo "Logging into Docker registry $REGISTRY_ENDPOINT as $REGISTRY_USER"
                              echo "$REGISTRY_PASS" | docker login "$REGISTRY_ENDPOINT" --username "$REGISTRY_USER" --password-stdin
                              docker tag "$LOCAL_HEADER_IMAGE_NAME:$IMAGE_TAG" "$REMOTE_HEADER_IMAGE_TAG"
                              docker tag "$LOCAL_UPDATER_IMAGE_NAME:$IMAGE_TAG" "$REMOTE_UPDATER_IMAGE_TAG"
                              echo "Pushing Docker image $REMOTE_HEADER_IMAGE_TAG to $REGISTRY_AUTHORITY"
                              docker push "$REMOTE_HEADER_IMAGE_TAG"
                              echo "Pushing Docker image $REMOTE_UPDATER_IMAGE_TAG to $REGISTRY_AUTHORITY"
                              docker push "$REMOTE_UPDATER_IMAGE_TAG"
                              docker logout "$REGISTRY_ENDPOINT"
                            '''
                        }
                    }
                }
            }
        }

        stage('Cleanup Docker Images') {
            when {
                expression { currentBuild.result == null }
            }
            steps {
                sh '''
                  set -eux
                  docker image prune -f
                  docker builder prune -f
                '''
            }
        }
    }
}
