#!groovy

import groovy.json.JsonOutput

def terraformProvidersVersionsParameterName = '/infra/jenkins/terraform/providers'

def getLatestProviderVersion(String provider) {
  sh(script: """
    curl -sL https://releases.hashicorp.com/${provider}/index.json | jq -r '.versions | keys | map(split(".") | map(ltrimstr("v")) | map(rtrimstr("-alpha")) | map(rtrimstr("-alpha1")) | map(rtrimstr("-alpha2")) | map(rtrimstr("-beta")) | map(rtrimstr("-beta1")) | map(rtrimstr("-beta2")) | map(rtrimstr("-beta3")) | map(tonumber)) | max | map(tostring) | join(".")'
  """, returnStdout: true).trim()
}

def compareProviderVersions(currentVersion, latestVersion) {
  echo "Compare ${currentVersion} and ${latestVersion}"
  return latestVersion.equalsIgnoreCase(currentVersion)
}

pipeline {
  agent {
    label 'linux-agents'
  }

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

  triggers {
    cron 'H 5 * * *'
  }

  environment {
    AWS_PROFILE = 'gdb-infra-dev'
  }

  stages {
    stage('Load Shared Libraries') {
      steps {
        library('infraLib')
      }
    }
    stage('Populate environment variables') {
      environment {
        CURRENT_AWS_PROVIDER_VERSION         = "${utility.getParameterValueByNameAndPath(terraformProvidersVersionsParameterName, '.aws_provider_version', env.AWS_PROFILE)}"
        CURRENT_GOOGLE_PROVIDER_VERSION      = "${utility.getParameterValueByNameAndPath(terraformProvidersVersionsParameterName, '.google_provider_version', env.AWS_PROFILE)}"
        CURRENT_GOOGLE_BETA_PROVIDER_VERSION = "${utility.getParameterValueByNameAndPath(terraformProvidersVersionsParameterName, '.google_beta_provider_version', env.AWS_PROFILE)}"
        CURRENT_LOCAL_PROVIDER_VERSION       = "${utility.getParameterValueByNameAndPath(terraformProvidersVersionsParameterName, '.local_provider_version', env.AWS_PROFILE)}"
        CURRENT_RANDOM_PROVIDER_VERSION      = "${utility.getParameterValueByNameAndPath(terraformProvidersVersionsParameterName, '.random_provider_version', env.AWS_PROFILE)}"
        CURRENT_ARCHIVE_PROVIDER_VERSION     = "${utility.getParameterValueByNameAndPath(terraformProvidersVersionsParameterName, '.archive_provider_version', env.AWS_PROFILE)}"
        CURRENT_DNS_PROVIDER_VERSION         = "${utility.getParameterValueByNameAndPath(terraformProvidersVersionsParameterName, '.dns_provider_version', env.AWS_PROFILE)}"
        CURRENT_NULL_PROVIDER_VERSION        = "${utility.getParameterValueByNameAndPath(terraformProvidersVersionsParameterName, '.null_provider_version', env.AWS_PROFILE)}"
        CURRENT_TIME_PROVIDER_VERSION        = "${utility.getParameterValueByNameAndPath(terraformProvidersVersionsParameterName, '.time_provider_version', env.AWS_PROFILE)}"

        LATEST_AWS_PROVIDER_VERSION         = "${getLatestProviderVersion('terraform-provider-aws')}"
        LATEST_GOOGLE_PROVIDER_VERSION      = "${getLatestProviderVersion('terraform-provider-google')}"
        LATEST_GOOGLE_BETA_PROVIDER_VERSION = "${getLatestProviderVersion('terraform-provider-google-beta')}"
        LATEST_LOCAL_PROVIDER_VERSION       = "${getLatestProviderVersion('terraform-provider-local')}"
        LATEST_RANDOM_PROVIDER_VERSION      = "${getLatestProviderVersion('terraform-provider-random')}"
        LATEST_ARCHIVE_PROVIDER_VERSION     = "${getLatestProviderVersion('terraform-provider-archive')}"
        LATEST_DNS_PROVIDER_VERSION         = "${getLatestProviderVersion('terraform-provider-dns')}"
        LATEST_NULL_PROVIDER_VERSION        = "${getLatestProviderVersion('terraform-provider-null')}"
        LATEST_TIME_PROVIDER_VERSION        = "${getLatestProviderVersion('terraform-provider-time')}"
      }
      stages {
        stage('Compare Versions') {
          steps {
            script {
              assert compareProviderVersions(env.CURRENT_AWS_PROVIDER_VERSION, env.LATEST_AWS_PROVIDER_VERSION) : 'there is a newest version of the provider'
              assert compareProviderVersions(env.CURRENT_GOOGLE_PROVIDER_VERSION, env.LATEST_GOOGLE_PROVIDER_VERSION) : 'there is a newest version of the provider'
              assert compareProviderVersions(env.CURRENT_GOOGLE_BETA_PROVIDER_VERSION, env.LATEST_GOOGLE_BETA_PROVIDER_VERSION) : 'there is a newest version of the provider'
              assert compareProviderVersions(env.CURRENT_LOCAL_PROVIDER_VERSION, env.LATEST_LOCAL_PROVIDER_VERSION) : 'there is a newest version of the provider'
              assert compareProviderVersions(env.CURRENT_RANDOM_PROVIDER_VERSION, env.LATEST_RANDOM_PROVIDER_VERSION) : 'there is a newest version of the provider'
              assert compareProviderVersions(env.CURRENT_ARCHIVE_PROVIDER_VERSION, env.LATEST_ARCHIVE_PROVIDER_VERSION) : 'there is a newest version of the provider'
              assert compareProviderVersions(env.CURRENT_DNS_PROVIDER_VERSION, env.LATEST_DNS_PROVIDER_VERSION) : 'there is a newest version of the provider'
              assert compareProviderVersions(env.CURRENT_NULL_PROVIDER_VERSION, env.LATEST_NULL_PROVIDER_VERSION) : 'there is a newest version of the provider'
              assert compareProviderVersions(env.CURRENT_TIME_PROVIDER_VERSION, env.LATEST_TIME_PROVIDER_VERSION) : 'there is a newest version of the provider'
            }
          }
          post {
            failure {
              script {
                def newProvidersVersions = [
                  aws_provider_version: env.LATEST_AWS_PROVIDER_VERSION,
                  google_provider_version: env.LATEST_GOOGLE_PROVIDER_VERSION,
                  google_beta_provider_version: env.LATEST_GOOGLE_BETA_PROVIDER_VERSION,
                  local_provider_version: env.LATEST_LOCAL_PROVIDER_VERSION,
                  random_provider_version: env.LATEST_RANDOM_PROVIDER_VERSION,
                  archive_provider_version: env.LATEST_ARCHIVE_PROVIDER_VERSION,
                  dns_provider_version: env.LATEST_DNS_PROVIDER_VERSION,
                  null_provider_version: env.LATEST_NULL_PROVIDER_VERSION,
                  time_provider_version: env.LATEST_TIME_PROVIDER_VERSION
                ]

                def newProvidersVersionsJson = JsonOutput.toJson(newProvidersVersions)

                echo(JsonOutput.prettyPrint(newProvidersVersionsJson))

                utility.putParameterValueByName(terraformProvidersVersionsParameterName, newProvidersVersionsJson, env.AWS_PROFILE)

                build wait: false, propagate: false, job: 'terraform-agent'
              }
            }
          }
        }
      }
    }
  }
}
