@Library('corda-shared-build-pipeline-steps@5.2') _

import groovy.transform.Field
import com.r3.build.utils.PipelineUtils
import com.r3.build.utils.GitUtils

@Field
String postgresHost = 'localhost'
@Field
String postgresPort = '5432'
@Field
String postgresCredentialsId = 'e2e-postgresql-credentials'
@Field
String postgresDb = "test_${UUID.randomUUID().toString().replace("-", "")}"

@Field
PipelineUtils pipelineUtils = new PipelineUtils(this)

@Field
GitUtils gitUtils = new GitUtils(this)

@Field
String agentLabel = 'docker-private-network'

if (env.CHANGE_ID || gitUtils.isReleaseTag()) {
    agentLabel = 'docker-on-demand-private-network'
}

pipeline {
    agent {
        docker {
            image 'build-zulu-openjdk:17'
            label "${agentLabel}"
            registryUrl 'https://engineering-docker.software.r3.com/'
            registryCredentialsId 'artifactory-credentials'
            args '-v /tmp:/host_tmp '
            alwaysPull true
        }
    }

    environment {
        ARTIFACTORY_CREDENTIALS = credentials('artifactory-credentials')
        BUILD_CACHE_CREDENTIALS = credentials('gradle-ent-cache-credentials')
        POSTGRES_CREDENTIALS = credentials('e2e-postgresql-credentials')
        BUILD_CACHE_USERNAME = "${env.BUILD_CACHE_CREDENTIALS_USR}"
        BUILD_CACHE_PASSWORD = "${env.BUILD_CACHE_CREDENTIALS_PSW}"
        CORDA_ARTIFACTORY_USERNAME = "${env.ARTIFACTORY_CREDENTIALS_USR}"
        CORDA_ARTIFACTORY_PASSWORD = "${env.ARTIFACTORY_CREDENTIALS_PSW}"
        CORDA_DEV_POSTGRES_USER="${env.POSTGRES_CREDENTIALS_USR}"
        CORDA_DEV_POSTGRES_PASSWORD="${env.POSTGRES_CREDENTIALS_PSW}"
        CORDA_DEV_CLUSTER_DB_NAME="${postgresDb}"
        CORDA_USE_CACHE = "corda-remotes"
        KUBECONFIG = credentials("kubernetes-eks-e2e-01-credentials")
        CORDA_CLI_USER_HOME = "/tmp/corda-cli-home"
        CORDA_GRADLE_SCAN_KEY = credentials('gradle-build-scans-key')
        GRADLE_USER_HOME = "/host_tmp/gradle"
        CORDA_REVISION = "${env.GIT_COMMIT}"
        GRADLE_PERFORMANCE_TUNING = "--max-workers=4 --parallel -Dscan.tag.combined-worker --build-cache -Si"
    }

    parameters {
        string(name: 'COMMIT_TO_CHECKOUT', defaultValue: '', description: 'Commit ID to check out of SCM - leave blank to take head of current branch')
    }

    options {
        buildDiscarder(logRotator(daysToKeepStr: '30', artifactDaysToKeepStr: '30'))
        timestamps()
    }

    stages {
        stage('check out') {
            steps {
                script {
                    gitUtils.checkoutGitRevisionOfTriggeringJob(params.COMMIT_TO_CHECKOUT)
                }
            }
        }
        stage('create DBs') {
            environment {
                KUBECONFIG = credentials('kubernetes-eks-e2e-01-credentials')
            }
            steps {
                script {
                    pipelineUtils.createPostgresDatabase(postgresPort, postgresHost, postgresDb, postgresCredentialsId)
                }
            }
        }
        stage('build') {
            steps {
                gradlew (':applications:workers:release:combined-worker:assemble')
            }
        } 			
        stage('start combined worker') {       
            environment {
                JAR_PATH = "${env.WORKSPACE}/applications/workers/release/combined-worker/build/bin/corda-combined-worker-*.jar"
                JDBC_PATH = "${env.WORKSPACE}/applications/workers/release/combined-worker/drivers"
                REST_TLS_PATH = "${env.WORKSPACE}/applications/workers/release/combined-worker/tls/rest/rest_worker.pfx"
                VM_PARAMETERS = "-Dco.paralleluniverse.fibers.verifyInstrumentation=true -Dnet.corda.flow.fiber.cache.maximumSize=1"
                LOG4J_PARAMETERS = "-Dlog4j.configurationFile=log4j2-console.xml"
                PROGRAM_PARAMETERS = "--instance-id=0 -mbus.busType=DATABASE -spassphrase=password -ssalt=salt -ddatabase.user=u${postgresDb} -ddatabase.pass=password -ddatabase.jdbc.url=jdbc:postgresql://${postgresHost}:${postgresPort}/${postgresDb} -ddatabase.jdbc.directory=${JDBC_PATH} -rtls.keystore.path=${REST_TLS_PATH} -rtls.keystore.password=mySecretPassword"
                WORKING_DIRECTORY = "${env.WORKSPACE}"
            }
            steps {
                sh '''
                    nohup java ${LOG4J_PARAMETERS} -jar ${VM_PARAMETERS} ${JAR_PATH} ${PROGRAM_PARAMETERS} 2<&1 > workerLogs.txt &
                    export PROCNO=$!
                '''        
            }            
        }
        stage('connect to combined worker') {
            steps {
                script {
                    pipelineUtils.waitForServiceToBeUp('http://localhost:7004/status', 20, 3)
                }
            }
        }
        stage('smoketests') {
                options {
                    timeout(time: 30, unit: 'MINUTES')
                }
                steps {
                   gradlew('smoketest -PisCombinedWorker=true')
                }
                post {
                    always {
                        junit allowEmptyResults: true, testResults: '**/test-results/**/TEST-*.xml'
                    }
                }
        }
    }
    post {
        always {
            script {      
                    findBuildScans()
                    pipelineUtils.getPodLogs("postgres")
                    pipelineUtils.dropPostgresDB(postgresCredentialsId, env.CORDA_DEV_CLUSTER_DB_NAME)
            }
            archiveArtifacts artifacts: 'forward.txt, workerLogs.txt, podLogs.txt', allowEmptyArchive: true
            sh 'rm -f forward.txt workerLogs.txt podLogs.txt'
        }
        failure {
            sendSlackNotifications("danger", "BUILD FAILURE - Combined Worker E2E Tests", true, "#corda-corda5-build-notifications")
        }
    }
}


def gradleCmd() {
    return isUnix() ? './gradlew' : './gradlew.bat'
}

def gradlew(String... args) {
    def allArgs = args.join(' ')
    sh "${gradleCmd()} ${allArgs} ${GRADLE_PERFORMANCE_TUNING}"
}
