#!groovy

// Current version of this Pipeline https://github.com/VitexSoftware/BuildImages/blob/main/Test/Jenkinsfile

String[] distributions = [
			// 'debian:bookworm', // Disabled: python3-fastmcp is not published for this
			//                    // suite yet ("virtual package and not provided by any
			//                    // available package"). Re-enable once fastmcp's own
			//                    // packaging covers bookworm.
			'debian:trixie',
			// 'debian:forky', // Disabled: Forky is still unstable/research-only.
			//                 // The full Debian package ecosystem is not yet available for Forky.
			//                 // Re-enable once the stack builds cleanly for Forky.
			// 'ubuntu:jammy', // Disabled: python3-fastmcp resolves but is not installable
			//                 // on this suite (unsatisfiable transitive dependency).
			//                 // Re-enable once fastmcp's own packaging covers jammy.
			// 'ubuntu:noble', // Disabled: python3-fastmcp is not published for this
			//                 // suite yet ("virtual package and not provided by any
			//                 // available package"). Re-enable once fastmcp's own
			//                 // packaging covers noble.
			// 'ubuntu:resolute', // Disabled: python3-fastmcp resolves but is not
			//                    // installable on this suite (unsatisfiable transitive
			//                    // dependency). Re-enable once fastmcp's own packaging
			//                    // covers resolute.
]

String vendor = 'vitexsoftware'
//String distroFamily = ''

properties([
    copyArtifactPermission('*'),
    buildBlocker(
        useBuildBlocker: true,
        blockLevel: 'GLOBAL',
        scanQueueFor: 'ALL',
        blockingJobs: 'RebulidDEBRepoByAnsible'
    )
])
node() {
    ansiColor('xterm') {
        stage('SCM Checkout') {
            sh 'sudo chown -R jenkins:jenkins . 2>/dev/null || true'
            checkout scm
        }
    }
}

