package com.mirantis.mk
import java.util.regex.Pattern
import com.cloudbees.groovy.cps.NonCPS
import com.sonyericsson.hudson.plugins.gerrit.trigger.hudsontrigger.GerritCause
/**
 * Gerrit functions
 *
 */

/**
 * Execute git clone and checkout stage from gerrit review
 *
 * @param config LinkedHashMap
 *        config includes next parameters:
 *          - credentialsId, id of user which should make checkout
 *          - withMerge, merge master before build
 *          - withLocalBranch, prevent detached mode in repo
 *          - withWipeOut, wipe repository and force clone
 *          - GerritTriggerBuildChooser - use magic GerritTriggerBuildChooser class from gerrit-trigger-plugin.
 *            By default,enabled.
 *        Gerrit properties like GERRIT_SCHEMA can be passed in config as gerritSchema or will be obtained from env
 * @param extraScmExtensions list of extra scm extensions which will be used for checkout (optional)
 * @return boolean result
 *
 * Usage example:
 * //anonymous gerrit checkout
 * def gitFunc = new com.mirantis.mcp.Git()
 * gitFunc.gerritPatchsetCheckout([
 *   withMerge : true
 * ])
 *
 * def gitFunc = new com.mirantis.mcp.Git()
 * gitFunc.gerritPatchsetCheckout([
 *   credentialsId : 'mcp-ci-gerrit',
 *   withMerge : true
 * ])
 */
def gerritPatchsetCheckout(LinkedHashMap config, List extraScmExtensions = []) {
    def merge = config.get('withMerge', false)
    def wipe = config.get('withWipeOut', false)
    def localBranch = config.get('withLocalBranch', false)
    def credentials = config.get('credentialsId','')
    def gerritScheme = config.get('gerritScheme', env["GERRIT_SCHEME"] ? env["GERRIT_SCHEME"] : "")
    def gerritRefSpec = config.get('gerritRefSpec', env["GERRIT_REFSPEC"] ? env["GERRIT_REFSPEC"] : "")
    def gerritName = config.get('gerritName', env["GERRIT_NAME"] ? env["GERRIT_NAME"] : "")
    def gerritHost = config.get('gerritHost', env["GERRIT_HOST"] ?  env["GERRIT_HOST"] : "")
    def gerritPort = config.get('gerritPort', env["GERRIT_PORT"] ? env["GERRIT_PORT"] : "")
    def gerritProject = config.get('gerritProject', env["GERRIT_PROJECT"] ? env["GERRIT_PROJECT"] : "")
    def gerritBranch = config.get('gerritBranch', env["GERRIT_BRANCH"] ? env["GERRIT_BRANCH"] : "")
    def path = config.get('path', "")
    def depth = config.get('depth', 0)
    def timeout = config.get('timeout', 20)
    def GerritTriggerBuildChooser = config.get('useGerritTriggerBuildChooser', true)

    def invalidParams = _getInvalidGerritParams(config)
    if (invalidParams.isEmpty()) {
        // default parameters
        def scmExtensions = [
            [$class: 'CleanCheckout'],
            [$class: 'CheckoutOption', timeout: timeout],
            [$class: 'CloneOption', depth: depth, noTags: false, reference: '', shallow: depth > 0, timeout: timeout]
        ]
        def scmUserRemoteConfigs = [
            name: 'gerrit',
        ]
        if(gerritRefSpec && gerritRefSpec != ""){
            scmUserRemoteConfigs.put('refspec', gerritRefSpec)
        }

        if (credentials == '') {
            // then try to checkout in anonymous mode
            scmUserRemoteConfigs.put('url',"${gerritScheme}://${gerritHost}/${gerritProject}")
        } else {
            // else use ssh checkout
            scmUserRemoteConfigs.put('url',"ssh://${gerritName}@${gerritHost}:${gerritPort}/${gerritProject}.git")
            scmUserRemoteConfigs.put('credentialsId',credentials)
        }

        // Usefull, if we only need to clone branch. W\o any refspec magic
        if (GerritTriggerBuildChooser) {
            scmExtensions.add([$class: 'BuildChooserSetting', buildChooser: [$class: 'GerritTriggerBuildChooser']],)
        }

        // if we need to "merge" code from patchset to GERRIT_BRANCH branch
        if (merge) {
            scmExtensions.add([$class: 'PreBuildMerge', options: [fastForwardMode: 'FF', mergeRemote: 'gerrit', mergeStrategy: 'DEFAULT', mergeTarget: gerritBranch]])
        }
        // we need wipe workspace before checkout
        if (wipe) {
            scmExtensions.add([$class: 'WipeWorkspace'])
        }

        if(localBranch){
            scmExtensions.add([$class: 'LocalBranch', localBranch: gerritBranch])
        }

        if(!extraScmExtensions.isEmpty()){
            scmExtensions.addAll(extraScmExtensions)
        }
        if (path == "") {
            checkout(
                scm: [
                    $class: 'GitSCM',
                    branches: [[name: "${gerritBranch}"]],
                    extensions: scmExtensions,
                    userRemoteConfigs: [scmUserRemoteConfigs]
                ]
            )
        } else {
            dir(path) {
                checkout(
                    scm: [
                        $class: 'GitSCM',
                        branches: [[name: "${gerritBranch}"]],
                        extensions: scmExtensions,
                        userRemoteConfigs: [scmUserRemoteConfigs]
                    ]
                )
            }
        }
        return true
    }else{
        throw new Exception("Cannot perform gerrit checkout, missed config options: " + invalidParams)
    }
    return false
}
/**
 * Execute git clone and checkout stage from gerrit review
 *
 * @param gerritUrl gerrit url with scheme
 *    "${GERRIT_SCHEME}://${GERRIT_NAME}@${GERRIT_HOST}:${GERRIT_PORT}/${GERRIT_PROJECT}.git
 * @param gerritRef gerrit ref spec
 * @param gerritBranch gerrit branch
 * @param credentialsId jenkins credentials id
 * @param path checkout path, optional, default is empty string which means workspace root
 * @return boolean result
 */
