// git

def initGitSha(gitCommit) {
    sh "echo initGitSha"

    def trimmedGitCommit = gitCommit.trim()
    def isSHA1 = trimmedGitCommit ==~ /^[0-9a-f]{40}$/
    env.GIT_SHA = isSHA1
        ? trimmedGitCommit
        : sh(script: "git rev-parse origin/${trimmedGitCommit}", returnStdout: true).trim()

    env.SLACK_MESSAGE_BUILD_INFO = slackMessageBuildInfo()

    sh "echo env.GIT_SHA: $GIT_SHA"
    sh "echo env.SLACK_MESSAGE_BUILD_INFO: $SLACK_MESSAGE_BUILD_INFO"
}

def initDryRun(dryRun) {
    if (dryRun) {
        sh "echo DRY_RUN is true. Jobs will not be executed, only echoed."
    }
    env.DRY_RUN = dryRun.toString()
}

// jobs

def jobBinary() {
    return "mobile-binary"
}

def jobE2E() {
    return "mobile-e2e-tests"
}

def jobUnitTests() {
    return "mobile-unit-lint"
}

def jobBundleQA() {
    return "mobile-js-bundle-deploy-qa"
}

def jobBundleProd() {
    return "mobile-js-bundle-promote"
}

// run

def trackStage(stageName) {
    def stages = env.COMPLETED_STAGES ?: ''
    env.COMPLETED_STAGES = stages ? "${stages}, ${stageName}" : stageName
}

def runJob(name, params) {
    if (env.DRY_RUN == 'true') {
        echo "[DRY_RUN] Would run job: ${name} with params: ${params}"
        trackStage(env.STAGE_NAME)
        return
    }
    build job: name, parameters: params
    trackStage(env.STAGE_NAME)
}

def runJobWithRetry(name, params) {
    if (env.DRY_RUN == 'true') {
        echo "[DRY_RUN] Would run job (with retry): ${name} with params: ${params}"
        trackStage(env.STAGE_NAME)
        return
    }
    try {
        build job: name, parameters: params
    } catch (e1) {
        println("error. retry...")
        try {
            build job: name, parameters: params
        } catch (e2) {
            println("error. retry...")
            build job: name, parameters: params
        }
    }
    trackStage(env.STAGE_NAME)
}

// parameters

def gitCommit() {
    return string(name: 'GIT_COMMIT', value: env.GIT_SHA)
}

def host(value) {
    return string(name: 'HOST', value: value)
}

def platformAndroid() {
    return string(name: 'PLATFORM', value: "android")
}

def platformIos() {
    return string(name: 'PLATFORM', value: "ios")
}

def platformIosSimulator() {
    return string(name: 'PLATFORM', value: "iosSimulator")
}

def brandOrchard() {
    return string(name: 'BRAND', value: "orchard")
}

def brandAwal() {
    return string(name: 'BRAND', value: "awal")
}

def brandSme() {
    return string(name: 'BRAND', value: "sme")
}

def brand(value) {
    return string(name: 'BRAND', value: value)
}

def environmentProd() {
    return string(name: 'ENVIRONMENT', value: "prod")
}

def environmentQa() {
    return string(name: 'ENVIRONMENT', value: "qa")
}

def environmentDev() {
    return string(name: 'ENVIRONMENT', value: "dev")
}

def internalTesting(boolean value) {
    return booleanParam(name: 'INTERNAL_TESTING', value: value)
}

def prodCodePushDisabled() {
    return string(name: 'PROD_CODE_PUSH_ENABLED', value: "false")
}

def storeStore() {
    return string(name: 'STORE', value: "store")
}

def storeS3() {
    return string(name: 'STORE', value: "s3")
}

def androidBinaryTypeApk() {
    return string(name: 'ANDROID_BINARY_TYPE', value: "apk")
}

def androidBinaryTypeAab() {
    return string(name: 'ANDROID_BINARY_TYPE', value: "aab")
}

def awsBinariesNamePrefix(value) {
    return string(name: 'AWS_BINARIES_NAME_PREFIX', value: value)
}

def e2eOsIos() {
    return string(name: 'OS', value: "ios")
}

def e2eOsIosVer() {
    return string(name: 'OS_VERSION', value: "26")
}

def e2eDeviceIos() {
    return string(name: 'APPIUM_DEVICE', value: "iPhone 17")
}

def e2eOsAndroid() {
    return string(name: 'OS', value: "android")
}

def e2eOsAndroidVer() {
    return string(name: 'OS_VERSION', value: "16.0")
}

def e2eDeviceAndroid() {
    return string(name: 'APPIUM_DEVICE', value: "Google Pixel 10")
}

def e2eBrandOrchard() {
    return string(name: 'BRAND', value: "orchard")
}

