properties = null
def loadProperties() {
    node {
        properties = readProperties file: "${TESTGRID_HOME}/config.properties"
    }
}

def uploadToS3() {
    def bucket= properties['AWS_S3_BUCKET_NAME']
    if ( "${bucket}" == "null") {
        bucket="unknown"
    }
    sh """
      aws s3 sync ${PWD}/builds/ s3://${bucket}/artifacts/jobs/${PRODUCT}/builds --include "*"
      """
}

def runPlan(tPlan, node) {
    echo "Executing Test Plan : ${tPlan} On node : ${node}"

    try {
        echo "Running Test-Plan: ${tPlan}"
        sh "java -version"
        unstash name: "${JOB_CONFIG_YAML}"
        dir("${PWD}") {
            unstash name: "test-plans"
        }
        sh """
            pwd
            cd /testgrid/testgrid-home/jobs/${PRODUCT}/${SCENARIOS_LOCATION}
            git clean -fd
            cd ${TESTGRID_HOME}/testgrid-dist/${TESTGRID_NAME}
            ./testgrid run-testplan --product ${PRODUCT} \
             --file "/testgrid/testgrid-home/jobs/${PRODUCT}/${tPlan}"
            """
    } catch (Exception err) {
        echo "Error : ${err}"
        currentBuild.result = 'UNSTABLE'
    }
    echo "RESULT: ${currentBuild.result}"

    script {
        loadProperties()
        uploadToS3()
    }
}


