#!groovy

// The GIT checkout must use the remote branch name as the checkout local
// branch name so that tarball names contain the branch name.
// In "Additional Behaviours", enable "Checkout to specific local branch"
// and leave "Branch name" empty.
// Not needed for multi-branch pipelines which already BRANCH_NAME in the environment.

def gitRepoURL = ""
def gitBranch = ""
def tarballgz
def tarballbz2
def statusHasChanged = false

def isBasicJob = env.JOB_NAME.matches("basic/(.*)")
println('This is '+(isBasicJob ? '' : 'NOT ')+'an official Basic job.')

def isExtendedJob = env.JOB_NAME.matches("extended/(.*)")
println('This is '+(isExtendedJob ? '' : 'NOT ')+'an official Extended job.')

// all jobs run on Unix nodes (either with debug or not)
def doUnix = (env.NO_UNIX != 'true')
println('Unix is '+(doUnix ? 'enabled.' : 'disabled.'))
def doDebug = (isExtendedJob || env.FORCE_DEBUG == 'true')
println('Debug is '+(doDebug ? 'enabled.' : 'disabled.'))
// extended job doesn't run MSVC and WinCMake
def doMSVC = (!isExtendedJob && env.NO_MSVC != 'true')
println('MSVC is '+(doMSVC ? 'enabled.' : 'disabled.'))
def doWinCMake = (!isExtendedJob && env.NO_WINCMAKE != 'true')
println('WinCMake is '+(doWinCMake ? 'enabled.' : 'disabled.'))
// basic job doesn't run Coverity/Sonarqube/Embedded/MinGW/Cygwin/Android
def doCoverity = (!isBasicJob && env.NO_COVERITY != 'true')
println('Coverity is '+(doCoverity ? 'enabled.' : 'disabled.'))
def doSonarQube = (!isBasicJob && env.NO_SONARQUBE != 'true')
println('SonarQube is '+(doSonarQube ? 'enabled.' : 'disabled.'))
def doEmbedded = (!isBasicJob && env.NO_EMBEDDED != 'true')
println('Embedded is '+(doEmbedded ? 'enabled.' : 'disabled.'))
def doMinGW = (!isBasicJob && env.NO_MINGW != 'true')
println('MinGW is '+(doMinGW ? 'enabled.' : 'disabled.'))
def doCygwin = (!isBasicJob && env.NO_CYGWIN != 'true')
println('Cygwin is '+(doCygwin ? 'enabled.' : 'disabled.'))
def doAndroid =  (!isBasicJob && env.NO_ANDROID != 'true')
println('Android is '+(doAndroid ? 'enabled.' : 'disabled.'))