def gerritPatchsetCheckout(gerritUrl, gerritRef, gerritBranch, credentialsId, path="") {
    def gerritParams = _getGerritParamsFromUrl(gerritUrl)
    if(gerritParams.size() == 5){
        if (path==""){
            gerritPatchsetCheckout([
              credentialsId : credentialsId,
              gerritBranch: gerritBranch,
              gerritRefSpec: gerritRef,
              gerritScheme: gerritParams[0],
              gerritName: gerritParams[1],
              gerritHost: gerritParams[2],
              gerritPort: gerritParams[3],
              gerritProject: gerritParams[4]
            ])
            return true
        } else {
            dir(path) {
                gerritPatchsetCheckout([
                  credentialsId : credentialsId,
                  gerritBranch: gerritBranch,
                  gerritRefSpec: gerritRef,
                  gerritScheme: gerritParams[0],
                  gerritName: gerritParams[1],
                  gerritHost: gerritParams[2],
                  gerritPort: gerritParams[3],
                  gerritProject: gerritParams[4]
                ])
                return true
            }
        }
    }
    return false
}

/**
 * Return gerrit change object from gerrit API
 * @param gerritName gerrit user name (usually GERRIT_NAME property)
 * @param gerritHost gerrit host (usually GERRIT_HOST property)
 * @param gerritPort gerrit port (usually GERRIT_PORT property, default 29418)
 * @param gerritChangeNumber gerrit change number (usually GERRIT_CHANGE_NUMBER property)
 * @param credentialsId jenkins credentials id for gerrit
 * @param includeCurrentPatchset do you want to include current (last) patchset
 * @return gerrit change object
 */
def getGerritChange(gerritName, gerritHost, gerritChangeNumber, credentialsId, includeCurrentPatchset = false, gerritPort = '29418'){
    def common = new com.mirantis.mk.Common()
    def ssh = new com.mirantis.mk.Ssh()
    ssh.prepareSshAgentKey(credentialsId)
    ssh.ensureKnownHosts("${gerritHost}:${gerritPort}")
    def curPatchset = "";
    if(includeCurrentPatchset){
        curPatchset = "--current-patch-set"
    }
    return common.parseJSON(ssh.agentSh(String.format("ssh -p %s %s@%s gerrit query ${curPatchset} --commit-message --format=JSON change:%s", gerritPort, gerritName, gerritHost, gerritChangeNumber)))
}

/**
 * Returns list of Gerrit trigger requested builds
 * @param allBuilds list of all builds of some job
 * @param gerritChange gerrit change number
 * @param excludePatchset gerrit patchset number which will be excluded from builds, optional null
 */
@NonCPS
def getGerritTriggeredBuilds(allBuilds, gerritChange, excludePatchset = null){
    return allBuilds.findAll{job ->
        def cause = job.causes[0]
        if(cause instanceof GerritCause &&
           (cause.getEvent() instanceof com.sonymobile.tools.gerrit.gerritevents.dto.events.PatchsetCreated ||
            cause.getEvent() instanceof com.sonymobile.tools.gerrit.gerritevents.dto.events.CommentAdded)) {
            if(excludePatchset == null || excludePatchset == 0){
                return cause.event.change.number.equals(String.valueOf(gerritChange))
            }else{
                return cause.event.change.number.equals(String.valueOf(gerritChange)) && !cause.event.patchSet.number.equals(String.valueOf(excludePatchset))
            }
        }
        return false
    }
}
/**
 * Returns boolean result of test given gerrit patchset for given approval type and value
 * @param patchset gerrit patchset
 * @param approvalType type of tested approval (optional, default Verified)
 * @param approvalValue value of tested approval (optional, default empty string which means any value)
 * @return boolean result
 * @example patchsetHasApproval(gerrit.getGerritChange(*,*,*,*, true).currentPatchSet)
 */
@NonCPS
def patchsetHasApproval(patchSet, approvalType="Verified", approvalValue = ""){
  if(patchSet && patchSet.approvals){
    for(int i=0; i < patchSet.approvals.size();i++){
      def approval = patchSet.approvals.get(i)
      if(approval.type.equals(approvalType)){
        if(approvalValue.equals("") || approval.value.equals(approvalValue)){
            return true
        }else if(approvalValue.equals("+") && Integer.parseInt(approval.value) > 0) {
            return true
        }else if(approvalValue.equals("-") && Integer.parseInt(approval.value) < 0) {
            return true
        }
      }
    }
  }
  return false
}

@NonCPS
def _getGerritParamsFromUrl(gitUrl){
    def gitUrlPattern = Pattern.compile("(.+):\\/\\/(.+)@(.+):(.+)\\/(.+)")
    def gitUrlMatcher = gitUrlPattern.matcher(gitUrl)
    if(gitUrlMatcher.find() && gitUrlMatcher.groupCount() == 5){
        return [gitUrlMatcher.group(1),gitUrlMatcher.group(2),gitUrlMatcher.group(3),gitUrlMatcher.group(4),gitUrlMatcher.group(5)]
    }
    return []
}

def _getInvalidGerritParams(LinkedHashMap config){
    def requiredParams = ["gerritScheme", "gerritName", "gerritHost", "gerritPort", "gerritProject", "gerritBranch"]
    def missedParams = requiredParams - config.keySet()
    def badParams = config.subMap(requiredParams).findAll{it.value in [null, '']}.keySet()
    return badParams + missedParams
}

/**
 * Post Gerrit comment from CI user
 *
 * @param config map which contains next params:
 *  gerritName - gerrit user name (usually GERRIT_NAME property)
 *  gerritHost - gerrit host (usually GERRIT_HOST property)
 *  gerritChangeNumber - gerrit change number (usually GERRIT_CHANGE_NUMBER property)
 *  gerritPatchSetNumber - gerrit patch set number (usually GERRIT_PATCHSET_NUMBER property)
 *  message - message to send to gerrit review patch
 *  credentialsId - jenkins credentials id for gerrit
 */
def postGerritComment(LinkedHashMap config) {
    def common = new com.mirantis.mk.Common()
    def ssh = new com.mirantis.mk.Ssh()
    String gerritName = config.get('gerritName')
    String gerritHost = config.get('gerritHost')
    String gerritChangeNumber = config.get('gerritChangeNumber')
    String gerritPatchSetNumber = config.get('gerritPatchSetNumber')
    String message = config.get('message')
    String credentialsId = config.get('credentialsId')

    ssh.prepareSshAgentKey(credentialsId)
    ssh.ensureKnownHosts(gerritHost)
    ssh.agentSh(String.format("ssh -p 29418 %s@%s gerrit review %s,%s -m \"'%s'\" --code-review 0", gerritName, gerritHost, gerritChangeNumber, gerritPatchSetNumber, message))
}

/**
 * Return map of dependent patches info for current patch set
 * based on commit message hints: Depends-On: https://gerrit_address/_CHANGE_NUMBER_
 * @param changeInfo Map Info about current patch set, such as:
 *   gerritName Gerrit user name (usually GERRIT_NAME property)
 *   gerritHost Gerrit host (usually GERRIT_HOST property)
 *   gerritChangeNumber Gerrit change number (usually GERRIT_CHANGE_NUMBER property)
 *   credentialsId Jenkins credentials id for gerrit
 * @return map of dependent patches info
 */
LinkedHashMap getDependentPatches(LinkedHashMap changeInfo) {
    def dependentPatches = [:]
    def currentChange = getGerritChange(changeInfo.gerritName, changeInfo.gerritHost, changeInfo.gerritChangeNumber, changeInfo.credentialsId, true)
    def dependentCommits = currentChange.commitMessage.tokenize('\n').findAll { it  ==~ /Depends-On: \b[^ ]+\b(\/)?/  }
    if (dependentCommits) {
        dependentCommits.each { commit ->
            def patchLink = commit.tokenize(' ')[1]
            def changeNumber = patchLink.tokenize('/')[-1].trim()
            def dependentCommit = getGerritChange(changeInfo.gerritName, changeInfo.gerritHost, changeNumber, changeInfo.credentialsId, true)
            if (dependentCommit.status == "NEW") {
                dependentPatches[dependentCommit.project] = [
                    'number': dependentCommit.number,
                    'ref': dependentCommit.currentPatchSet.ref,
                    'branch': dependentCommit.branch,
                ]
            }
        }
    }
    return dependentPatches
}

/**
 * Find Gerrit change(s) according to various input parameters like owner, topic, etc.
 * @param gerritAuth        A map containing information about Gerrit. Should include
 *                          HOST, PORT and USER
 * @param changeParams      Parameters to identify Geriit change e.g.: owner, topic,
 *                          status, branch, project
 * @param extraFlags        Additional flags for gerrit querry for example
 *                          '--current-patch-set' or '--comments' as a simple string
 */
def findGerritChange(credentialsId, LinkedHashMap gerritAuth, LinkedHashMap changeParams, String extraFlags = '', String sshOpts = '') {
    def scriptText = """
                 ssh ${sshOpts} -p ${gerritAuth['PORT']} ${gerritAuth['USER']}@${gerritAuth['HOST']} \
                 gerrit query ${extraFlags} \
                 --format JSON \
                 """
    def jsonChange
    changeParams.each {
        scriptText += " ${it.key}:${it.value}"
    }
    scriptText += " | fgrep -v runTimeMilliseconds || :"
    sshagent([credentialsId]) {
        jsonChange = sh(
          script: scriptText,
          returnStdout: true,
          ).trim()
    }
    return jsonChange
}

/**
 * Download Gerrit review by number
 *
 * @param credentialsId            credentials ID
 * @param virtualenv               virtualenv path
 * @param repoDir                  repository directory
 * @param gitRemote                the value of git remote
 * @param changeNum                the number of change to download
 */
def getGerritChangeByNum(credentialsId, virtualEnv, repoDir, gitRemote, changeNum) {
    def python = new com.mirantis.mk.Python()
    sshagent([credentialsId]) {
        dir(repoDir) {
            python.runVirtualenvCommand(virtualEnv, "git review -r ${gitRemote} -d ${changeNum}")
        }
    }
}