def getParameters(file){
    def tpyaml = readFile(file)
    def m = tpyaml =~ /(parameters:)([A-z \n:'0-9\.-]*)(provisioners)/
    // echo tpyaml
    def params = m[0][2].trim().split('\n')
    // echo Long.toString(params.size())
    def name=""
    params = params.sort()
    for (String s: params) {
        name += s.split(":")[1]
    }
    echo "This is the name" + name
    return name
}

pipeline {
    agent {
        node {
            label ""
            customWorkspace "/testgrid/testgrid-home/jobs/${JOB_BASE_NAME}"
        }
    }

    environment {
        TESTGRID_NAME = 'WSO2-TestGrid'
        TESTGRID_DIST_LOCATION = '/testgrid/testgrid-home/testgrid-dist/'
        TESTGRID_HOME='/testgrid/testgrid-home/'

        PRODUCT = "${JOB_BASE_NAME}"
        TESTGRID_REPOSITORY='https://github.com/wso2/testgrid'
        INFRASTRUCTURE_REPOSITORY='https://github.com/ballerina-platform/ballerina-message-broker'
        DEPLOYMENT_REPOSITORY='https://github.com/ballerina-platform/ballerina-message-broker'
        SCENARIOS_REPOSITORY='https://github.com/ballerina-platform/ballerina-message-broker'

        TESTGRID_LOCATION="workspace/testgrid"
        INFRA_LOCATION="workspace/ballerina-message-broker"
        DEPLOYMENT_LOCATION="workspace/ballerina-message-broker"
        SCENARIOS_LOCATION="workspace/ballerina-message-broker"
        TESTGRID_YAML_LOCATION="${INFRA_LOCATION}/jobs/${PRODUCT}/testgrid.yaml"

        AWS_ACCESS_KEY_ID=credentials('AWS_ACCESS_KEY_ID')
        AWS_SECRET_ACCESS_KEY=credentials('AWS_SECRET_ACCESS_KEY')
        tomcatUsername=credentials('TOMCAT_USERNAME')
        tomcatPassword=credentials('TOMCAT_PASSWORD')
        PWD=pwd()
        JOB_CONFIG_YAML = "job-config.yaml"
        JOB_CONFIG_YAML_PATH = "${PWD}/${JOB_CONFIG_YAML}"

        PRODUCT_GIT_URL="${PRODUCT_GIT_URL}"
        PRODUCT_GIT_BRANCH="${PRODUCT_GIT_BRANCH}"
        PRODUCT_DIST_DOWNLOAD_API="${PRODUCT_DIST_DOWNLOAD_API}"
    }

    tools {
        jdk 'jdk8-slave1'
    }

    stages {
        stage('Preparation') {
            steps {
                echo pwd()
                deleteDir()

                //Clone testgrid repo
                sh "mkdir -p ${TESTGRID_LOCATION}"
                dir("${TESTGRID_LOCATION}"){
                    git branch: 'master', url: "${TESTGRID_REPOSITORY}"
                }

                // Clone infra repo
                sh "mkdir -p ${INFRA_LOCATION}"
                dir("${INFRA_LOCATION}"){
                    git branch: 'master', url:"${INFRASTRUCTURE_REPOSITORY}"
                }
                writeFile file: "${INFRA_LOCATION}/deploy.sh", text: '#!/bin/sh'

                sh """
                    echo ${TESTGRID_NAME}
                    cd ${TESTGRID_DIST_LOCATION}
                    cd ${TESTGRID_NAME}

                    sed -i 's/-Xms256m -Xmx1024m/-Xmx2G -Xms2G/g' testgrid
                    """

                // Get testgrid.yaml from jenkins managed files
                configFileProvider(
                        [configFile(fileId: "${PRODUCT}-testgrid-yaml", targetLocation:
                                "${TESTGRID_YAML_LOCATION}")]) {
                }

                configFileProvider([configFile(fileId: '3a63892b-06b8-483a-8a0d-74dffaf69c3d', targetLocation: 'workspace/testgrid-key.pem', variable: 'TESTGRIDKEY')]) {
                    sh """
                        echo 'keyFileLocation: workspace/testgrid-key.pem' > ${JOB_CONFIG_YAML_PATH}
                        chmod 400 workspace/testgrid-key.pem
                        """
                }

                sh """
                    echo 'jobName: ${PRODUCT}' >> ${JOB_CONFIG_YAML_PATH}
                    echo 'infrastructureRepository: ${INFRA_LOCATION}/' >> ${JOB_CONFIG_YAML_PATH}
                    echo 'deploymentRepository: ${INFRA_LOCATION}/' >> ${JOB_CONFIG_YAML_PATH}
                    echo 'scenarioTestsRepository: ${SCENARIOS_LOCATION}' >> ${JOB_CONFIG_YAML_PATH}
                    echo 'testgridYamlLocation: ${TESTGRID_YAML_LOCATION}' >> ${JOB_CONFIG_YAML_PATH}
                    echo 'properties:' >> ${JOB_CONFIG_YAML_PATH}
                    echo '  PRODUCT_GIT_URL: ${PRODUCT_GIT_URL}' >> ${JOB_CONFIG_YAML_PATH}
                    echo '  PRODUCT_GIT_BRANCH: ${PRODUCT_GIT_BRANCH}' >> ${JOB_CONFIG_YAML_PATH}
                    echo '  PRODUCT_DIST_DOWNLOAD_API: ${PRODUCT_DIST_DOWNLOAD_API}' >> ${JOB_CONFIG_YAML_PATH}
                    echo '  SQL_DRIVERS_LOCATION_UNIX: ${SQL_DRIVERS_LOCATION_UNIX}' >> ${JOB_CONFIG_YAML_PATH}
                    echo '  SSH_KEY_LOCATION: ${PWD}/workspace/testgrid-key.pem' >> ${JOB_CONFIG_YAML_PATH}
                    echo '  REMOTE_WORKSPACE_DIR_UNIX: ${REMOTE_WORKSPACE_DIR_UNIX}' >> ${JOB_CONFIG_YAML_PATH}
                    echo '  REMOTE_WORKSPACE_DIR_WINDOWS: ${REMOTE_WORKSPACE_DIR_WINDOWS}' >> ${JOB_CONFIG_YAML_PATH}

                    echo The job-config.yaml:
                    cat ${JOB_CONFIG_YAML_PATH}
                    """

                stash name: "${JOB_CONFIG_YAML}", includes : "${JOB_CONFIG_YAML}"

                sh """
                    cd ${TESTGRID_HOME}/testgrid-dist/${TESTGRID_NAME}
                    ./testgrid generate-test-plan \
                        --product ${PRODUCT} \
                        --file ${JOB_CONFIG_YAML_PATH}
                    """
                dir("${PWD}"){
                    stash name: "test-plans", includes : "test-plans/**"
                }
            }
        }

        stage('parallel-run') {
            steps {
                script {
                    def parallelExecCount = 12
                    def tests = [:]
                    def files = findFiles(glob: '**/test-plans/*.yaml')
                    for (int f = 1; f < parallelExecCount+1 && f <= files.length; f++) {
                        def executor = f
                        def name = getParameters('/testgrid/testgrid-home/jobs/wso2am-intg/test-plans/'+files[f-1].name)
                        echo name
                        tests["${name}"] = {
                            node {
                                stage("Parallel Executor : ${executor}") {
                                    script {
                                        int processFileCount = 0;
                                        if (files.length < parallelExecCount) {
                                            processFileCount = 1;
                                        } else {
                                            processFileCount = files.length/parallelExecCount;
                                        }
                                        if (executor == parallelExecCount) {
                                            for (int i = processFileCount * (executor - 1); i < files.length; i++) {
                                                // Execution logic
                                                // runPlan(files[i], "node1")
                                            }
                                        } else {
                                            for (int i = 0; i <  processFileCount; i++) {
                                                int fileNo = processFileCount * (executor - 1) + i
                                                runPlan(files[fileNo], "node1")
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                    parallel tests
                }
            }
        }
    }

    post {
        always {
            sh """
            cd ${TESTGRID_HOME}/testgrid-dist/${TESTGRID_NAME}
            ./testgrid finalize-run-testplan \
            --product ${PRODUCT} --workspace ${PWD}
            """

            sh """
             cd ${TESTGRID_HOME}/testgrid-dist/${TESTGRID_NAME}
            ./testgrid generate-report \
            --product ${PRODUCT} \
            --groupBy scenario
            """
            // Generate email-able report
            /* Prereq:
               1. Needs TestSuit.txt and output.properties files in relevant scenario directory.
               2. DB needs to be updated on integration test result statues.
            */
            sh """
                cd ${TESTGRID_HOME}/testgrid-dist/${TESTGRID_NAME}
                ./testgrid generate-email \
                --product ${PRODUCT} \
                --workspace ${PWD}
                """
            script {
                sh """
                   echo "/testgrid/testgrid-home/jobs/${PRODUCT}"
                   ls -al /testgrid/testgrid-home/jobs/${PRODUCT}
                   """
                //Send email for failed results.
                if (fileExists("/testgrid/testgrid-home/jobs/${PRODUCT}/builds/EmailReport.html")) {
                    def emailBody = readFile '/testgrid/testgrid-home/jobs/wso2am-intg/builds/EmailReport.html'
                    mail (to: 'kasung@wso2.com, pasinduj@wso2.com, yasassri@wso2.com, lasanthad@wso2.com, sameeraw@wso2.com, asmaj@wso2.com, harshan@wso2.com',
                            subject: "'${env.JOB_NAME}' Integration Test Failure! #(${env.BUILD_NUMBER})",
                            body: "${emailBody}", mimeType: 'text/html'
                    );
                } else {
                    echo "No EmailReport.html file found!!"
                }
            }
            // Delete logs and reports after upload
            dir("${TESTGRID_HOME}/jobs/${PRODUCT}") {
                sh """
                find . -maxdepth 1 -type f \\( -name "*.log" -o -name "*.html" \\) -delete
                """
            }
        }
    }
}
