pipeline {
    // Some steps hang forever. Rather than take an agent, we are good Jenkins denizens and explicitly say when we want
    // a jenkins worker
    agent none
    options {
        // Add timestamps before stdout/stderr in jenkins logs
        timestamps()
        // Let the jenkins logs show console command colors
        ansiColor('xterm')
        // Don't bother running builds if the pushes happen one right after the other
        quietPeriod(30)
    }
    parameters {
        // We can manually trigger these builds with DEBUG=true and output a bunch of debug logs to the build
        booleanParam(name: 'DEBUG', defaultValue: false, description: 'Debug the build with way too much verbose output.')
    }
    stages {
        stage("Verify code") {
            // We have to explicitly declare when we want an agent. Agents do things like give us a jenkins-worker node
            // that can run things or access jenkins information.  These are a reserved and limited resource, so we should
            // only take one when we need it.
            agent any
            stages {
                // Print some quick debug information at the stop so we can debug this build if things go wrong
                stage("Print debug info") {
                    steps {
                        script {
                            // Put the short git SHA in the build name so we can find a build by SHA on the UI
                            currentBuild.displayName = env.GIT_COMMIT[0..6]+ " #" + env.BUILD_NUMBER
                        }
                        sh 'env'
                        sh 'docker --version'
                    }
                }
            }
        }
        stage("Staging deploy") {
            agent {
                docker {
                    image 'python:3.7'
                    args '-u root'
                }
            }
            environment {
                AWS_PROFILE = "twitch-marionette-dev"
                AWS_SHARED_CREDENTIALS_FILE = credentials('twitch-marionette-dev')
            }
            when {
                branch 'master';
            }
            options {
                // This lock could be smarter when https://issues.jenkins-ci.org/browse/JENKINS-55485 is resolved
                // Do not allow two staging deploys at once
                // inversePrecedence will let the most recent staging deploy access the lock first
                lock(resource: 'mgst_bot_staging_deploy', inversePrecedence: true)
            }
            steps {
                // milestone means that if one build does a staging push, it will cancel older builds from also trying
                // to push to staging.
                milestone(100)
                sh 'apt-get update && apt-get install -yyq npm'
                sh 'npm install && npm run serverless -- deploy --stage dev'
            }
        }
        stage("Wait for production confirmation") {
            agent none
            when {
                branch 'master';
            }
            steps {
                input message: "Proceed?"
            }
        }
        stage("Production deploy") {
            agent {
                docker {
                    image 'python:3.7'
                    args '-u root'
                }
            }
            environment {
                AWS_PROFILE = "twitch-marionette-prod"
                AWS_SHARED_CREDENTIALS_FILE = credentials('twitch-marionette-prod')
            }
            when {
                branch 'master';
            }
            options {
                lock(resource: 'mgst_bot_production_deploy', inversePrecedence: true)
            }
            steps {
                milestone(200)
                sh 'apt-get update && apt-get install -yyq npm'
                sh 'npm install && npm run serverless -- deploy --stage production'
            }
        }
    }
    post{
        cleanup {
            script {
                docker.image("alpine:latest").inside("-u root") {
                    sh "chown -R 61000:61000 ."
                }
            }
        }
    }
}
