// zip package functions where the target is a folder with VERSION file inside
def setZipPackagePipelineParams(failIfReleaseExists, projectPath, projectGroup, legacyOptions=true) {
  // uses common environment variables to set parameter map for zipPackagePipeline method
  def params = [:]

  // Jenkins build parameters
  if (legacyOptions) {
    //revert value if legacy options is still true
    params.failIfReleaseExists = failIfReleaseExists == "no" ? "yes" : "no"
  }
  else {
    params.failIfReleaseExists = failIfReleaseExists
  }

  // Common variables to parameters
  params.octopusChannel       = env.OCTOPUS_CHANNEL
  params.deployEnv            = env.DEPLOY_ENV
  params.zipPackageUploadMode = env.ZIP_PACKAGE_UPLOAD_MODE

  params.projectName    = projectPath.split('/')[-1]
  params.octopusProject = "${projectGroup}.${params.projectName.replace('_','-')}"
  params.workDir        = "${env.WORKSPACE}/${projectPath}"
  params.version        = octopus.getVersion(env.BRANCH_NAME,params.workDir)
  params.projectPath    = projectPath

  return params
}

def zipPackagePipeline(params) {
  stage('Create an artifact and upload it to octopus') {
    echo "Version: ${params.version} Octopus project: ${params.octopusProject}"
    echo octopus.createZipPackageV3(params.octopusProject,params.version,params.workDir)
    echo octopus.pushPackage("./${params.octopusProject}.${params.version}.zip", params.zipPackageUploadMode)
    echo octopus.createPackageBuildInformation(params.octopusProject, params.version)
  }
  stage('Create a release in octopus') {
    if ( params.failIfReleaseExists == 'yes' || !octopus.releaseExists(params.octopusProject,params.version) ) {
      echo octopus.createRelease(params.octopusProject,params.version,params.octopusChannel)
    } else {
      echo "Step skipped because release already exists in octopus and failIfReleaseExists option was set to no."
    }
  }
  stage('Deploy release in octopus') {
    if (params.deployEnv != 'skip_deployment') {
      echo octopus.deployRelease(params.octopusProject,params.deployEnv,params.version,params.octopusChannel)
    } else {
      echo "Step skipped due to conditions."
    }
  }
}


// zip package functions where the target is a folder or a single file with versions.json file in the repository root

// setDeploymentEnv function version with default deployments to dev
def setDeploymentEnvV2(deployEnvChoice, projectGroup, branch) {
  switch(deployEnvChoice) {
    case "default":
      return ("qa" + " " + projectGroup)
    case "skip_deployment":
      return deployEnvChoice
    default:
      return (deployEnvChoice + " " + projectGroup)
  }
}

def setZipPackagePipelineParamsV2(failIfReleaseExists, projectPath, projectGroup, projectName='', legacyOptions=true) {
  // uses common environment variables to set parameter map for zipPackagePipeline method
  def params = [:]

  // Jenkins build parameters
  if (legacyOptions) {
    //revert value if legacy options is still true
    params.failIfReleaseExists = failIfReleaseExists == "no" ? "yes" : "no"
  }
  else {
    params.failIfReleaseExists = failIfReleaseExists
  }

  // Common variables to parameters
  params.octopusChannel       = env.OCTOPUS_CHANNEL
  params.deployEnv            = env.DEPLOY_ENV
  params.zipPackageUploadMode = env.ZIP_PACKAGE_UPLOAD_MODE

  if (projectName == '') {
    params.projectName = projectPath.split('/')[-1]
  }
  else {
    params.projectName = projectName
  }

  params.octopusProject = "${projectGroup}.${params.projectName.replace('_','-')}"
  params.target         = "${env.WORKSPACE}/${projectPath}"
  params.version        = octopus.getVersionV2(env.BRANCH_NAME,params.projectName)

  return params
}

def zipPackagePipelineV2(params) {
  stage('Create an artifact and upload it to octopus') {
    echo "Version: ${params.version} Octopus project: ${params.octopusProject}"
    echo octopus.createZipPackageV1(params.octopusProject,params.version,params.target)
    echo octopus.pushPackage("./${params.octopusProject}.${params.version}.zip", params.zipPackageUploadMode)
    echo octopus.createPackageBuildInformation(params.octopusProject, params.version)
  }
  stage('Create a release in octopus') {
    if ( params.failIfReleaseExists == 'yes' || !octopus.releaseExists(params.octopusProject,params.version) ) {
      echo octopus.createRelease(params.octopusProject,params.version,params.octopusChannel)
    } else {
      echo "Step skipped because release already exists in octopus and failIfReleaseExists option was set to no."
    }
  }
  stage('Deploy release in octopus') {
    if (params.deployEnv != 'skip_deployment') {
      echo octopus.deployRelease(params.octopusProject,params.deployEnv,params.version,params.octopusChannel)
    } else {
      echo "Step skipped due to skip_deployment parameter."
    }
  }
}

