@NonCPS
def checkChangesInPlan(String plan) {
/*
Checks whether there are changes in the given plan.
Returns map with boolean flag fr and the message
*/
  def changes = [:]
  changes.changesInPlan = false
  changes.message = "No changes in the plan"
  for (line in plan.split('\n')) {
    if (line.contains('Plan:') && !line.contains('Plan: 0 to add, 0 to change, 0 to destroy.')) {
      changes.changesInPlan = true
      changes.message = line
      break
    }
  }
  return changes
}

def removeChangesDriftFromPlan(String plan) {
  def result = []
  def addFlag = true
  for (line in plan.split('\n')) {
    if (line.contains('Note: Objects have changed outside of Terraform')) {
      addFlag = false
    }
    if (line.contains('Terraform will perform the following actions')) {
      addFlag = true
    }
    if (addFlag) {result.add(line)}
  }
  return result.join('\n')
}

def checkBranchConditions(parameter="default") {
  switch(parameter) {
    case "default":
      switch(env.BRANCH_NAME) {
        case "master":
          return true
        default:
          return false
      }
    case "yes":
      return true
    case "no":
      return false
    default:
      return false
  }
}

def autoApplyMergedPR() {
  if (env.BRANCH_NAME == 'master') {
    last_commit_title = sh(
      script: "git log -1 --pretty=%B",
      returnStdout: true)\
      .trim().split('\n').collect{it as String}[0]
    if (last_commit_title.contains('Merge and apply pull request #') ) {
      println('Autoapply conditions are met. Commit title:')
      println(last_commit_title)
      return true
    }
  }
  return false
}

def getChangesLastOrPR() {
  // The function will provide of changelist for last commit,
  // or for whole PR if variable env.CHANGE_TARGET is presented
  def changeset = []
  if (env.CHANGE_TARGET) {
    // https://i.stack.imgur.com/4wMJI.png checkout to get difference between diff with .. and ...
    changeset = sh(
      script: "git --no-pager diff  --name-only origin/${env.CHANGE_TARGET}...origin/${env.BRANCH_NAME}",
      returnStdout: true)\
      .trim().split('\n').collect{it as String}
  }
  else {
    changeset = sh(
      script: "git --no-pager diff --name-only HEAD~1",
      returnStdout: true)\
      .trim().split('\n').collect{it as String}
  }
  // Get union of latest commit and PR changes
  return changeset
}

def getChangedTfProjectPaths(Iterable changeset, String tf_projects_dir) {
  // Filter out only Terraform folder and then remove Terraform prefix
  // Don't take into account changes in the READMY files
  def remove_prefix = ~/^${tf_projects_dir}\//
  changes_filtered_list = changeset.findAll { it.startsWith(tf_projects_dir)} \
    .collect { it - remove_prefix} \
    .findAll { !it.endsWith('README.md') }

  changes_modules_excluded = changes_filtered_list.findAll {!it.contains('modules/')}
  def remove_filename = ~/[a-zA-Z0-9._\-]*$/
  result_set = changes_modules_excluded \
    .collect{it - remove_filename } \
    .findAll{it != null && it != ""}\
    .toSet()

  /*
  // Check if root modules have changed
  if (changes_filtered_list.any{it.contains('modules/')}) {
    root_changed_modules = changes_filtered_list.findAll { it.startsWith('modules/')}
    project_changed_modules = changes_filtered_list.findAll { it.contains('/modules/')}
  }*/

  // Check if project modules have changed
  return result_set
}

def convertConfigPathToJobName(configPath, defaultJobLocation='Devops/Terraform/') {
  splittedPath = configPath.toLowerCase().split('/').toList()
  jobPath = defaultJobLocation + splittedPath[0]
  jobName = splittedPath.subList(1, splittedPath.size()).join('-').replaceAll('_', '-')
  return jobPath + '/' + jobName
}

//Prepare build stages map for list of external jobs
def prepareTerraformBuildStages(Map jenkinsParams, Iterable jobList, String branchId) {
  def stagesMap = [:]
  jobList.each{
    stagesMap.put(it, getTerraformRunJobStage(jenkinsParams, it, branchId))
  }
  return stagesMap
}

def getTerraformRunJobStage(Map jenkinsParams, String job, String branchId) {
  return {
    stage(job) {
      build job: "${job}/${branchId}",
        parameters: [
          string(name: 'TERRAFORM_APPLY', value: "${jenkinsParams.TERRAFORM_APPLY}"),
          booleanParam(name: 'SKIP_APPROVAL', value: jenkinsParams.SKIP_APPROVAL),
        ]
    }
  }
}

def runEnvironmentStages(env, envProjects, buildJobList, params, branchId) {
  def stageJobs = envProjects.toSet().intersect(buildJobList)
  println "${env} jobs:\n${stageJobs}"
  parallel(prepareTerraformBuildStages(params, stageJobs, branchId))
}

def generateTfvarsAuto (tfvarParams, jenkinsParams, path) {
  tfvarsAuto = ""
  for (param in tfvarParams) {
    tfvarsAuto += param.name + ' = "' + jenkinsParams[param.name] + '"\n'
  }
  println "resulting config"
  println tfvarsAuto
  writeFile([file: "${path}/jenkins.auto.tfvars", text: tfvarsAuto])
}
