/**
 * Pipeline to run the test suite and build a Debian package.
 *
 * https://industrial.jenkins.tttech.com/view/NERVE/
 *
 * See also:
 *  https://confluence.tttech.com/display/NER/Debian+packages
 *  https://confluence.tttech.com/display/NER/Jenkins
 *  https://confluence.tttech.com/display/JENKINS/Pipeline+guides+and+examples
 *  https://confluence.tttech.com/display/INFRA/How+to+Configure+a+Jenkins+Pipeline+job+for+doc-builder+Docker
 */
@Library('nerve-jenkins-libraries') _

/* Additional mounts for gbp docker */
def gbp_volumes = [:]

pipeline {
    agent { label 'nerve && docker && nerve-main' }
    environment {
        APT_MIRROR = 'apt.nerve.cloud'
        HOME = sh(script: "mkdir -p build/ && mktemp -d -p $WORKSPACE/build/", returnStdout: true).trim()
    }
    options {
        buildDiscarder(logRotator(
            artifactDaysToKeepStr: '30',
            artifactNumToKeepStr: '45',
            daysToKeepStr: '30',
            numToKeepStr: '45'
        ))
        timestamps()
    }
    parameters {
        string(
            name: 'DIST',
            defaultValue: 'buster',
            description: 'Release to build for (buster = development)'
        )
        choice(
            name: 'ARCH',
            choices: 'amd64\ni386',
            description: 'Architecture to build on (for now should always be "amd64")'
        )
        booleanParam (
            name : 'UPLOAD',
            defaultValue: env.BRANCH_NAME == 'integration',
            description: 'Upload package to APT repository.'
        )
        string(
            name: 'APT_COMPONENT',
            defaultValue: 'main',
            description: 'APT component to upload to.'
        )
        string (
            name : 'LOCAL_APT_PATTERNS',
            defaultValue: '',
            description: 'Inject packages from Artifactory for testing purposes. You can use a comma-separated list of patterns.'
        )
        string(
            name: 'PARENT_BUILD_NAME',
            defaultValue: '',
            description: '<strong>Internal use only.</strong>'
        )
        string(
            name: 'PARENT_BUILD_NUMBER',
            defaultValue: '',
            description: '<strong>Internal use only.</strong>'
        )
    }
    stages {
        stage ('Prepare environment') {
            steps {
                nervePrepare()
                nerveAptCheckStatus()
                nerveArtifactoryDockerLogin()
            }
        }

        stage ('Prepare local APT') {
            when {expression { return params.LOCAL_APT_PATTERNS != '' }}
            steps {
                /* Download required artifacts */
                script {
                    sh "rm -rf build/apt" /* Force local APT cleanup */
                    def files = []
                    /* Inject packages from Artifactory to local apt repository for testing */
                    params.LOCAL_APT_PATTERNS.split(',').each {
                        p -> files.add("""
                            {
                                "pattern": "${p.trim()}",
                                "target": "build/apt/",
                                "flat": true
                            }
                        """)
                    }
                    retry(3) {
                        rtDownload(
                            serverId: 'TTTech Artifactory',
                            failNoOp: true,
                            spec: """{"files": $files}"""
                        )
                    }
                    /* Create APT repository */
                    sh """
                        (cd build/apt && apt-ftparchive packages . > Packages && apt-ftparchive packages . > Release)
                        echo "deb [trusted=yes] file:/opt/local-apt ./" > ${env.WORKSPACE}/build/local-apt.list
                    """
                    /* Add repo and list to gbp docker */
                    gbp_volumes["${env.WORKSPACE}/build/apt"] = "/opt/local-apt"
                    gbp_volumes["${env.WORKSPACE}/build/local-apt.list"] = "/etc/apt/sources.list.d/local-apt.list"
                }
            }
        }

        /* Unfortunately, there is no test suite.
        stage ('Test') {
            environment {
                BASE_IMAGE = "$REGISTRY/nervesw/nerve:${params.DIST}"
                DOCKER_BUILD_ARGS = "--pull -t $DOCKER_SAFE_TAG -f Dockerfile.test --label=$DOCKER_LABEL"
            }
            steps {
                sh "docker build --build-arg IMAGE=$BASE_IMAGE $DOCKER_BUILD_ARGS ."
                sh "docker run --rm --user $UID:$GID -v $WORKSPACE:/dest/ $DOCKER_SAFE_TAG"
            }
        }
        */

        stage ('Build package') {
            steps {
                script {
                    gbp_volumes["${env.WORKSPACE}/debian/docker-build.sh"] = "/usr/local/bin/build.sh"
                    gbp_volumes["${env.WORKSPACE}/debian/docker-gbp.sh"] = "/usr/local/bin/gbp.sh"
                    nerveGitBuildpackage(volumes: gbp_volumes)
                }
            }
        }
        stage ('Upload to Artifactory') {
            steps {
                nerveArtifactoryUpload spec: "build/${params.DIST}-${params.ARCH}/*"
            }
        }
        stage ('Upload to APT') {
            when { expression { return params.UPLOAD } }
            steps {
                nerveAptUpload()
            }
        }
    }
    post {
        always {
            archiveArtifacts artifacts: "build/${params.DIST}-${params.ARCH}/*", fingerprint: true, allowEmptyArchive: true
            cleanWs()
            nerveCleanup()
        }
    }
}
