import java.util.regex.Matcher

/**
 * Pipeline to publish the web site of the open-source community of Silverpeas. It doesn't publish
 * the documentation of each project on which Silverpeas is made up. Those documentations are
 * published only at release of each latest stable version of Silverpeas.
 *
 * This pipeline expects the following environment variable to be set:
 * STABLE_BRANCH     the SCM branch in which the current stable version of the project is currently
 *                   maintained
 *
 * This pipeline is based upon the existence of a Jenkins job named
 * 'Silverpeas_Project_Definition_AutoDeploy' that has produced a build version of the Silverpeas
 * Project POM used as POM parent for all Silverpeas projects in development. It will fetch from it
 * the job result report in order to compute some parameters required by this pipeline and to check
 * if the POM parent of the community web site project have to be updated.
 *
 * The build is performed within a dedicated Docker image in order to ensure the reproducibility of
 * the builds and to containerize them from the host OS.
 */
pipeline {

  agent {
    docker {
      image 'silverpeas/silverbuild'
      args '''
          -v $HOME/.m2/settings.xml:/home/silverbuild/.m2/settings.xml 
          -v $HOME/.m2/settings-security.xml:/home/silverbuild/.m2/settings-security.xml 
          -v $HOME/.gitconfig:/home/silverbuild/.gitconfig 
          -v $HOME/.ssh:/home/silverbuild/.ssh 
          -v $HOME/.gnupg:/home/silverbuild/.gnupg
          '''
    }
  }

  parameters {
    string (
        defaultValue: '',
        description: 'Version of Silvereas with which the web site info has to be updated. By default, an empty value means no update',
        name: 'SILVERPEAS_VERSION'
    )
  }

  environment {
    nexusRepo = 'https://nexus3.silverpeas.org/repository/releases'
    gitRepo = 'https://github.com/Silverpeas/Silverpeas-Project-Web-Site'
    gitCredential = 'cacc0467-7c85-41d1-bf4e-eaa470dd5e59'
    branch = getBranch()
    parentVersion = ''
    currentWildflyVersion = ''
    nextWildflyVersion = ''
    pom = null
  }

  stages {
    stage('Check Silverpeas version') {
      when {
        not {
          expression {
            params.SILVERPEAS_VERSION == '' ||
                (params.SILVERPEAS_VERSION.contains('-build') && branch == 'master') ||
                (isStableVersion() && (branch == 'master' || branch == env.STABLE_BRANCH))
          }
        }
      }
      steps {
        error "Community web site cannot be generated for such version: ${params.SILVERPEAS_VERSION}"
      }
    }
    stage('Checkout') {
      steps {
        git([url: gitRepo, credentialsId: gitCredential])
        script {
          pom = readMavenPom()
          parentVersion = ''
          currentWildflyVersion = ''
          nextWildflyVersion = ''
        }
      }
    }
    stage('Check POM parent version') {
      when {
        expression { pom.parent.version.contains('SNAPSHOT') }
      }
      steps {
        error "The parent POM must be at a stable or a build version for this project to be deployed. Current version is ${pom.parent.version}"
      }
    }
    stage('Prepare for a new build version of Silverpeas') {
      when {
        expression {
          params.SILVERPEAS_VERSION.contains('-build') && branch == 'master'
        }
      }
      steps {
        copyArtifacts projectName: 'Silverpeas_Project_Definition_AutoDeploy', flatten: true
        script {
          def parentBuild = readYaml file: 'build.yaml'
          String isReleased = sh returnStatus: true,
              script: "curl --output /dev/null --silent --head --fail -r 0-0 ${nexusRepo}/org/silverpeas/silverpeas-project/${parentBuild.release}/silverpeas-project-${parentBuild.release}.pom"
          parentVersion = isReleased == '0' ? parentBuild.release : parentBuild.version
          nextWildflyVersion = parentBuild.wildfly.replace('.Final', '')
          currentWildflyVersion = ''
          echo "Next Wildfly version: ${nextWildflyVersion}"
        }
        sh 'rm -f build.yaml'
      }
    }
    stage('Prepare for a new stable version of Silverpeas') {
      when {
        expression { isStableVersion() }
      }
      steps {
        copyArtifacts projectName: "Silverpeas_Release", flatten: true,
            selector: specific(params.SILVERPEAS_VERSION)
        script {
          def report = readYaml file: 'release.yaml'
          parentVersion = report.parent
          nextWildflyVersion = ''
          currentWildflyVersion = report.wildfly.replace('.Final', '')
          echo "Parent version: ${parentVersion}"
          echo "Current Wildfly version: ${currentWildflyVersion}"
        }
        sh 'rm -f release.yaml'
      }
    }
    stage('Update POM parent version') {
      when {
        expression { parentVersion && pom.parent.version < parentVersion }
      }
      steps {
        script {
          sh """
            mvn -U versions:update-parent -DgenerateBackupPoms=false -DparentVersion="[$parentVersion]"
            git commit -am "Update parent POM to version $parentVersion"
            """
        }
      }
    }
    stage('Update current version of Wildfly') {
      when {
        expression {
          currentWildflyVersion && currentWildflyVersion != pom.properties['current_wildfly_version']
        }
      }
      steps {
        sh """
          sed -i -e "s/<current_wildfly_release>[0-9]\\+/<current_wildfly_release>${currentWildflyVersion.split('\\.')[0]}/g" pom.xml
          sed -i -e "s/<current_wildfly_version>[0-9.]\\+/<current_wildfly_version>${currentWildflyVersion}/g" pom.xml
          git commit -am "Update current Wildfly version to ${currentWildflyVersion}"
          """
      }
    }
    stage('Update next version of Wildfly') {
      when {
        expression {
          nextWildflyVersion && nextWildflyVersion != pom.properties['next_wildfly_version']
        }
      }
      steps {
        sh """
          sed -i -e "s/<next_wildfly_release>[0-9]\\+/<next_wildfly_release>${nextWildflyVersion.split('\\.')[0]}/g" pom.xml
          sed -i -e "s/<next_wildfly_version>[0-9.]\\+/<next_wildfly_version>${nextWildflyVersion}/g" pom.xml
          git commit -am "Update next Wildfly version to ${nextWildflyVersion}"
          """
      }
    }
    stage('Update build version of Silverpeas') {
      when {
        expression {
          params.SILVERPEAS_VERSION && params.SILVERPEAS_VERSION.contains('-build') &&
              params.SILVERPEAS_VERSION != pom.properties['installer_build_version']
        }
      }
      steps {
        sh """
          sed -i -e "s/<installer_build_version>[0-9a-zA-Z.-]\\+/<installer_build_version>${params.SILVERPEAS_VERSION}/g" pom.xml
          git commit -am "Update the build version of Silverpeas to ${params.SILVERPEAS_VERSION}"
          """
      }
    }
    stage('Update stable version of Silverpeas') {
      when {
        expression {
          params.SILVERPEAS_VERSION && isStableVersion() &&
              params.SILVERPEAS_VERSION != pom.properties['installer_stable_version']
        }
      }
      steps {
        sh """
          sed -i -e "s/<installer_stable_version>[0-9a-zA-Z.-]\\+/<installer_stable_version>${params.SILVERPEAS_VERSION}/g" pom.xml
          sed -i -e "s/<installer_izpack_version>[0-9a-zA-Z.-]\\+/<installer_izpack_version>${params.SILVERPEAS_VERSION}/g" pom.xml
          mvn -U versions:set -DgenerateBackupPoms=false -DnewVersion=${params.SILVERPEAS_VERSION}
          sed -i -e "s/silverpeas-[0-9.]\\+-wildfly[0-9]\\+/silverpeas-${params.SILVERPEAS_VERSION}-wildfly${currentWildflyVersion.split('\\.')[0]}/g" src/site/resources/index.html
          git commit -am "Update the stable version of Silverpeas to ${params.SILVERPEAS_VERSION}"
          """
      }
    }
    stage('Publish the web site') {
      steps {
        sh 'mvn clean site-deploy'
      }
    }
    stage('Push the changes into the SCM') {
      environment {
        GIT_AUTH = credentials("${gitCredential}")
      }
      steps {
        sh script: '''
          git config --local credential.helper "!f() { echo username=\\$GIT_AUTH_USR; echo password=\\$GIT_AUTH_PSW; }; f"    
          git push origin HEAD:master
          ''', returnStatus: true
      }
    }
  }

  post {
    success {
      script {
        if (params.SILVERPEAS_VERSION) {
          currentBuild.displayName = params.SILVERPEAS_VERSION
        }
      }
    }
    always {
      step([$class                  : 'Mailer',
            notifyEveryUnstableBuild: true,
            recipients              : "miguel.moquillon@silverpeas.org, silveryocha@chastagnier.com",
            sendToIndividuals       : true])
    }
  }
}

boolean isStableVersion() {
  Matcher m = params.SILVERPEAS_VERSION =~ '^\\d+.\\d+(.\\d+)?$'
  return m.matches()
}

String getBranch() {
  Matcher matcher = params.SILVERPEAS_VERSION =~ '^(\\d+.\\d+)\\..*$'
  matcher ? "${matcher[0][1]}.x" : 'master'
}