/**
 * Post Gerrit review
 * @param credentialsId            credentials ID
 * @param virtualenv               virtualenv path
 * @param repoDir                  repository directory
 * @param gitName                  committer name
 * @param gitEmail                 committer email
 * @param gitRemote                the value of git remote
 * @param gitTopic                 the name of the topic
 * @param gitBranch                the name of git branch
 */
def postGerritReview(credentialsId, virtualEnv, repoDir, gitName, gitEmail, gitRemote, gitTopic, gitBranch) {
    def python = new com.mirantis.mk.Python()
    def common = new com.mirantis.mk.Common()
    def cmdText = """
                    GIT_COMMITTER_NAME=${gitName} \
                    GIT_COMMITTER_EMAIL=${gitEmail} \
                    git review -r ${gitRemote} \
                    -t ${gitTopic} \
                    ${gitBranch}
                  """
    sshagent([credentialsId]) {
        dir(repoDir) {
            res = python.runVirtualenvCommand(virtualEnv, cmdText)
            common.infoMsg(res)
        }
    }
}

/**
 * Prepare and upload Gerrit commit from prepared repo
 * @param LinkedHashMap params dict with parameters
 *   venvDir - Absolute path to virtualenv dir
 *   gerritCredentials - credentialsId
 *   gerritHost - gerrit host
 *   gerritPort - gerrit port
 *   repoDir - path to repo dir
 *   repoProject - repo name
 *   repoBranch - repo branch
 *   changeCommitComment - comment for commit message
 *   changeAuthorName - change author
 *   changeAuthorEmail - author email
 *   changeTopic - change topic
 *   gitRemote - git remote
 *   returnChangeInfo - whether to return info about uploaded change
 *
 * @return map with change info if returnChangeInfo set to true
*/
def prepareGerritAutoCommit(LinkedHashMap params) {
    def common = new com.mirantis.mk.Common()
    def git = new com.mirantis.mk.Git()
    String venvDir = params.get('venvDir')
    String gerritCredentials = params.get('gerritCredentials')
    String gerritHost = params.get('gerritHost', 'gerrit.mcp.mirantis.net')
    String gerritPort = params.get('gerritPort', '29418')
    String gerritUser = common.getCredentialsById(gerritCredentials, 'sshKey').username
    String repoDir = params.get('repoDir')
    String repoProject = params.get('repoProject')
    String repoBranch = params.get('repoBranch', 'master')
    String changeCommitComment = params.get('changeCommitComment')
    String changeAuthorName = params.get('changeAuthorName', 'MCP-CI')
    String changeAuthorEmail = params.get('changeAuthorEmail', 'mcp-ci-jenkins@ci.mcp.mirantis.net')
    String changeTopic = params.get('changeTopic', 'auto_ci')
    Boolean returnChangeInfo = params.get('returnChangeInfo', false)
    String gitRemote = params.get('gitRemote', '')
    if (! gitRemote) {
        dir(repoDir) {
            gitRemote = sh(
                script:
                    'git remote -v | head -n1 | cut -f1',
                    returnStdout: true,
            ).trim()
        }
    }
    def gerritAuth = ['PORT': gerritPort, 'USER': gerritUser, 'HOST': gerritHost ]
    def changeParams = ['owner': gerritUser, 'status': 'open', 'project': repoProject, 'branch': repoBranch, 'topic': changeTopic]
    // find if there is old commit present
    def gerritChange = findGerritChange(gerritCredentials, gerritAuth, changeParams)
    def changeId = ''
    if (gerritChange) {
        try {
            def jsonChange = readJSON text: gerritChange
            changeId = "Change-Id: ${jsonChange['id']}".toString()
        } catch (Exception error) {
            common.errorMsg("Can't parse ouput from Gerrit. Check that user ${changeAuthorName} does not have several \
                open commits to ${repoProject} repo and ${repoBranch} branch with topic ${changeTopic}")
            throw error
        }
    }
    def commitMessage =
        """${changeCommitComment}

       |${changeId}
    """.stripMargin()
    git.commitGitChanges(repoDir, commitMessage, changeAuthorEmail, changeAuthorName, false)
    //post change
    postGerritReview(gerritCredentials, venvDir, repoDir, changeAuthorName, changeAuthorEmail, gitRemote, changeTopic, repoBranch)
    if (returnChangeInfo) {
        gerritChange = findGerritChange(gerritCredentials, gerritAuth, changeParams)
        jsonChange = readJSON text: gerritChange
        return getGerritChange(gerritUser, gerritHost, jsonChange['number'], gerritCredentials, true)
    }
}