// V3 version for snowflake
def setZipPackagePipelineParamsV3(failIfReleaseExists, projectPath, projectGroup, projectName, version) {
  // uses common environment variables to set parameter map for zipPackagePipeline method
  def params = [:]


  params.failIfReleaseExists = failIfReleaseExists

  // Common variables to parameters
  params.octopusChannel       = env.OCTOPUS_CHANNEL
  params.deployEnv            = env.DEPLOY_ENV
  params.zipPackageUploadMode = env.ZIP_PACKAGE_UPLOAD_MODE
  params.projectName          = projectName
  params.octopusProject       = "${projectGroup}.${params.projectName.replace('_','-')}"
  params.target               = "${env.WORKSPACE}/${projectPath}"
  params.version              = version

  return params
}

def stageFlag(forceBuild, stageParams) {
  // Map that defines what parts of pipeline will be triggered.
  // It can be test only, test + the rest of pipeline, or skipping the stage at all
  // Depends on FORCE_BUILD parameter, TEST_ALL parameter and
  // on whether there were changes in files for current component
  def mainPipelineFlag = false
  switch(forceBuild) {
    case 'ALL':
    case stageParams.name:
      echo "Project have been choosen directly or Build ALL is running"
      mainPipelineFlag = true
      break
    case 'Please make a choice':
      echo "default choice"
      if (pythonPackage.isPathInChangeSet(stageParams.path)) {
        mainPipelineFlag = true
      }
      break
    default:
      echo "Other project is being built"
      mainPipelineFlag = false
      break
  }
  return mainPipelineFlag
}

// Generuc stages
def getStage(jenkinsParams, stageParams) {
  return {
    if (stageFlag(jenkinsParams.FORCE_BUILD, stageParams)) {
      stage(stageParams.name) {
        switch (stageParams.mode) {
          case "json":
            zipPackagePipelineV2(
              setZipPackagePipelineParamsV2(
                jenkinsParams.SKIP_RELEASE_CREATION,
                stageParams.path,
                env.PROJECT_GROUP,
                stageParams.name
              )
            )
            break
          case "txt":
            zipPackagePipeline(
              setZipPackagePipelineParams(
                jenkinsParams.SKIP_RELEASE_CREATION,
                stageParams.path,
                env.PROJECT_GROUP
              )
            )
            break
          default:
            error "Zip packages should use json or txt mode for versioning."
        }
      }
    }
  }
}

def generateStages(jenkinsParams, stagesParamList) {
  stagesMap = [:]

  // each member of stagesParamsList should have name, path and mode specified
  stagesParamList.each {
    stagesMap.put(it.name, getStage(jenkinsParams,it))
  }
  return stagesMap
}

def prepareMultiEnvConfigs(name,envs,source_path="configs",dest_path="artifacts") {
  for (env in envs) {
    def dest_path_dir = "${dest_path}/${name}/${env}/${name}".split('/')[0..-2].join('/')
    sh(script: "mkdir -p ${dest_path_dir}",returnStdout: true).trim()
    sh(script: "cp ${source_path}/${env}/${name}.json ${dest_path}/${name}/${env}/${name}.json",returnStdout: true).trim()
  }
}

//Slz monorepo parallel job invocations
def prepareStepFunctionBuildStages(jenkinsParams, stageJobList, buildJobList, branchId) {
  def stagesMap = [:]
  stageJobList.each{
    stagesMap.put(it, getStepFuncRunJobStage(jenkinsParams, it, buildJobList, branchId))
  }
  return stagesMap
}

//Slz monorepo parallel job invocations
def getStepFuncRunJobStage(jenkinsParams, job, buildJobList, branchId) {
  return {
    stage(job) {
      if (buildJobList.contains(job)) {
        build job: "${job}/${branchId}",
          parameters: [
            string(name: 'DEPLOY_ENV_CHOICE', value: "${jenkinsParams.DEPLOY_ENV_CHOICE}"),
            string(name: 'ZIP_PACKAGE_UPLOAD_MODE', value: "${jenkinsParams.ZIP_PACKAGE_UPLOAD_MODE}"),
            string(name: 'FAIL_IF_RELEASE_EXISTS', value: "${jenkinsParams.FAIL_IF_RELEASE_EXISTS}")
          ]
      }
      else {
        println "Skipping stage ${job}"
      }
    }
  }
}