def e2eBrandAwal() {
    return string(name: 'BRAND', value: "awal")
}

def e2eBrandSme() {
    return string(name: 'BRAND', value: "sme")
}

def e2ePrefix(value) {
    return string(name: 'PREFIX', value: value)
}

// slack

def library() {
    return "jenkins-global-libraries@master"
}

def notifySlackStarted() {
    slackNotify channel: slackChannelVerbose(),
                message: slackMessageStart(),
                color: slackColorStart()
}

def notifySlackFinished(boolean critical = false) {
    slackNotify channel: slackChannelVerbose(),
                message: slackMessageFinish()
    if (critical) {
        slackNotify channel: slackChannelCritical(),
                    message: slackMessageFinish()
    }
}

def slackChannelCritical() {
    'mobile-notifications'
}

def slackChannelVerbose() {
    'mobile-notifications-verbose'
}

def slackColorStart() {
    "#0000FF"
}

def slackMessageStart() {
    "${env.SLACK_MESSAGE_BUILD_INFO} STARTED ${slackMessageBuildLink()}"
}

def slackMessageFinish(boolean includeStages = false) {
    def stages = includeStages && env.COMPLETED_STAGES ? "\nStages: ${env.COMPLETED_STAGES}" : ''
    "${env.SLACK_MESSAGE_BUILD_INFO} ${currentBuild.currentResult} ${slackMessageBuildTime()} ${slackMessageBuildLink()}${stages}"
}

def slackMessageBuildInfo() {
    def modePrefix = env.MODE ? "[${env.MODE}] " : ''
    "${modePrefix}${env.JOB_NAME} - #${env.BUILD_NUMBER} ${appVersion()}"
}

def slackMessageBuildTime() {
    "after ${getTimeSpanString(System.currentTimeMillis() - currentBuild.startTimeInMillis)}"
}

def slackMessageBuildLink() {
    "(<${env.BUILD_URL}|Open>)"
}

def getTimeSpanString(long durationMillis) {
    long seconds = durationMillis / 1000
    long minutes = seconds / 60
    long hours = minutes / 60
    long days = hours / 24

    if (days > 0) {
        return "${days} days ${hours % 24} hr ${minutes % 60} min"
    } else if (hours > 0) {
        return "${hours} hr ${minutes % 60} min"
    } else if (minutes > 0) {
        return "${minutes} min ${seconds % 60} sec"
    } else {
        return "${seconds} sec"
    }
}

// version

def appVersion() {
    "${binariesVersion()} (${bundleVersion()})"
}

def binariesVersion() {
    def json = readFile('package.json')
    def parsedJson = new groovy.json.JsonSlurper().parseText(json)
    return parsedJson.version
}

def bundleVersion() {
    sh(script: 'git rev-parse --short=7 HEAD', returnStdout: true).trim()
}