/**
 * Get email and username from credentials id
 * @param credentialsId      Credentials ID to use for source Git
 */
def getGerritUserOptions(credentialsId) {
    def changeAuthorName = "MCP-CI"
    def changeAuthorEmail = "mcp-ci-jenkins@ci.mcp.mirantis.net"

    switch (credentialsId) {
        case 'mos-ci':
            changeAuthorName = "MOS-CI"
            changeAuthorEmail = "infra+mos-ci@mirantis.com"
            break;
        case 'mcp-ci-gerrit':
            changeAuthorName = "MCP-CI"
            changeAuthorEmail = "mcp-ci-jenkins@ci.mcp.mirantis.net"
            break;
        case 'product-ci':
            changeAuThorName = "Product CI"
            changeAuthorEmail = "infra+product-ci@mirantis.com"
            break;
        case 'services-ci':
            changeAuThorName = "Services CI"
            changeAuthorEmail = "infra+services-ci@mirantis.com"
            break;
    }
    return ["changeAuthorName": changeAuthorName,
            "changeAuthorEmail": changeAuthorEmail]
}

/**
 * Download change from gerrit, if needed repository maybe pre cloned
 *
 * @param path               Directory to checkout repository to
 * @param url                Source Gerrit repository URL
 * @param reference          Gerrit reference to download (e.g refs/changes/77/66777/16)
 * @param type               type of gerrit download
 * @param credentialsId      Credentials ID to use for source Git
 * @param gitCheckoutParams  map with additional parameters for git.checkoutGitRepository method e.g:
 *                           [ branch: 'master', poll: true, timeout: 10, depth: 0 ]
 * @param doGitClone      boolean whether to pre clone and do some checkout
 */
def downloadChange(path, url, reference, credentialsId, type = 'cherry-pick', doGitClone = true, Map gitCheckoutParams = [:]){
    def common = new com.mirantis.mk.Common()
    def git = new com.mirantis.mk.Git()
    def ssh = new com.mirantis.mk.Ssh()
    def cmd
    def credentials = common.getCredentialsById(credentialsId)
    Map gerritUserOptions = getGerritUserOptions(credentialsId)
    String gitCommiterOpts = "GIT_COMMITTER_EMAIL=\'${gerritUserOptions['changeAuthorEmail']}\' GIT_COMMITTER_NAME=\'${gerritUserOptions['changeAuthorName']}\'"
    switch(type) {
        case 'cherry-pick':
            cmd = "git fetch ${url} ${reference} && ${gitCommiterOpts} git cherry-pick FETCH_HEAD"
            break;
        case 'format-patch':
            cmd = "git fetch ${url} ${reference} && git format-patch -1 --stdout FETCH_HEAD"
            break;
        case 'pull':
            cmd = "git pull ${url} ${reference}"
            break;
        default:
            error("Unsupported gerrit download type")
    }
    if (doGitClone) {
        def branch =  gitCheckoutParams.get('branch', 'master')
        def poll = gitCheckoutParams.get('poll', true)
        def timeout = gitCheckoutParams.get('timeout', 10)
        def depth = gitCheckoutParams.get('depth', 0)
        git.checkoutGitRepository(path, url, branch, credentialsId, poll, timeout, depth, '')
    }
    sshagent (credentials: [credentialsId]) {
      dir(path){
        sh(script: "GIT_SSH_COMMAND='ssh -l ${credentials.username}' ${cmd}", returnStdout:true)
      }
    }
}

/**
 * Parse gerrit event text and if Workflow +1 is detected,
 * return true
 *
 * @param gerritEventCommentText  gerrit event comment text
 * @param gerritEventType         type of gerrit event
 */