pipeline {
        agent none

	// Trigger the build
	triggers {
		// extended/* jobs poll GitHub explicitly once per night, in case webhooks aren't used
		pollSCM(isExtendedJob ? '30 5 * * *' : '')
	}

        stages {
		stage('Tarball') {
			steps {
				node('autotools') {
                                        checkout scm
					script {
						gitRepoURL = sh (script: 'git config --get remote.origin.url', returnStdout: true).trim()
						gitBranch = sh (script: 'if test "$BRANCH_NAME"; then echo $BRANCH_NAME; else git rev-parse --abbrev-ref HEAD; fi', returnStdout: true).trim()
						sh 'contrib/ci.inria.fr/job-0-tarball.sh '+gitBranch
						tarballgz = sh (script: 'ls *.gz', returnStdout: true).trim()
						tarballbz2 = sh (script: 'ls *.bz2', returnStdout: true).trim()
						stash includes: tarballgz, name: 'tarballgz'
						if (doAndroid) {
							sh 'tar zcvf android.tar.gz contrib/android'
							stash includes: "android.tar.gz", name: 'tar-android'
						}
					}
					dir('contrib/ci.inria.fr') {
						script {
							if (doUnix && !doDebug) {
								stash includes: "job-1-check.sh", name: 'script-unix-check'
							}
							if (doUnix && doDebug) {
								stash includes: "job-3-debug.sh", name: 'script-unix-debug'
							}
							if (doMSVC) {
								stash includes: "job-1-visualstudio.bat", name: 'script-msvc'
							}
							if (doWinCMake) {
								stash includes: "job-1-wincmake.bat", name: 'script-wincmake'
							}
							if (doMinGW) {
								stash includes: "job-3-mingw.*", name: 'scripts-mingw'
							}
							if (doCygwin) {
								stash includes: "job-3-cygwin.*", name: 'scripts-cygwin'
							}
							if (doAndroid) {
								stash includes: "job-3-android.sh", name: 'script-android'
							}
							if (doEmbedded) {
								stash includes: "job-3-embedded.sh", name: 'script-embedded'
							}
							if (doCoverity) {
								stash includes: "job-3-coverity.sh", name: 'script-coverity'
							}
							if (doSonarQube) {
								stash includes: "job-3-sonarscanner.sh", name: 'script-sonarscanner'
							}
						}
					}
					archiveArtifacts artifacts: tarballgz+","+tarballbz2+",doc/doxygen-doc/hwloc-a4.pdf", fingerprint: true, onlyIfSuccessful: true
					deleteDir()
				}
			}
		}
		stage('Check') {
			steps {
				script {
					listOfNodeNames = []
					if (doUnix) {
						listOfNodeNames = nodesByLabel('unix')
					}
					if (doMSVC) {
						listOfNodeNames.push('VisualStudio')
					}
					if (doWinCMake) {
						listOfNodeNames.push('WinCMake')
					}
					if (doMinGW) {
						listOfNodeNames.push('MinGW64')
						listOfNodeNames.push('MinGW32')
					}
					if (doCygwin) {
						listOfNodeNames.push('Cygwin')
					}
					if (doAndroid) {
						listOfNodeNames.push('AndroidStudio')
					}
					if (doCoverity) {
						listOfNodeNames.push('Coverity')
					}
					if (doSonarQube) {
						listOfNodeNames.push('SonarQube Scanner')
					}
					if (doEmbedded) {
						listOfNodeNames.push('Embedded')
					}
					println('listOfNodeNames: '+listOfNodeNames)

					def p = listOfNodeNames.collectEntries {
					[ (it): {
						if (it == 'VisualStudio') {
							node('msvc') {
								dir('check-msvc') {
									unstash 'tarballgz'
									unstash 'script-msvc'
									bat 'job-1-visualstudio.bat '+tarballgz
									if (env.KEEP_WORKING_DIRECTORY != 'true')
										deleteDir()
								}
							}
						} else if (it == 'WinCMake') {
							node('wincmake') {
								dir('check-wincmake') {
									unstash 'tarballgz'
									unstash 'script-wincmake'
									bat 'job-1-wincmake.bat '+tarballgz
									if (env.KEEP_WORKING_DIRECTORY != 'true')
										deleteDir()
								}
							}
						} else if (it == 'MinGW64') {
							node('mingw64') {
								dir('check-mingw64') {
									unstash 'tarballgz'
									unstash 'scripts-mingw'
									bat 'job-3-mingw.bat '+tarballgz+' 64'
									archiveArtifacts artifacts: "*.zip", fingerprint: true, onlyIfSuccessful: true
									if (env.KEEP_WORKING_DIRECTORY != 'true')
										deleteDir()
								}
							}
						} else if (it == 'MinGW32') {
							node('mingw32') {
								dir('check-mingw32') {
									unstash 'tarballgz'
									unstash 'scripts-mingw'
									bat 'job-3-mingw.bat '+tarballgz+' 32'
									archiveArtifacts artifacts: "*.zip", fingerprint: true, onlyIfSuccessful: true
									if (env.KEEP_WORKING_DIRECTORY != 'true')
										deleteDir()
								}
							}
						} else if (it == 'Cygwin') {
							node('cygwin') {
								dir('check-cygwin') {
									unstash 'tarballgz'
									unstash 'scripts-cygwin'
									bat './job-3-cygwin.bat '+tarballgz
									if (env.KEEP_WORKING_DIRECTORY != 'true')
										deleteDir()
								}
							}
						} else if (it == 'Coverity') {
							node('coverity') {
								dir('check-coverity') {
									unstash 'tarballgz'
									unstash 'script-coverity'
									sh 'chmod 755 job-3-coverity.sh && ./job-3-coverity.sh '+gitRepoURL+' '+gitBranch+' '+tarballgz
									if (env.KEEP_WORKING_DIRECTORY != 'true')
										deleteDir()
								}
							}
						} else if (it == 'SonarQube Scanner') {
							node('sonarscanner') {
								dir('check-sonarscanner') {
									unstash 'tarballgz'
									unstash 'script-sonarscanner'
									sh 'chmod 755 job-3-sonarscanner.sh && ./job-3-sonarscanner.sh '+gitRepoURL+' '+gitBranch+' '+tarballgz
									if (env.KEEP_WORKING_DIRECTORY != 'true')
										deleteDir()
								}
							}
						} else if (it == 'Embedded') {
							node('autotools') {
								dir('check-embedded') {
									unstash 'tarballgz'
									unstash 'script-embedded'
									sh 'chmod 755 job-3-embedded.sh && ./job-3-embedded.sh '+tarballgz
									if (env.KEEP_WORKING_DIRECTORY != 'true')
										deleteDir()
								}
							}
						} else if (it == 'AndroidStudio') {
							node('android') {
								dir('check-android') {
									unstash 'script-android'
									unstash 'tar-android'
									unstash 'tarballgz'
									sh 'chmod 755 job-3-android.sh && ./job-3-android.sh '+tarballgz
									archiveArtifacts artifacts: "lstopo-android/*.apk", fingerprint: true, onlyIfSuccessful: true
									if (env.KEEP_WORKING_DIRECTORY != 'true')
										deleteDir()
								}
							}
						} else if (doDebug) {
							node(it) {
								dir('check-unix-debug') {
									unstash 'tarballgz'
									unstash 'script-unix-debug'
									sh 'chmod 755 job-3-debug.sh && ./job-3-debug.sh '+tarballgz
									if (env.KEEP_WORKING_DIRECTORY != 'true')
										deleteDir()
								}
							}
						} else {
							node(it) {
								dir('check-unix') {
									unstash 'tarballgz'
									unstash 'script-unix-check'
									sh 'chmod 755 job-1-check.sh && ./job-1-check.sh '+tarballgz
									if (env.KEEP_WORKING_DIRECTORY != 'true')
										deleteDir()
								}
							}
						}
					}]}
					parallel p;
				}
			}
		}
	}

	post {
		// hooks are called in order: always, changed, aborted, failure, success, unstable
		changed {
			echo "Build status has changed."
			script {
				statusHasChanged = true
			}
		}
		success {
			echo "Build success."
			// email when changed to success
			script {
				if (statusHasChanged || env.EMAIL_NOTIFICATION == 'true') {
					emailext(body: '${DEFAULT_CONTENT}',
						 subject: '${DEFAULT_SUBJECT}',
						 replyTo: '$DEFAULT_REPLYTO',
						 to: '$DEFAULT_RECIPIENTS',
						 recipientProviders: [[$class: 'CulpritsRecipientProvider'],[$class: 'RequesterRecipientProvider']])
				}
			}
		}
		failure {
			echo "Build failure."
			// always email on failure
			emailext(body: '${DEFAULT_CONTENT}',
				 subject: '${DEFAULT_SUBJECT}',
				 replyTo: '$DEFAULT_REPLYTO',
				 to: '$DEFAULT_RECIPIENTS',
				 recipientProviders: [[$class: 'CulpritsRecipientProvider'],[$class: 'RequesterRecipientProvider']])
		}
	}
}
