#! /usr/bin/groovy

final String NODE_LABEL = "h2o-3"
final String DOCKER_STASH = 'h2o-3-xgb-build-docker-stash'

def pipelineContext = null

properties(
    [
        buildDiscarder(logRotator(artifactDaysToKeepStr: '', artifactNumToKeepStr: '', daysToKeepStr: '', numToKeepStr: '25')),
        parameters([
                string(name: 'gitBranch', defaultValue: 'master', description: 'Branch to load the Dockerfile from.'),
                string(name: 'registry', defaultValue: 'harbor.h2o.ai', description: 'Docker registry to push images to'),
                booleanParam(name: 'publish', defaultValue: true, description: 'If true, publish the docker image'),
                booleanParam(name: 'noCache', defaultValue: false, description: 'If set to true, the docker image is built from scratch, with no stages used from the cache.')
        ])
    ]
)

// define list of OSs for which to build the docker image,
// for each OS there must by a ci/docker/Dockerfile-gpu-<OS>
final List<String> IMAGES_MAP = ['centos'] // ubuntu disabled for now since the build is failing and the images not used
final String IMAGE_TAG = "5"
// base of the image name
final String IMAGE_NAME = "${params.registry}/opsh2oai/h2o-3-xgboost-build"

node (NODE_LABEL) {
    final String stageName = 'Checkout and Prepare'
    stage(stageName) {
        def scmEnv = git credentialsId: 'c6bab81a-6bb5-4497-9ec9-285ef5db36ea',
                poll: false,
                url: 'https://github.com/h2oai/h2o-3',
                branch: params.gitBranch

        def pipelineContextFactory = load('scripts/jenkins/groovy/pipelineContext.groovy')
        pipelineContext = pipelineContextFactory('.', 'MODE_HADOOP', scmEnv, true)

        try {
            pipelineContext.getBuildSummary().addStageSummary(this, stageName, '')
            pipelineContext.getBuildSummary().setStageDetails(this, stageName, env.NODE_NAME, env.WORKSPACE)

            pipelineContext.getBuildSummary().addSection(this, 'docker-details', "<a href=\"${currentBuild.rawBuild.getAbsoluteUrl()}\" style=\"color: black;\">Details</a>", """
                <ul>
                <li><strong>Git Branch:</strong> ${env.BRANCH_NAME}</li>
                <li><strong>No cache:</strong> ${params.noCache}</li>
                </ul>
            """)

            dir('docker') {
                withCredentials([[$class: 'AmazonWebServicesCredentialsBinding', accessKeyVariable: 'AWS_ACCESS_KEY_ID', credentialsId: 'AWS S3 Credentials', secretKeyVariable: 'AWS_SECRET_ACCESS_KEY']]) {
                    docker.image('harbor.h2o.ai/opsh2oai/s3cmd').inside("-e AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID} -e AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY}") {
                        sh "s3cmd -f get s3://artifacts.h2o.ai/releases/oracle/jdk-8/x64-linux/jdk1.8.0_171.zip"
                    }
                }
            }
            pipelineContext.getUtils().stashFiles(this, DOCKER_STASH, 'docker/xgb_build/**,docker/xgb/common/sbin/*,docker/jdk1.8.0_171.zip')

            pipelineContext.getBuildSummary().markStageSuccessful(this, stageName)
        } catch (Exception e) {
            pipelineContext.getBuildSummary().markStageFailed(this, stageName)
            throw e
        }
    }
}

final String noCache = params.noCache ? "--no-cache" : ""

parallel(IMAGES_MAP.collectEntries { image ->
    [
        "Build $image image", {
            node(pipelineContext.getBuildConfig().getDefaultNodeLabel()) {
                final String buildStageName = "Build $image"
                stage(buildStageName) {
                    try {
                        pipelineContext.getBuildSummary().addStageSummary(this, buildStageName, '')
                        pipelineContext.getBuildSummary().setStageDetails(this, buildStageName, env.NODE_NAME, env.WORKSPACE)

                        pipelineContext.getUtils().unstashFiles(this, DOCKER_STASH)

                        dir('docker') {
                            sh """                                
                                docker build \
                                    ${noCache} \
                                    -t ${IMAGE_NAME}-${image}:${IMAGE_TAG}  \
                                    -f xgb_build/Dockerfile-gpu-${image} \
                                    .
                                """
                        }

                        pipelineContext.getBuildSummary().markStageSuccessful(this, buildStageName)
                    } catch (Exception e) {
                        pipelineContext.getBuildSummary().markStageFailed(this, buildStageName)
                        throw e
                    }
                }

                if (params.publish) {
                    final String publishStageName = "Publish $image"
                    stage(publishStageName) {
                        try {
                            pipelineContext.getBuildSummary().addStageSummary(this, publishStageName, '')
                            pipelineContext.getBuildSummary().setStageDetails(this, publishStageName, env.NODE_NAME, env.WORKSPACE)

                            withCredentials([usernamePassword(credentialsId: "${params.registry}", usernameVariable: 'REGISTRY_USERNAME', passwordVariable: 'REGISTRY_PASSWORD')]) {
                                sh """
                                    docker login -u $REGISTRY_USERNAME -p $REGISTRY_PASSWORD ${params.registry}
                                    docker push ${IMAGE_NAME}-${image}:${IMAGE_TAG}
                                """
                                echo "###### Docker image ${IMAGE_NAME}-${image}:${IMAGE_TAG} built and pushed. ######"
                            }

                            pipelineContext.getBuildSummary().markStageSuccessful(this, publishStageName)
                        } catch (Exception e) {
                            pipelineContext.getBuildSummary().markStageFailed(this, publishStageName)
                            throw e
                        }
                    }
                }
            }
        }
    ]
})