def branches = [:]
distributions.each { distro ->
    branches[distro] = {
        def distroName = distro
        println  "Dist:" + distroName

        def dist = distroName.split(':')
        def distroFamily = dist[0]
        def distroCode = dist[1]
        def buildImage = ''
        def artifacts = []
        def buildVer = ''

        node {
            ansiColor('xterm') {
                stage('Checkout ' + distroName) {
                    sh 'sudo chown -R jenkins:jenkins . 2>/dev/null || true'
                    checkout scm
                    buildImage = docker.image(vendor + '/' + distro)
                }
                stage('Build ' + distroName) {
                    buildImage.inside {
                        // Git operations run inside the container to avoid index.lock conflicts
                        // when multiple parallel branches share the same Jenkins agent node.
                        sh 'git checkout debian/changelog'
                        def version = sh(
                            script: 'dpkg-parsechangelog --show-field Version',
                            returnStdout: true
                        ).trim()
                        buildVer = version + '.' + env.BUILD_NUMBER + '~' + distroCode
                        // Set unique build directories for this parallel build to avoid conflicts
                        def uniqueBuildId = env.BUILD_NUMBER + '-' + distroCode + '-' + env.EXECUTOR_NUMBER
                        sh '''
                            export DH_INTERNAL_BUILDDIR="/tmp/debhelper-build-''' + uniqueBuildId + '''"
                            export TMPDIR="/tmp/build-''' + uniqueBuildId + '''"
                            mkdir -p "$DH_INTERNAL_BUILDDIR" "$TMPDIR"
                        '''
                        withEnv(["BUILDVER=${buildVer}"]) {
                            sh 'dch -b -v "$BUILDVER" "$BUILD_TAG"'
                        }
                        sh 'sudo apt-get update --allow-releaseinfo-change'
                        sh 'sudo chown jenkins:jenkins ..'
                        sh 'sudo rm -rf debian/$(dpkg-parsechangelog --show-field Source)/ debian/.debhelper/ debian/tmp/'
                        sh '''
                            export DH_INTERNAL_BUILDDIR="/tmp/debhelper-build-''' + uniqueBuildId + '''"
                            export TMPDIR="/tmp/build-''' + uniqueBuildId + '''"
                            debuild-pbuilder -r"sudo -E" -i -us -uc -b
                        '''
                        sh '''
                            mkdir -p $WORKSPACE/dist/debian/
                            rm -rf $WORKSPACE/dist/debian/*
                            while read -r deb _; do
                                case "$deb" in -*) continue;; esac
                                [ -n "$deb" ] || continue
                                mv -- "../$deb" "$WORKSPACE/dist/debian/"
                            done < debian/files
                        '''
                        artifacts = sh (
                            script: "cat debian/files | awk '{print \$1}'",
                            returnStdout: true
                        ).trim().split('\n')
                    }
                }

                stage('Test ' + distroName) {
                    buildImage.inside {
                        def debconf_debug = 0 //Set to "5" or "developer" to debug debconf
                        sh 'cd $WORKSPACE/dist/debian/ ; dpkg-scanpackages . /dev/null > Packages; gzip -9c Packages > Packages.gz; cd $WORKSPACE'
                        sh 'echo "deb [trusted=yes] file://///$WORKSPACE/dist/debian/ ./" | sudo tee /etc/apt/sources.list.d/local.list'
                        sh 'sudo apt-get update --allow-releaseinfo-change'
                        sh 'echo "INSTALATION"'

                        def installOrder = []

                        def sorted_artifacts = artifacts.toList()

                        // If installOrder is empty, install all produced packages
                        if (installOrder.isEmpty()) {
                            sorted_artifacts.each { deb_file ->
                                if (deb_file.endsWith('.deb')) {
                                    def pkgName = deb_file.tokenize('/')[-1].replaceFirst(/_.*/, '')
                                    if (!(pkgName ==~ /^[a-z0-9][a-z0-9+.\-]+$/)) { error("Invalid package name: ${pkgName}") }
                                    withEnv(["PKG=${pkgName}"]) {
                                        sh 'echo "Installing $PKG on $(lsb_release -sc)"'
                                        sh 'sudo DEBIAN_FRONTEND=noninteractive apt-get -y install "$PKG"'
                                    }
                                }
                            }
                        } else {
                            // Install packages in specified order
                            installOrder.each { pkgPrefix ->
                                def debFile = null
                                for (item in sorted_artifacts) {
                                    def itemStr = item.toString()
                                    if (itemStr.startsWith(pkgPrefix) && itemStr.endsWith('.deb')) {
                                        debFile = itemStr
                                        break
                                    }
                                }
                                if (debFile) {
                                    def pkgName = debFile.tokenize('/')[-1].replaceFirst(/_.*/, '')
                                    if (!(pkgName ==~ /^[a-z0-9][a-z0-9+.\-]+$/)) { error("Invalid package name: ${pkgName}") }
                                    withEnv(["PKG=${pkgName}"]) {
                                        sh 'echo "Installing $PKG on $(lsb_release -sc)"'
                                        sh 'sudo DEBIAN_FRONTEND=noninteractive apt-get -y install "$PKG"'
                                    }
                                }
                            }
                        }
                        sh 'sudo rm -f /etc/apt/sources.list.d/local.list'
                    }
                }
                stage('Archive artifacts ' + distroName ) {
                    // Only run if previous stages (Build and Test) succeeded
                    buildImage.inside {
                        // Archive all produced artifacts listed in debian/files
                        artifacts.each { deb_file ->
                            println "Archiving artifact: " + deb_file
                            archiveArtifacts artifacts: 'dist/debian/' + deb_file
                        }

                        // Cleanup: remove any produced files named in debian/files
                        // Try both the dist location and any potential original locations referenced by debian/files
                        def uniqueBuildId = env.BUILD_NUMBER + '-' + distroCode + '-' + env.EXECUTOR_NUMBER
                        sh '''
                            set -e
                            if [ -f debian/files ]; then
                              while read -r file _; do
                                [ -n "$file" ] || continue
                                rm -f "dist/debian/$file" || true
                                rm -f "../$file" || true
                                rm -f "$WORKSPACE/$file" || true
                              done < debian/files
                            fi
                            # Cleanup temporary build directories
                            rm -rf "/tmp/debhelper-build-''' + uniqueBuildId + '''" || true
                            rm -rf "/tmp/build-''' + uniqueBuildId + '''" || true
                        '''
                    }
                }
            }
        }
    }
}

parallel branches

node {
    stage('Publish to Aptly') {
	publishDebToAptly()
    }
}
