pipeline {
  agent any

   options {
    buildDiscarder(logRotator(numToKeepStr: '10'))
    disableConcurrentBuilds()
    skipDefaultCheckout true
  }

  tools {
    maven 'apache-maven-latest'
    jdk 'temurin-jdk17-latest'
  }

  environment {
    PUBLISH_LOCATION = 'simrel-orbit'
  }

  parameters {
    choice(
      name: 'BUILD_TYPE',
      choices: ['nightly', 'milestone', 'release'],
      description: '''
        Choose the type of build.
        Note that a release build will not promote the build, but rather will promote the most recent milestone build.
        '''
    )

    string (
      name: 'ORBIT',
      defaultValue: 'https://download.eclipse.org/tools/orbit/downloads/latest-I',
      description: 'The Orbit repository to aggregate.<br/>Visit <a href="https://download.eclipse.org/justj/?file=tools/orbit/downloads/drops">https://download.eclipse.org/tools/orbit/downloads/drops/</a> for choices.'
    )

    string (
      name: 'OOMPH_MAVEN',
      defaultValue: 'https://download.eclipse.org/oomph/simrel-maven/nightly/latest',
      description: 'The Oomph Maven repository to aggregate.<br/>Visit <a href="https://download.eclipse.org/oomph/simrel-maven/">https://download.eclipse.org/oomph/simrel-maven/<a/> for choices'
    )

    booleanParam(
      name: 'PROMOTE',
      defaultValue: false,
      description: 'Whether to promote the build to the download server.'
    )
  }

  stages {
    stage('Display Parameters') {
      steps {
        echo "BUILD_TYPE=${params.BUILD_TYPE}"
        echo "PROMOTE=${params.PROMOTE}"
        echo "ORBIT=${params.ORBIT}"
        echo "OOMPH_MAVEN=${params.OOMPH_MAVEN}"
        script {
          env.PROMOTE = params.PROMOTE
          env.BUILD_TYPE = params.BUILD_TYPE
          env.ORBIT = params.ORBIT
          env.OOMPH_MAVEN = params.OOMPH_MAVEN
        }
      }
    }

    stage('Git Checkout') {
      steps {
        script {
          def gitVariables = checkout(
            poll: false,
            scm: [
              $class: 'GitSCM',
              branches: [[name: '*/master']],
              doGenerateSubmoduleConfigurations: false,
              submoduleCfg: [],
              extensions: [
                [$class: 'CloneOption', shallow: true],
                [$class: 'SparseCheckoutPaths', sparseCheckoutPaths:[[$class:'SparseCheckoutPath', path:'orbit/']]]
              ],
              userRemoteConfigs: [[url: 'https://git.eclipse.org/r/oomph/org.eclipse.oomph.incubator.git' ]]
            ]
          )

          echo "$gitVariables"
          env.GIT_COMMIT = gitVariables.GIT_COMMIT
        }
      }
    }

    stage('Initialize PGP') {
      steps {
        withCredentials([file(credentialsId: 'secret-subkeys.asc', variable: 'KEYRING')]) {
         sh '''
           gpg --batch --import "${KEYRING}"
           for fpr in $(gpg --list-keys --with-colons  | awk -F: \'/fpr:/ {print $10}\' | sort -u); do echo -e "5\ny\n" |  gpg --batch --command-fd 0 --expert --edit-key ${fpr} trust; done
           '''
        }
      }
    }

    stage('Modify Aggregation') {
      steps {
        script {
          def contents = readFile( file: 'orbit/orbit.aggr' )
          contents = contents.replaceAll('location="[^"]+" description="oomph-maven"', "location=\"${OOMPH_MAVEN}\"").replaceAll('location="[^"]+" description="orbit"', "location=\"${ORBIT}\"")
          echo "$contents"
          writeFile( file: 'orbit/orbit.aggr', text: contents)
        }
      }
    }

    stage('Build SimRel Orbit') {
      steps {
        sshagent(['projects-storage.eclipse.org-bot-ssh']) {
          dir('orbit') {
            withCredentials([
                string(credentialsId: 'gpg-passphrase', variable: 'KEYRING_PASSPHRASE') ]) {
              sh '''
                if [[ $PROMOTE == false ]]; then
                  promotion_argument='-Dorg.eclipse.justj.p2.manager.args='
                fi
                mvn \
                  --no-transfer-progress \
                  $promotion_argument \
                  -Pgpg-sign \
                  -Dgpg.passphrase="${KEYRING_PASSPHRASE}" \
                  -Dorg.eclipse.justj.p2.manager.build.url=$JOB_URL \
                  -Dorg.eclipse.justj.p2.manager.relative=$PUBLISH_LOCATION \
                  -Dgit.commit=$GIT_COMMIT \
                  -Dbuild.id=$BUILD_NUMBER \
                  -Dbuild.type=$BUILD_TYPE \
                  clean \
                  verify
                '''
            }
          }
        }
      }
    }

    stage('Start Repository Analysis') {
      when {
        expression {
          params.PROMOTE
        }
      }
      steps {
        sshagent(['projects-storage.eclipse.org-bot-ssh']) {
          script {
            def repositories = sh(returnStdout: true, script: '''
                ssh genie.oomph@projects-storage.eclipse.org '
                  cd /home/data/httpd/download.eclipse.org/oomph/
                  for i in $(find '${PUBLISH_LOCATION}' -name content.xml.xz); do [ ! -d $(dirname $i)/archive ] && echo $(dirname $i); done
                  exit 0
                '
            ''')

            for (String repository : repositories.split("\\s")) {
              echo "repository: '${repository}'"
              build job: 'repository-analyzer-any',
              parameters: [
                  booleanParam(name: 'PROMOTE', value: true),
                  booleanParam(name: 'TEST', value: false),
                  string(name: 'RELATIVE_LOCATION', value: "${repository}")
              ],
              wait: false
            }
          }
        }
      }
    }

    stage('Archive Results') {
      steps {
        archiveArtifacts 'orbit/**'
      }
    }
  }

  post {
    failure {
      mail to: 'ed.merks@gmail.com',
      subject: "[Oomph CI] Build Failure ${currentBuild.fullDisplayName}",
      mimeType: 'text/html',
      body: "Project: ${env.JOB_NAME}<br/>Build Number: ${env.BUILD_NUMBER}<br/>Build URL: ${env.BUILD_URL}<br/>Console: ${env.BUILD_URL}/console"
    }

    fixed {
      mail to: 'ed.merks@gmail.com',
      subject: "[Oomph CI] Back to normal ${currentBuild.fullDisplayName}",
      mimeType: 'text/html',
      body: "Project: ${env.JOB_NAME}<br/>Build Number: ${env.BUILD_NUMBER}<br/>Build URL: ${env.BUILD_URL}<br/>Console: ${env.BUILD_URL}/console"
    }

    cleanup {
      deleteDir()
    }
  }
}