pipeline {
    agent any
    parameters {
        string(
            name: 'GIT_COMMIT',
            defaultValue: 'master',
            description: 'Git commit')
        booleanParam(
            name: 'SKIP_BUILD',
            defaultValue: false,
            description: 'Set to true to skip build' )
    }
    environment {
        shared = null
        config = null
    }
    stages {
        stage('Initialize') {
            steps {
                script {
                    checkout([
                        $class: 'GitSCM',
                        branches: [[name: params.GIT_COMMIT]],
                        doGenerateSubmoduleConfigurations: false,
                        extensions: [],
                        submoduleCfg: [],
                        userRemoteConfigs: [[
                            credentialsId: '577cbc72-7d9e-4eba-924c-ecbbe6de9805',
                            url: 'git@github.com:theorchard/orchardgo.git'
                        ]]
                    ])
                    shared = load './jenkins/shared.groovy'
                    config = load './jenkins/config.groovy'
                    library identifier: shared.library(), changelog: false
                    shared.initGitSha(params.GIT_COMMIT)
                    shared.notifySlackStarted()
                }
            }
        }
        stage('Unit tests') {
            steps {
                script {
                    shared.runJobWithRetry(shared.jobUnitTests(), [shared.gitCommit()])
                }
            }
        }
        stage('JS bundle QA') {
            steps {
                script {
                    shared.runJob(shared.jobBundleQA(), [shared.gitCommit()])
                }
            }
        }
        stage('Build and test') {
            parallel {
                stage('Orchard Android') {
                    stages {
                        stage('Orchard Android app') {
                            when {
                                allOf {
                                    expression { return config.e2e.orchard }
                                    expression { return !params.SKIP_BUILD }
                                }
                            }
                            steps {
                                script {
                                    shared.runJobWithRetry(shared.jobBinary(), [
                                        shared.gitCommit(),
                                        hostAndroid(),
                                        shared.platformAndroid(),
                                        shared.brandOrchard(),
                                        shared.environmentQa(),
                                        shared.storeS3(),
                                        shared.androidBinaryTypeApk(),
                                        awsBinariesNamePrefix()
                                    ])
                                }
                            }
                        }
                        stage('Orchard Android e2e') {
                            when {
                                expression { return config.e2e.orchard }
                            }
                            steps {
                                script {
                                    shared.runJob(shared.jobE2E(), [
                                        shared.e2eBrandOrchard(),
                                        shared.e2eOsAndroid(),
                                        shared.e2eOsAndroidVer(),
                                        shared.e2eDeviceAndroid(),
                                        e2ePrefix()
                                    ])
                                }
                            }
                        }
                    }
                }
                stage('Awal Android') {
                    stages {
                        stage('Awal Android app') {
                            when {
                                allOf {
                                    expression { return config.e2e.awal }
                                    expression { return !params.SKIP_BUILD }
                                }
                            }
                            steps {
                                script {
                                    shared.runJobWithRetry(shared.jobBinary(), [
                                        shared.gitCommit(),
                                        hostAndroid(),
                                        shared.platformAndroid(),
                                        shared.brandAwal(),
                                        shared.environmentQa(),
                                        shared.storeS3(),
                                        shared.androidBinaryTypeApk(),
                                        awsBinariesNamePrefix()
                                    ])
                                }
                            }
                        }
                        stage('Awal Android e2e') {
                            when {
                                expression { return config.e2e.awal }
                            }
                            steps {
                                script {
                                    shared.runJob(shared.jobE2E(), [
                                        shared.e2eBrandAwal(),
                                        shared.e2eOsAndroid(),
                                        shared.e2eOsAndroidVer(),
                                        shared.e2eDeviceAndroid(),
                                        e2ePrefix()
                                    ])
                                }
                            }
                        }
                    }
                }
                stage('Sme Android') {
                    stages {
                        stage('Sme Android app') {
                            when {
                                allOf {
                                    expression { return config.e2e.sme }
                                    expression { return !params.SKIP_BUILD }
                                }
                            }
                            steps {
                                script {
                                    shared.runJobWithRetry(shared.jobBinary(), [
                                        shared.gitCommit(),
                                        hostAndroid(),
                                        shared.platformAndroid(),
                                        shared.brandSme(),
                                        shared.environmentQa(),
                                        shared.storeS3(),
                                        shared.androidBinaryTypeApk(),
                                        awsBinariesNamePrefix()
                                    ])
                                }
                            }
                        }
                        stage('Sme Android e2e') {
                            when {
                                expression { return config.e2e.sme }
                            }
                            steps {
                                script {
                                    shared.runJob(shared.jobE2E(), [
                                        shared.e2eBrandSme(),
                                        shared.e2eOsAndroid(),
                                        shared.e2eOsAndroidVer(),
                                        shared.e2eDeviceAndroid(),
                                        e2ePrefix()
                                    ])
                                }
                            }
                        }
                    }
                }
                stage('Orchard iOS') {
                    stages {
                        stage('Orchard iOS app') {
                            when {
                                allOf {
                                    expression { return config.e2e.orchard }
                                    expression { return !params.SKIP_BUILD }
                                }
                            }
                            steps {
                                script {
                                    shared.runJobWithRetry(shared.jobBinary(), [
                                        shared.gitCommit(),
                                        hostIos(),
                                        shared.platformIos(),
                                        shared.brandOrchard(),
                                        shared.environmentQa(),
                                        shared.storeS3(),
                                        shared.androidBinaryTypeApk(),
                                        awsBinariesNamePrefix()
                                    ])
                                }
                            }
                        }
                        stage('Orchard iOS e2e') {
                            when {
                                expression { return config.e2e.orchard }
                            }
                            steps {
                                script {
                                    shared.runJob(shared.jobE2E(), [
                                        shared.e2eBrandOrchard(),
                                        shared.e2eOsIos(),
                                        shared.e2eOsIosVer(),
                                        shared.e2eDeviceIos(),
                                        e2ePrefix()
                                    ])
                                }
                            }
                        }
                    }
                }
                stage('Awal iOS') {
                    stages {
                        stage('Awal iOS app') {
                            when {
                                allOf {
                                    expression { return config.e2e.awal }
                                    expression { return !params.SKIP_BUILD }
                                }
                            }
                            steps {
                                script {
                                    shared.runJobWithRetry(shared.jobBinary(), [
                                        shared.gitCommit(),
                                        hostIos(),
                                        shared.platformIos(),
                                        shared.brandAwal(),
                                        shared.environmentQa(),
                                        shared.storeS3(),
                                        shared.androidBinaryTypeApk(),
                                        awsBinariesNamePrefix()
                                    ])
                                }
                            }
                        }
                        stage('Awal iOS e2e') {
                            when {
                                expression { return config.e2e.awal }
                            }
                            steps {
                                script {
                                    shared.runJob(shared.jobE2E(), [
                                        shared.e2eBrandAwal(),
                                        shared.e2eOsIos(),
                                        shared.e2eOsIosVer(),
                                        shared.e2eDeviceIos(),
                                        e2ePrefix()
                                    ])
                                }
                            }
                        }
                    }
                }
                stage('Sme iOS') {
                    stages {
                        stage('Sme iOS app') {
                            when {
                                allOf {
                                    expression { return config.e2e.sme }
                                    expression { return !params.SKIP_BUILD }
                                }
                            }
                            steps {
                                script {
                                    shared.runJobWithRetry(shared.jobBinary(), [
                                        shared.gitCommit(),
                                        hostIos(),
                                        shared.platformIos(),
                                        shared.brandSme(),
                                        shared.environmentQa(),
                                        shared.storeS3(),
                                        shared.androidBinaryTypeApk(),
                                        awsBinariesNamePrefix()
                                    ])
                                }
                            }
                        }
                        stage('Sme iOS e2e') {
                            when {
                                expression { return config.e2e.sme }
                            }
                            steps {
                                script {
                                    shared.runJob(shared.jobE2E(), [
                                        shared.e2eBrandSme(),
                                        shared.e2eOsIos(),
                                        shared.e2eOsIosVer(),
                                        shared.e2eDeviceIos(),
                                        e2ePrefix()
                                    ])
                                }
                            }
                        }
                    }
                }
            }
        }
        stage('JS bundle Prod') {
            when {
                expression { return config.prodCodePushEnabled }
            }
            steps {
                script {
                    shared.runJob(shared.jobBundleProd(), [shared.gitCommit()])
                }
            }
        }
    }
    post {
        always {
            script {
                if (currentBuild.result == null) {
                    currentBuild.result = 'ABORTED'
                }
            }
        }
        success {
            script {
                shared.notifySlackFinished()
            }
        }
        failure {
            script {
                currentBuild.result = 'FAILURE'
                shared.notifySlackFinished(true)
            }
        }
        aborted {
            script {
                shared.notifySlackFinished(true)
            }
        }
        fixed {
            script {
                shared.notifySlackFinished(true)
            }
        }
    }
}

def awsBinariesNamePrefix() {
    return shared.awsBinariesNamePrefix(binariesPrefix())
}

def e2ePrefix() {
    return shared.e2ePrefix(binariesPrefix())
}

def binariesPrefix() {
    return config.mobilePipeline.binariesPrefix
}

def hostAndroid() {
    return shared.host(config.host.android)
}

def hostIos() {
    return shared.host(config.host.ios)
}
