// Pipeline script for: https://scheduler.theorchard.io/job/ows-text-campaigns-scheduler/

import java.time.LocalDate
import java.time.DayOfWeek

String GITHUB_REPOSITORY = 'ows-text-campaigns'
List<String> AWS_REGIONS = ['us-east-1']
String SLACK_ALERTS_CHANNEL = '#fansifter-alerts'
String SLACK_BUILDS_CHANNEL = '#fansifter-builds'
String QA_ACCOUNT_ID = '285943604611'
String QA_DEPLOYMENT_ROLE = 'qa-ows-text-campaigns-scheduler-role'
String QA_SESSION_NAME = 'qa-ows-text-campaigns-scheduler-session'
String PROD_ACCOUNT_ID = '737325105821'
String PROD_DEPLOYMENT_ROLE = 'prod-ows-text-campaigns-scheduler-role'
String PROD_SESSION_NAME = 'prod-ows-text-campaigns-scheduler-session'


def cronSchedule = 'H 0 * * *'

def isCronTrigger() {
    try {
        def buildCauses = currentBuild.getBuildCauses()
        for (buildCause in buildCauses) {
            if (buildCause != null) {
                if (buildCause.shortDescription.contains("Started by timer")) {
                    return true
                }
            }
        }
        return false
    } catch(theError) {
        echo "ERROR: Exception in isCronTrigger(): ${theError}"
        return false
    }
}

def syncTwilioPricing(Map args = [:]) {
    def awsRole = args.awsRole
    def awsAccountId = args.awsAccountId
    def environment = args.environment

    withSecrets(awsAccountId: awsAccountId, awsRole: awsRole, secrets: [
        [
            id: "${environment}/lambda-audience-refresh-m2m-token/m2m_token",
            environmentVariable: 'AUTH_TOKEN',
        ],
    ]) {
        def url = "https://${environment}-ows-text-campaigns.theorchard.io/twilio/sync-pricing"
        def response = sh(
            returnStdout: true,
            script: """
                curl -s -w "\\n%{http_code}" \\
                  -X POST \\
                  -H "Authorization: Bearer \$AUTH_TOKEN" \\
                  "${url}"
            """
        ).trim()

        def lines = response.readLines()
        if (lines.isEmpty()) {
            error "Could not parse curl output because it was empty."
        }
        def statusCode = lines.last().toInteger()

        if (lines.size() < 2) {
            responseBody = "" // Manually handle small lists
        } else {
            responseBody = lines[0..-2].join('\n')
        }

        if (statusCode != 204) {
            error "Failed to get response from ${url}. Status: ${statusCode} Response: ${responseBody}"
        } else {
            echo "Successfully fetched data from ${url}: ${responseBody}"
        }
    }
}

pipeline {
    agent any

    triggers {
        cron(cronSchedule)
    }

    options {
        ansiColor('xterm')
        disableConcurrentBuilds()
        timestamps()
    }

    parameters {
        booleanParam(name: 'SYNC_TWILIO_ON_QA', defaultValue: true, description: 'Whether or not to sync Twilio on qa.')
        booleanParam(name: 'SYNC_TWILIO_ON_PROD', defaultValue: false, description: 'Whether or not to sync Twilio on prod.')
        booleanParam(name: 'SIMULATE_CRON_TRIGGER', defaultValue: false, description: 'Simulate cron trigger for testing.')
        string(name: 'SHARED_LIBRARIES_VERSION', defaultValue: 'master', description: 'The version of the Jenkins shared libraries to use. Can be a branch, tag or Git revision.')
    }

    stages {
        stage('Load Shared Libraries') {
            steps {
                library "jenkins-global-libraries@${params.SHARED_LIBRARIES_VERSION}"
            }
        }

        stage('Sync Twilio Pricing QA') {
            when {
                allOf {
                    expression { return params.SYNC_TWILIO_ON_QA || isCronTrigger() }
                }
            }
            steps {
                script {
                    syncTwilioPricing(
                        awsRole: QA_DEPLOYMENT_ROLE,
                        awsAccountId: QA_ACCOUNT_ID,
                        environment: 'qa',
                    )
                }
            }
        }

        stage('Sync Twilio Pricing PROD') {
            when {
                allOf {
                    expression {
                        echo "DEBUG: currentBuild.result = '${currentBuild.result}'"
                        echo "DEBUG: SYNC_TWILIO_ON_PROD = '${params.SYNC_TWILIO_ON_PROD}'"
                        echo "DEBUG: isCronTrigger() = '${isCronTrigger()}'"
                        return params.SYNC_TWILIO_ON_PROD ||
                               ((currentBuild.result == null || currentBuild.result == 'SUCCESS') && isCronTrigger())
                    }
                }
            }
            steps {
                script {
                    try {
                        syncTwilioPricing(
                            awsRole: PROD_DEPLOYMENT_ROLE,
                            awsAccountId: PROD_ACCOUNT_ID,
                            environment: 'prod',
                        )
                    } catch (Exception e) {
                        echo "STAGE ERROR: Sync Twilio pricing PROD failed"
                        echo "Stage error details: ${e.getMessage()}"
                        currentBuild.result = 'FAILURE'
                        throw e
                    }
                }
            }
        }
    }

    post {
        always {
            script {
                slackNotify channel: SLACK_BUILDS_CHANNEL
            }
        }
        failure {
            script {
                slackNotify channel: SLACK_ALERTS_CHANNEL
            }
        }
        fixed {
            script {
                slackNotify channel: SLACK_ALERTS_CHANNEL
            }
        }
        cleanup {
            cleanWs()
        }
    }
}
