String SLACK_NOTIFICATIONS_CHANNEL = '#neo4j-db'
String REFRESH_ROLE = 'qa-refresh-aura-execution-role'
String QA_ACCOUNT_ID = '437795906767'
String SESSION_NAME = "qa-refresh-aura"
String NEO4J_SRC_CONNECTOR = "qa-kc-neo-cdc-src-nr"

pipeline {
    agent any
    parameters {
        choice(
            choices: ['qa-neighbouring-rights'],
            description: 'Neo4j instance to refresh',
            name: 'NEO4J_HOST_TO_REFRESH')
        choice(
            choices: ['FULL', 'OFF', 'DIFF'],
            description: 'The CDC mode of the instance. Default is FULL.',
            name: 'DESTINATION_CDC_MODE'
        )
        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.'
        )
        string(
            name: 'LOGGER_DSN',
            defaultValue: 'https://qa-fluentd-applications.theorchard.io:8888/application',
            description: 'Datadog logger for standalone apps.'
        )
        string(
            name: 'Environment',
            defaultValue: 'qa',
            description: 'Env for secret manager.'
        )
    }

    triggers {
        // Every day at 4AM GMT time.
        cron('TZ=GMT\n0 4 * * *')
    }

    stages {
        stage('Checkout') {
            steps {
                script {
                    cleanWs()
                    def scmVars = checkout scm
                    // Set SCM vars as environment variables to replicate default checkout functionality
                    scmVars.each { k, v ->
                        env."${k}" = v
                    }
                }
            }
        }
        stage('Load Shared Libraries') {
            steps {
                library "jenkins-global-libraries@${params.SHARED_LIBRARIES_VERSION}"
            }
        }
        stage('Notify Slack') {
            steps {
                slackNotify channel: SLACK_NOTIFICATIONS_CHANNEL,
                    message: "Build started for ${env.JOB_NAME} DB: ${params.NEO4J_HOST_TO_REFRESH}: ${env.BUILD_URL}"
            }
        }
        stage('Pause source connectors') {
            steps {
                withSecrets(awsAccountId: QA_ACCOUNT_ID, awsRole: REFRESH_ROLE, secrets: [
                    // We dont need secrets but it is a required argument to assume this role.
                    [id: 'qa/refresh-aura/SENTRY_DSN', environmentVariable: 'SENTRY_DSN'],
                ]) {
                    echo "Getting desired task Count for ${NEO4J_SRC_CONNECTOR}..."
                    script {
                        env.ORIGINAL_DESIRED_COUNT = sh(
                            script: """
                                aws ecs describe-services \
                                    --cluster "${NEO4J_SRC_CONNECTOR}" \
                                    --services "${NEO4J_SRC_CONNECTOR}" \
                                    --query "services[0].desiredCount"
                            """,
                            returnStdout: true
                        ).trim()
                        echo "Found ${env.ORIGINAL_DESIRED_COUNT} original running instances."
                    }
                    timeout(unit: 'SECONDS', time: 600) {
                        script {
                            if (env.ORIGINAL_DESIRED_COUNT.toInteger() == 0 ) {
                                echo "No instance running, so nothing to pause..."
                                return
                            }
                            echo "Pausing Replication..."
                            sh("""
                                aws ecs update-service \
                                    --cluster "${NEO4J_SRC_CONNECTOR}" \
                                    --service "${NEO4J_SRC_CONNECTOR}" \
                                    --desired-count 0 > /dev/null
                            """)

                            RUNNING_COUNT=env.ORIGINAL_DESIRED_COUNT.toInteger()
                            while (RUNNING_COUNT < 1) {
                                RUNNING_COUNT=sh(
                                    script: """
                                        aws ecs describe-services \
                                            --cluster "${NEO4J_SRC_CONNECTOR}" \
                                            --services "${NEO4J_SRC_CONNECTOR}" \
                                            --query "services[0].runningCount"
                                        """,
                                    returnStdout: true
                                ).trim()
                                echo "Found $RUNNING_COUNT running instances. Waiting for it to be 0."
                                if (RUNNING_COUNT < 1) {
                                    sleep 10
                                }
                            }
                        }
                    }
                }
            }
        }
        stage('Refresh Aura') {
            steps {
                dir("refresh_aura") {
                    withEcr{
                        withSecrets(awsAccountId: QA_ACCOUNT_ID, awsRole: REFRESH_ROLE, secrets: [
                            [id: 'qa/refresh-aura/SENTRY_DSN', environmentVariable: 'SENTRY_DSN'],
                            [id: 'qa/refresh-aura/AURA_API_CLIENT_SECRET', environmentVariable: 'AURA_API_CLIENT_SECRET'],
                            [id: 'qa/refresh-aura/AURA_API_CLIENT_ID', environmentVariable: 'AURA_API_CLIENT_ID'],
                        ]) {
                            sh 'make run_refresh'
                        }
                    }
                }
            }
            post {
                cleanup {
                    dir("refresh_aura") {
                        withEcr{
                            withSecrets(awsAccountId: QA_ACCOUNT_ID, awsRole: REFRESH_ROLE, secrets: [
                                [id: 'qa/refresh-aura/SENTRY_DSN', environmentVariable: 'SENTRY_DSN'],
                                [id: 'qa/refresh-aura/AURA_API_CLIENT_SECRET', environmentVariable: 'AURA_API_CLIENT_SECRET'],
                                [id: 'qa/refresh-aura/AURA_API_CLIENT_ID', environmentVariable: 'AURA_API_CLIENT_ID'],
                            ]) {
                                sh 'make docker_down'
                            }
                        }
                    }
                }
            }
        }
        stage('Post-Refresh Cypher Queries') {
            steps {
                echo "Do nothing"
            }
        }
        stage('Resuming source connector') {
            steps {
                withSecrets(awsAccountId: QA_ACCOUNT_ID, awsRole: REFRESH_ROLE, secrets: [
                    // We dont need secrets but it is a required argument to assume this role.
                    [id: 'qa/refresh-aura/SENTRY_DSN', environmentVariable: 'SENTRY_DSN'],
                ]) {
                    timeout(unit: 'SECONDS', time: 600) {
                        script {
                            ORIGINAL_COUNT = env.ORIGINAL_DESIRED_COUNT.toInteger()
                            if (ORIGINAL_COUNT == 0 ) {
                                echo "No instance was running, but resetting it to 1 task."
                                ORIGINAL_COUNT = 1
                            }
                            echo "Resuming Replication..."
                            sh("""
                                aws ecs update-service \
                                    --cluster "${NEO4J_SRC_CONNECTOR}" \
                                    --service "${NEO4J_SRC_CONNECTOR}" \
                                    --desired-count ${ORIGINAL_COUNT} > /dev/null
                            """)

                            RUNNING_COUNT=0
                            while (RUNNING_COUNT < 1) {
                                RUNNING_COUNT=sh(
                                    script: """
                                        aws ecs describe-services \
                                            --cluster "${NEO4J_SRC_CONNECTOR}" \
                                            --services "${NEO4J_SRC_CONNECTOR}" \
                                            --query "services[0].runningCount"
                                        """,
                                    returnStdout: true
                                ).trim()
                                echo "Found $RUNNING_COUNT running instances. Waiting for 1 or more instances."
                                if (RUNNING_COUNT < 1) {
                                    sleep 10
                                }
                            }

                        }
                    }
                }
            }
        }
    }
    post {
        always {
            script {
                slackNotify channel: SLACK_NOTIFICATIONS_CHANNEL
            }
        }
        failure {
            echo "Check if ${params.NEO4J_HOST_TO_REFRESH} is active."
            echo "If yes then you will have to run `aws ecs update-service --cluster ${NEO4J_SRC_CONNECTOR} --service ${NEO4J_SRC_CONNECTOR} --desired-count 1` to restart the source connector manually."
            echo "If the db is still down after few minutes then re-run the refresh pipeline."
        }
        cleanup {
            cleanWs()
        }
    }
}