def withCommonCredential(Closure body) {
    withCredentials([
            aws(accessKeyVariable: 'AWS_ACCESS_KEY',
                    secretKeyVariable: 'AWS_SECRET_ACCESS_KEY',
                    credentialsId: 'prod-orcd-mobile-user'),
            file(credentialsId: "${ORCHARD_APP_STORE_CERTIFICATE_FILE}", variable: 'ORCHARD_APP_STORE_CERTIFICATE_FILE_PATH'),
            file(credentialsId: "${ORCHARD_APP_STORE_API_KEY_FILE}", variable: 'ORCHARD_APP_STORE_API_KEY_FILE_PATH'),
            file(credentialsId: "${ORCHARD_PROD_GOOGLE_PLAY_KEYSTORE_FILE}", variable: 'ORCHARD_PROD_GOOGLE_PLAY_KEYSTORE_FILE_PATH'),
            file(credentialsId: "${ORCHARD_QA_GOOGLE_PLAY_KEYSTORE_FILE}", variable: 'ORCHARD_QA_GOOGLE_PLAY_KEYSTORE_FILE_PATH'),
            file(credentialsId: "${ORCHARD_DEV_GOOGLE_PLAY_KEYSTORE_FILE}", variable: 'ORCHARD_DEV_GOOGLE_PLAY_KEYSTORE_FILE_PATH'),
            file(credentialsId: "${AWAL_PROD_GOOGLE_PLAY_KEYSTORE_FILE}", variable: 'AWAL_PROD_GOOGLE_PLAY_KEYSTORE_FILE_PATH'),
            file(credentialsId: "${AWAL_QA_GOOGLE_PLAY_KEYSTORE_FILE}", variable: 'AWAL_QA_GOOGLE_PLAY_KEYSTORE_FILE_PATH'),
            file(credentialsId: "${ORCHARD_PROD_STORE_APP_STORE_PROFILE_FILE}", variable: 'ORCHARD_PROD_STORE_APP_STORE_PROFILE_FILE_PATH'),
            file(credentialsId: "${ORCHARD_QA_STORE_APP_STORE_PROFILE_FILE}", variable: 'ORCHARD_QA_STORE_APP_STORE_PROFILE_FILE_PATH'),
            file(credentialsId: "${ORCHARD_DEV_STORE_APP_STORE_PROFILE_FILE}", variable: 'ORCHARD_DEV_STORE_APP_STORE_PROFILE_FILE_PATH'),
            file(credentialsId: "${ORCHARD_PROD_S3_APP_STORE_PROFILE_FILE}", variable: 'ORCHARD_PROD_S3_APP_STORE_PROFILE_FILE_PATH'),
            file(credentialsId: "${ORCHARD_QA_S3_APP_STORE_PROFILE_FILE}", variable: 'ORCHARD_QA_S3_APP_STORE_PROFILE_FILE_PATH'),
            file(credentialsId: "${ORCHARD_DEV_S3_APP_STORE_PROFILE_FILE}", variable: 'ORCHARD_DEV_S3_APP_STORE_PROFILE_FILE_PATH'),
            file(credentialsId: "${AWAL_PROD_STORE_APP_STORE_PROFILE_FILE}", variable: 'AWAL_PROD_STORE_APP_STORE_PROFILE_FILE_PATH'),
            file(credentialsId: "${AWAL_QA_STORE_APP_STORE_PROFILE_FILE}", variable: 'AWAL_QA_STORE_APP_STORE_PROFILE_FILE_PATH'),
            file(credentialsId: "${AWAL_PROD_S3_APP_STORE_PROFILE_FILE}", variable: 'AWAL_PROD_S3_APP_STORE_PROFILE_FILE_PATH'),
            file(credentialsId: "${AWAL_QA_S3_APP_STORE_PROFILE_FILE}", variable: 'AWAL_QA_S3_APP_STORE_PROFILE_FILE_PATH'),
            file(credentialsId: "${ORCHARD_GOOGLE_PLAY_JSON_FILE}", variable: 'ORCHARD_GOOGLE_PLAY_JSON_FILE_PATH'),
            file(credentialsId: "${AWAL_GOOGLE_PLAY_JSON_FILE}", variable: 'AWAL_GOOGLE_PLAY_JSON_FILE_PATH'),
            file(credentialsId: "${SME_GOOGLE_PLAY_JSON_FILE}", variable: 'SME_GOOGLE_PLAY_JSON_FILE_PATH'),
            file(credentialsId: "${SME_PROD_GOOGLE_PLAY_KEYSTORE_FILE}", variable: 'SME_PROD_GOOGLE_PLAY_KEYSTORE_FILE_PATH'),
            file(credentialsId: "${SME_QA_GOOGLE_PLAY_KEYSTORE_FILE}", variable: 'SME_QA_GOOGLE_PLAY_KEYSTORE_FILE_PATH'),
            file(credentialsId: "${AWAL_APP_STORE_API_KEY_FILE}", variable: 'AWAL_APP_STORE_API_KEY_FILE_PATH'),
            file(credentialsId: "${AWAL_APP_STORE_CERTIFICATE_FILE}", variable: 'AWAL_APP_STORE_CERTIFICATE_FILE_PATH'),
            file(credentialsId: "${AWAL_DEV_STORE_APP_STORE_PROFILE_FILE}", variable: 'AWAL_DEV_STORE_APP_STORE_PROFILE_FILE_PATH'),
            file(credentialsId: "${SME_APP_STORE_API_KEY_FILE}", variable: 'SME_APP_STORE_API_KEY_FILE_PATH'),
            file(credentialsId: "${SME_APP_STORE_CERTIFICATE_FILE}", variable: 'SME_APP_STORE_CERTIFICATE_FILE_PATH'),
            file(credentialsId: "${SME_PROD_STORE_APP_STORE_PROFILE_FILE}", variable: 'SME_PROD_STORE_APP_STORE_PROFILE_FILE_PATH'),
            file(credentialsId: "${SME_PROD_S3_APP_STORE_PROFILE_FILE}", variable: 'SME_PROD_S3_APP_STORE_PROFILE_FILE_PATH'),
            file(credentialsId: "${SME_QA_STORE_APP_STORE_PROFILE_FILE}", variable: 'SME_QA_STORE_APP_STORE_PROFILE_FILE_PATH'),
            file(credentialsId: "${SME_DEV_STORE_APP_STORE_PROFILE_FILE}", variable: 'SME_DEV_STORE_APP_STORE_PROFILE_FILE_PATH'),
            file(credentialsId: "${SME_QA_S3_APP_STORE_PROFILE_FILE}", variable: 'SME_QA_S3_APP_STORE_PROFILE_FILE_PATH'),
    ]) {
        body()
    }
}

return this