def isGate(gerritEventCommentText, gerritEventType) {
    def common = new com.mirantis.mk.Common()
    def gerritEventCommentTextStr = ''
    def res = false
    if (gerritEventCommentText) {
        try{
            gerritEventCommentTextStr = new String(gerritEventCommentText.decodeBase64())
        } catch (e) {
            gerritEventCommentTextStr = gerritEventCommentText
        }
        common.infoMsg("GERRIT_EVENT_COMMENT_TEXT is ${gerritEventCommentTextStr}")
    }
    def gateComment = gerritEventCommentTextStr.split('\n')[0]
    if (gerritEventType == 'comment-added' && gateComment =~ /^Patch Set \d+:\s.*Workflow\+1.*$/) {
        common.infoMsg("Running in gate mode")
        res = true
    }
    return res
}

/**
 * Get gerrit change based on a given refspec.
 *
 * @param gerritAuth A map containing Gerrit authentication details (credentialsId, USER, HOST, PORT).
 * @param repoName The name of the repository.
 * @param refSpec The refspec or commit hash.
 * @return A map containing information about the Gerrit change.
 */
def getGerritChangeInfoByRefspec(Map gerritAuth, String repoName, String refSpec) {
    def common = new com.mirantis.mk.Common()
    String commitHash = ''
    if (refSpec.startsWith('refs/') || refSpec == 'master') {
        // why we have retry here? bz infra is awesome and stable!
        common.retry(15, 10) {
            sshagent([gerritAuth['credentialsId']]) {
                commitHash = sh(script: "git ls-remote ssh://${gerritAuth['USER']}@${gerritAuth['HOST']}:${gerritAuth['PORT']}/${repoName} ${refSpec}", returnStdout: true).trim().split('\\t')[0]
            }
        }
    } else {
        commitHash = refSpec
    }
    if (!commitHash) {
        common.errorMsg("Could not get commit hash for refspec '${refSpec}'")
        return [:]
    }
    LinkedHashMap gerritQuery = [
        'commit': commitHash,
    ]
    String gerritFlags = '--current-patch-set'
    String patchsetRawJson = findGerritChange(gerritAuth['credentialsId'], gerritAuth, gerritQuery, gerritFlags)
    if (!patchsetRawJson) {
        // WARNING(alexz): gerrit search only by CR. so merge event,like https://gerrit.mcp.mirantis.com/plugins/gitiles/kaas/si-tests/+/cabb45ea73ac538c653d62cb0a2ffb4802521251
        // will not be catched here. In that case, return dummy raw_commit_hash only
        common.errorMsg("Could not find gerrit change as refspec '${refSpec}' (commit: ${commitHash})")
        return ['raw_commit_hash': commitHash]
    }
    try {
        // It can (and should) return only one json for given commitHash
        return readYaml(text: patchsetRawJson)
    } catch (Exception e) {
        common.errorMsg("Could not parse JSON: ${patchsetRawJson}\nError: ${e}")
        return [:]
    }
}

/**
 * Get gerrit repository tags with gerrit API.
 *
 * @param repoName The name of the repository.
 * @param credentialsId jenkins credentials id.
 * @param trimTag Whether to trim the leading 'v' from tags.
 * @return A list containing all repository tags.
 */
def listRepoTags(String repoName, String credentialsId, Boolean trimTag = false) {
    def common = new com.mirantis.mk.Common()
    def replacePattern = trimTag ? 'refs/tags/v' : 'refs/tags/'
    def coreTags = ''
    def tags = []
    withCredentials([usernamePassword(credentialsId: credentialsId,
                     usernameVariable: 'GERRIT_USERNAME',
                     passwordVariable: 'GERRIT_PASSWORD')]) {
        common.retry(15, 10) {
            coreTags = sh(script: "echo \${GERRIT_PASSWORD} | curl -u ${GERRIT_USERNAME} https://gerrit.mcp.mirantis.com/a/projects/${repoName}/tags", returnStdout: true).trim()
        }
    }
    def jsonResponse = coreTags.split('\n').last()
    def jsonTags = readJSON text: jsonResponse
    jsonTags.each { tagData ->
        def tag = tagData['ref']?.replace(replacePattern, '')
        if (tag) {
            tags.add(tag)
        }
    }

    return tags
}