/**
 *
 * Deploy the product cluster using Jenkins master on CICD cluster
 *
 * Expected parameters:
 *   STACKS                        List of deployments from 'all physical' view in the Jenkins
                                   They should be separated by newline
 *   PARENT_NODE_NAME
 *   OS_AUTH_URL                   OpenStack keystone catalog URL
 *   OS_PROJECT_NAME               OpenStack project (tenant) name
 *   OS_CREDENTIALS                OpenStack username and password credentials ID in Jenkins
 *   OS_USER_DOMAIN_NAME           OpenStack domain

 *   TCP_QA_REFS                   Reference to the tcp-qa change on Gerrit, like refs/changes/46/418546/41
 */
@Library('tcp-qa')_

common = new com.mirantis.mk.Common()
shared = new com.mirantis.system_qa.SharedPipeline()
import jenkins.model.*

def stacks = env.STACKS.readLines()

def get_last_build_time(job_name) {
  def job = Hudson.instance.getJob(job_name)
  def last_build = Jenkins.instance.getItemByFullName(job.fullName).getLastBuild()
  if (last_build == null) {
  	return null
  }
  def upStreamBuild = Jenkins.getInstance().getItemByFullName(job.fullName).getBuildByNumber(last_build.getNumber())
  return upStreamBuild.getTime()
}

@NonCPS
def oldest_job(map) {
  return map.sort({a, b -> a.value <=> b.value})*.key[0]
}

// ============================================================================
timeout(time: 15, unit: 'HOURS') {
  node (env.PARENT_NODE_NAME) {
    stage("Remove extra stacks") {
        withCredentials([
           [$class          : 'UsernamePasswordMultiBinding',
           credentialsId   : env.OS_CREDENTIALS,
           passwordVariable: 'OS_PASSWORD',
           usernameVariable: 'OS_USERNAME']
        ]) {
            env.OS_IDENTITY_API_VERSION = 3
            for (stack_name in stacks) {
              shared.run_cmd("""
                export OS_IDENTITY_API_VERSION=3
                export OS_AUTH_URL=${OS_AUTH_URL}
                export OS_USERNAME=${OS_USERNAME}
                export OS_PASSWORD=${OS_PASSWORD}
                export OS_PROJECT_NAME=${OS_PROJECT_NAME}
                export OS_USER_DOMAIN_NAME=${OS_USER_DOMAIN_NAME}
                openstack --insecure stack delete -y ${stack_name} || true
                timeout 20m /bin/bash -c "while openstack --insecure stack show ${stack_name} -f value -c stack_status; do sleep 10; done";
              """)
            }
        }
    }

    stage("Start deployment") {
      def jobs_map = [:]
      for (stack_name in stacks) {
        jobs_map.put ("${stack_name}", get_last_build_time(stack_name))
      }
      stack_to_deploy = oldest_job(jobs_map)

      println "Build ${stack_to_deploy}"
      currentBuild.description = "${stack_to_deploy}"
      // Trigger job
      def deploy = build job: "${stack_to_deploy}",
        parameters: [
            string(name: 'PARENT_NODE_NAME', value: env.PARENT_NODE_NAME),
            string(name: 'OS_CREDENTIALS', value: env.OS_CREDENTIALS),
            string(name: 'OS_AUTH_URL', value: env.OS_AUTH_URL),
            string(name: 'OS_PROJECT_NAME', value: env.OS_PROJECT_NAME),
            string(name: 'OS_USER_DOMAIN_NAME', value: env.OS_USER_DOMAIN_NAME),
            string(name: 'TCP_QA_REFS', value: env.TCP_QA_REFS)
        ]
    }
  }
}