#!/usr/bin/env groovy
library 'status-jenkins-lib@v1.9.13'

import groovy.json.JsonBuilder

pipeline {
  agent { label 'linux' }

  options {
    timestamps()
    disableConcurrentBuilds()
    /* Prevent Jenkins jobs from running forever */
    timeout(time: 40, unit: 'MINUTES')
    /* Limit builds retained */
    buildDiscarder(logRotator(
      numToKeepStr: '10',
      daysToKeepStr: '30',
      artifactNumToKeepStr: '1',
    ))
  }

  /* WARNING: Defining parameters here with the ?: trick causes them to remember last value. */
  parameters {
    choice(
      name: 'BUILD_TYPE',
      description: 'Makefile target to build. Optional Parameter.',
      choices: genChoices(params.BUILD_TYPE, ['manual', 'nightly', 'release', 'pr', 'e2e']),
    )
    booleanParam(
      name: 'PUBLISH',
      description: 'Trigger publishing of build results for nightly or release.',
      defaultValue: getPublishDefault(params.PUBLISH),
    )
  }

  stages {
    stage('Prep') {
      steps { script {
        println("Current JOB: ${env.JOB_NAME}")
      } }
    }
    stage('Build') {
      parallel {
        stage('iOS') { steps { script {
          ios = jenkins.Build('status-mobile/platforms/ios')
        } } }
        stage('Android') { steps { script {
          apk = jenkins.Build('status-mobile/platforms/android')
        } } }
        stage('Tests') { steps { script {
          jenkins.Build('status-mobile/platforms/tests')
        } } }
      }
    }
    stage('Archive') {
      steps { script {
        sh('rm -f pkg/*')
        jenkins.copyArts(ios)
        jenkins.copyArts(apk)
        sha = "pkg/${utils.pkgFilename(ext: 'sha256')}"
        dir('pkg') {
          /* generate sha256 checksums for upload */
          sh "sha256sum * | tee ../${sha}"
          archiveArtifacts('*')
        }
      } }
    }
    stage('Upload') {
      steps { script {
        /* object for easier URLs handling */
        urls = [
          /* mobile */
          Apk: utils.pkgUrl(apk),
          iOS: utils.pkgUrl(ios),
          Diawi: utils.getEnv(ios, 'DIAWI_URL'),
          /* upload the sha256 checksums file too */
          SHA: s5cmd.upload(sha),
        ]
        /* add URLs to the build description */
        jenkins.setBuildDesc(urls)
      } }
    }
    stage('Publish') {
      when { expression { params.PUBLISH } }
      steps { script {
        switch (utils.getBuildType()) {
          case 'nightly': /* Create JSON file with newest build URLs */
            updateBucketJSON(urls, 'latest.json');
            break;
          case 'release':
            github.publishReleaseFiles(repo: 'status-mobile');
            break;
        }
      } }
    }
  }
}

/* Helper that generates list of available choices for a parameter
 * but re-orders them based on the currently set value. First is default. */
def List genChoices(String previousChoice, List defaultChoices) {
  if (previousChoice == null) {
     return defaultChoices
  }
  choices = defaultChoices.minus(previousChoice)
  choices.add(0, previousChoice)
  return choices
}

/* Helper that makes PUBLISH default to 'false' unless:
 * - The build is for a release branch
 * - A user explicitly specified a value
 * Since release builds create and re-create GitHub drafts every time. */
def Boolean getPublishDefault(Boolean previousValue) {
  if (env.JOB_NAME.startsWith('status-mobile/release')) { return true }
  if (previousValue != null) { return previousValue }
  return false
}

/* Helper for updating JSON with newest builds. */
def updateBucketJSON(urls, fileName) {
  /* latest.json has slightly different key names */
  def content = [
    DIAWI: urls.Diawi,
    APK: urls.Apk, IOS: urls.iOS,
    APP: urls.App, MAC: urls.Mac,
    WIN: urls.Win, SHA: urls.SHA
  ]
  def filePath = "${pwd()}/pkg/${fileName}"
  /* it might not exist */
  sh "mkdir -p ${pwd()}/pkg"
  def contentJson = new JsonBuilder(content).toPrettyString()
  println "${filePath}:\n${contentJson}"
  writeFile(file: filePath, text: contentJson)
  return s5cmd.upload(filePath)
}