#!groovy
// This script is run daily by https://jenkins.znc.in/ to:
// * upload new English strings to https://crowdin.com/project/znc-bouncer
// * download new translations
// * commits results to ZNC repo

import groovy.json.JsonSlurper;
import groovy.json.JsonOutput;

def upstream_user = 'znc'
def upstream_repo = 'znc'
def my_user = 'znc-jenkins'
def my_repo = 'znc'
def branches = ['master', '1.8.x']

def pr_mode = false

timestamps {
  node {
    timeout(time: 30, unit: 'MINUTES') {
      stage('WsCleanup') {
        step([$class: 'WsCleanup'])
      }
      def tasks = [:]
      def crowdin_cli = "java -jar ${tool 'crowdin-cli'}/crowdin-cli.jar --config .ci/crowdin.yml"
      for (def branch in branches) {
        def upstream_branch = branch
        def my_branch = "l10n_${branch}"
        tasks[branch] = {
          stage(upstream_branch) {
            dir(upstream_branch) {
              stage("Checkout ${upstream_branch}") {
                checkout([$class: 'GitSCM', branches: [[name: "*/${upstream_branch}"]], doGenerateSubmoduleConfigurations: false, extensions: [[$class: 'SubmoduleOption', recursiveSubmodules: true]], userRemoteConfigs: [[credentialsId: '6ef10f80-20dc-4661-af45-52a6e1e15749', name: 'upstream', url: "git@github.com:${upstream_user}/${upstream_repo}.git"]]])
              }
              stage("Prepare strings for ${upstream_branch}") {
                dir("build") {
                  sh "cmake .."
                  sh 'make translation'
                }
                sh 'rm -rf build/'
                sh 'git status'
              }
              stage("Crowdin for ${upstream_branch}") {
                withCredentials([string(credentialsId: '11c7e2b4-f990-4670-98a4-c89d2a5a2f43', variable: 'CROWDIN_API_KEY')]) {
                  withEnv(['CROWDIN_BASE_PATH='+pwd()]) {
                    sh "$crowdin_cli upload sources --branch ${upstream_branch}"
                    // sh "$crowdin_cli upload translations --branch ${upstream_branch}"
                    sh "$crowdin_cli download --branch ${upstream_branch}"
                  }
                }
                sh 'LANG=C.UTF-8 find . -name "*.po" -exec msgfilter -i "{}" -o "{}.replacement" .ci/cleanup-po.pl ";"'
                sh 'find . -name "*.po" -exec mv "{}.replacement" "{}" ";"'
                withCredentials([string(credentialsId: 'fe727e3e-a8e0-4019-817f-6583c3c51ef7', variable: 'CROWDIN_API2_KEY')]) {
                  def headers = [[maskValue: true, name: 'Authorization', value: "Bearer ${env.CROWDIN_API2_KEY}"], [maskValue: false, name: 'User-Agent', value: 'https://github.com/znc/znc/blob/master/.ci/Jenkinsfile.crowdin']]
                  def contributors = httpRequest consoleLogResponseBody: true, customHeaders: headers, url: "https://crowdin.com/api/v2/projects/289533/members?limit=500"
                  writeFile file: 'contributors.tmp', text: contributors.content
                }
                sh '.ci/crowdin-contributors.py < contributors.tmp'
                sh 'rm contributors.tmp'
              }
              stage("Push ${upstream_branch}") {
                sh 'git config user.name "ZNC-Jenkins"'
                sh 'git config user.email jenkins@znc.in'
                sh 'git status'
                def git_status_short = sh (script: 'git status --short', returnStdout: true)
                def modified_locales = sh (
                  script: 'git status --short | grep -o -E "[^ ]+\\.po$" | sed "s/.po//g" | grep -o -E "[a-z]{2}_[A-Z]{2}$" | sort -u | tr "\\n" " " | sed -E "s/ $//"',
                  returnStdout: true
                )
                sh 'git add .'
                try {
                  sh "git commit -m 'Update translations from Crowdin for ${modified_locales}'"
                } catch(e) {
                  echo 'No changes found'
                  return
                }
                sh "git remote add my git@github.com:${my_user}/${my_repo}.git"
                if (!pr_mode) {
                  sshagent(credentials: ['baf2df74-935d-40e5-b20f-076e92fa3e9f']) {
                    sh "git push upstream HEAD:refs/heads/${upstream_branch}"
                  }
                  return
                }
                sshagent(credentials: ['6ef10f80-20dc-4661-af45-52a6e1e15749']) {
                  sh "git push my HEAD:refs/heads/${my_branch} -f"
                }
                // Create pull request if it doesn't exist yet
                withCredentials([string(credentialsId: '7a2546ae-8a29-4eab-921c-6a4803456dce', variable: 'GITHUB_OAUTH_KEY')]) {
                  def headers = [[maskValue: true, name: 'Authorization', value: "token ${env.GITHUB_OAUTH_KEY}"], [maskValue: false, name: 'Accept', value: 'application/vnd.github.v3+json'], [maskValue: false, name: 'User-Agent', value: 'https://github.com/znc/znc/blob/master/.ci/Jenkinsfile.crowdin']]
                  def pulls = httpRequest consoleLogResponseBody: true, customHeaders: headers, url: "https://api.github.com/repos/${upstream_user}/${upstream_repo}/pulls?head=${my_user}:${my_branch}&base=${upstream_branch}"
                  pulls = new JsonSlurper().parseText(pulls.content)
                  if (!pulls) {
                    def bodyContents = "Crowdin: https://crowdin.com/project/znc-bouncer\nJenkins Build: ${env.BUILD_URL}"
                    bodyContents += "\n\nModified locales:\n${modified_locales}"
                    bodyContents += "\n\n<details><summary>Modified files</summary>${git_status_short}</details>"

                    httpRequest consoleLogResponseBody: true,
                      customHeaders: headers,
                      url: "https://api.github.com/repos/${upstream_user}/${upstream_repo}/pulls",
                      httpMode: 'POST',
                      requestBody: JsonOutput.toJson(
                        [
                          head: my_user + ':' + my_branch,
                          base: upstream_branch,
                          title: "Update translations in ${upstream_branch} (${modified_locales})",
                          body: bodyContents
                        ]
                      )
                  }
                }
              }
            }
          }
        }
      }
      parallel tasks
    }
  }
}

// vim: set ts=2 sw=2 et:
