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
      environment {
        AWS_PROFILE = "twitch-marionette-dev"
        AWS_SHARED_CREDENTIALS_FILE = credentials('twitch-marionette-dev')
        DOCKER_REGISTRY = "690059204336.dkr.ecr.us-west-2.amazonaws.com"
      }
      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 'git clean -ffdx'
            sh 'env'
            sh 'docker --version'
          }
        }
        stage("Test") {
          steps {
            withCredentials([sshUserPrivateKey(credentialsId: 'git-aws-read-key', keyFileVariable: 'SSH_KEY_FILE')]) {
              sh 'eval $(aws ecr get-login --no-include-email --region us-west-2)'
              sh 'make jenkins_test'
            }
          }
        }
      }
    }
    stage("Staging deploy") {
      agent any
      environment {
        AWS_PROFILE = "twitch-marionette-dev"
        AWS_SHARED_CREDENTIALS_FILE = credentials('twitch-marionette-dev')
        DOCKER_REGISTRY = "690059204336.dkr.ecr.us-west-2.amazonaws.com"
      }
      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: 'marionette_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)
        withCredentials([sshUserPrivateKey(credentialsId: 'git-aws-read-key', keyFileVariable: 'SSH_KEY_FILE')]) {
          sh 'eval $(aws ecr get-login --no-include-email --region us-west-2)'
          sh 'make jenkins_deploy_dev'
        }
      }
    }
    stage("Wait for production confirmation") {
      agent none
      when {
        branch 'master';
      }
      steps {
        input message: "Proceed?"
      }
    }
    stage("Production deploy") {
      agent any
      environment {
        AWS_PROFILE = "twitch-marionette-prod"
        AWS_SHARED_CREDENTIALS_FILE = credentials('twitch-marionette-prod')
        DOCKER_REGISTRY = "377472072742.dkr.ecr.us-west-2.amazonaws.com"
      }
      when {
        branch 'master';
      }
      options {
        lock(resource: 'marionette_production_deploy', inversePrecedence: true)
      }
      steps {
        milestone(300)
        withCredentials([sshUserPrivateKey(credentialsId: 'git-aws-read-key', keyFileVariable: 'SSH_KEY_FILE')]) {
          sh 'eval $(aws ecr get-login --no-include-email --region us-west-2)'
          sh 'make jenkins_deploy_prod'
        }
      }
    }
  }
  // TODO: Add post step to clean workspace
}
