/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

def AGENT_LABEL = env.AGENT_LABEL ?: 'ubuntu'
def JDK_NAME = env.JDK_NAME ?: 'jdk_11_latest'
def MAVEN_NAME = env.MAVEN_NAME ?: 'maven_3_latest'

def MAVEN_PARAMS = "-T 2 -U -B -e -fae -V -Dmaven.compiler.fork=true -Dsurefire.rerunFailingTestsCount=2"

pipeline {

    agent {
        label AGENT_LABEL
    }

    triggers {
        cron('H H(2-7) * * *')
    }

    tools {
        jdk JDK_NAME
        maven MAVEN_NAME
    }

    environment {
        MAVEN_SKIP_RC = true
        dockerImage = ''
        imagename = 'hop'
        jenkins_user = "${USER}"
        jenkins_uid = sh(script: "id -u ${USER}", returnStdout: true).trim()
        jenkins_gid = sh(script: "id -g ${USER}", returnStdout: true).trim()
        jenkins_group = sh(script: "id -gn ${USER}", returnStdout: true).trim()
    }

    options {
        buildDiscarder(
            logRotator(artifactNumToKeepStr: '5', numToKeepStr: '10')
        )
        disableConcurrentBuilds()
    }

    stages {
        stage('Initialization') {
              steps {
                  echo 'Using PATH = ' + env.PATH
                  echo 'Using Jenkins user = ' + jenkins_user
                  echo 'Using Jenkins userid = ' + jenkins_uid
                  echo 'Using Jenkins group = ' + jenkins_group
                  echo 'Using Jenkins groupid = ' + jenkins_gid
              }
         }
         stage('Cleanup') {
              steps {
                  echo 'Cleaning up the workspace'
                  deleteDir()
              }
         }
        stage('Checkout') {
            steps {
                echo 'Checking out code'
                checkout scm
            }
        }
        stage('Run Selenium tests'){
            steps {
                 sh "mvn -f integration-tests/hopweb/pom.xml clean test"
                }
            post {
                always {
                    archiveArtifacts(artifacts: 'integration-tests/hopweb/**/*.png', allowEmptyArchive: true)
                    junit(testResults: 'integration-tests/**/surefire-reports/*.xml', allowEmptyResults: true)
                }
            }
        }

    }
    post {
        always {
            cleanWs()
            emailext(
                subject: '${DEFAULT_SUBJECT}',
                body: '${DEFAULT_CONTENT}',
                recipientProviders: [[$class: 'CulpritsRecipientProvider']]
            )
        }
    }
}
