package com.mirantis.mk

/**
 *
 * Git functions
 *
 */

/**
 * Checkout single git repository
 *
 * @param path            Directory to checkout repository to
 * @param url             Source Git repository URL
 * @param branch          Source Git repository branch
 * @param credentialsId   Credentials ID to use for source Git
 * @param poll            Enable git polling (default true)
 * @param timeout         Set checkout timeout (default 10)
 * @param depth           Git depth param (default 0 means no depth)
 * @param reference       Git reference param to checkout (default empyt, i.e. no reference)
 * @param withWipeOut     Enable workspace wipe before checkout
 */
def checkoutGitRepository(path, url, branch, credentialsId = null, poll = true, timeout = 10, depth = 0, reference = '', withWipeOut = false){
    def branch_name = reference ? 'FETCH_HEAD' : "*/${branch}"
    def scmExtensions = [
        [$class: 'CheckoutOption', timeout: timeout],
        [$class: 'CloneOption', depth: depth, noTags: false, shallow: depth > 0, timeout: timeout]
    ]

    // wipe workspace before checkout
    if (withWipeOut) {
        scmExtensions.add([$class: 'WipeWorkspace'])
    }

    dir(path) {
        checkout(
            changelog:true,
            poll: poll,
            scm: [
                $class: 'GitSCM',
                branches: [[name: branch_name]],
            doGenerateSubmoduleConfigurations: false,
            extensions: scmExtensions,
            submoduleCfg: [],
            userRemoteConfigs: [[url: url, credentialsId: credentialsId, refspec: reference]]]
        )
    }
}

/**
 * Parse HEAD of current directory and return commit hash
 */
def getGitCommit() {
    git_commit = sh (
        script: 'git rev-parse HEAD',
        returnStdout: true
    ).trim()
    return git_commit
}

/**
 * Change actual working branch of repo
 *
 * @param path            Path to the git repository
 * @param branch          Branch desired to switch to
 */
def changeGitBranch(path, branch) {
    dir(path) {
        git_cmd = sh (
            script: "git checkout ${branch}",
            returnStdout: true
        ).trim()
    }
    return git_cmd
}

/**
 * Get remote URL
 *
 * @param name  Name of remote (default any)
 * @param type  Type (fetch or push, default fetch)
 */
def getGitRemote(name = '', type = 'fetch') {
    gitRemote = sh (
        script: "git remote -v | grep '${name}' | grep ${type} | awk '{print \$2}' | head -1",
        returnStdout: true
    ).trim()
    return gitRemote
}

/**
 * Get commit message for given commit reference
 */
def getGitCommitMessage(String path, String commitRef = 'HEAD') {
    dir(path) {
        commitMsg = sh (
            script: "git log --format=%B -n 1 ${commitRef}",
            returnStdout: true
        ).trim()
    }
    return commitMsg
}

/**
 * Create new working branch for repo
 *
 * @param path            Path to the git repository
 * @param branch          Branch desired to switch to
 */
def createGitBranch(path, branch) {
    def git_cmd
    dir(path) {
        git_cmd = sh (
            script: "git checkout -b ${branch}",
            returnStdout: true
        ).trim()
    }
    return git_cmd
}

/**
 * Commit changes to the git repo
 *
 * @param path            Path to the git repository
 * @param message         A commit message
 * @param global          Use global config
 * @param amend           Whether to use "--amend" in commit command
 */
def commitGitChanges(path, message, gitEmail='jenkins@localhost', gitName='jenkins-slave', global=false, amend=false) {
    def git_cmd
    def gitOpts
    def global_arg = ''
    if (global) {
        global_arg = '--global'
    }
    if (amend) {
        gitOpts = '--amend'
    } else {
        gitOpts = ''
    }
    def gitEnv = [
        "GIT_AUTHOR_NAME=${gitName}",
        "GIT_AUTHOR_EMAIL=${gitEmail}",
        "GIT_COMMITTER_NAME=${gitName}",
        "GIT_COMMITTER_EMAIL=${gitEmail}",
    ]
    dir(path) {
        sh "git config ${global_arg} user.email '${gitEmail}'"
        sh "git config ${global_arg} user.name '${gitName}'"

        sh(
            script: 'git add -A',
            returnStdout: true
        ).trim()
        withEnv(gitEnv) {
            git_cmd = sh(
                script: "git commit ${gitOpts} -m '${message}'",
                returnStdout: true
            ).trim()
        }
    }
    return git_cmd
}

/**
 * Push git changes to remote repo
 *
 * @param path            Path to the local git repository
 * @param branch          Branch on the remote git repository
 * @param remote          Name of the remote repository
 * @param credentialsId   Credentials with write permissions
 */
def pushGitChanges(path, branch = 'master', remote = 'origin', credentialsId = null) {
    def ssh = new com.mirantis.mk.Ssh()
    dir(path) {
        if (credentialsId == null) {
            sh script: "git push ${remote} ${branch}"
        }
        else {
            ssh.prepareSshAgentKey(credentialsId)
            ssh.runSshAgentCommand("git push ${remote} ${branch}")
        }
    }
}


/**
 * Mirror git repository, merge target changes (downstream) on top of source
 * (upstream) and push target or both if pushSource is true
 *
 * @param sourceUrl      Source git repository
 * @param targetUrl      Target git repository
 * @param credentialsId  Credentials id to use for accessing target repositories
 * @param branches       List or comma-separated string of branches to sync
 * @param followTags     Mirror tags
 * @param pushSource     Push back into source branch, resulting in 2-way sync
 * @param pushSourceTags Push target tags into source or skip pushing tags
 * @param gitEmail       Email for creation of merge commits
 * @param gitName        Name for creation of merge commits
 */
def mirrorGit(sourceUrl, targetUrl, credentialsId, branches, followTags = false, pushSource = false, pushSourceTags = false, gitEmail = 'jenkins@localhost', gitName = 'Jenkins', sourceRemote = 'origin') {
    def common = new com.mirantis.mk.Common()
    def ssh = new com.mirantis.mk.Ssh()
    if (branches instanceof String) {
        branches = branches.tokenize(',')
    }
    // If both source and target repos are secured and accessible via http/https,
    // we need to switch GIT_ASKPASS value when running git commands
    def sourceAskPass
    def targetAskPass

    def sshCreds = common.getCredentialsById(credentialsId, 'sshKey') // True if found
    if (sshCreds) {
        ssh.prepareSshAgentKey(credentialsId)
        ssh.ensureKnownHosts(targetUrl)
        sh "git config user.name '${gitName}'"
    } else {
        withCredentials([[$class          : 'UsernamePasswordMultiBinding',
                          credentialsId   : credentialsId,
                          passwordVariable: 'GIT_PASSWORD',
                          usernameVariable: 'GIT_USERNAME']]) {
            sh """
                set +x
                git config --global credential.${targetUrl}.username \${GIT_USERNAME}
                echo "echo \${GIT_PASSWORD}" > ${WORKSPACE}/${credentialsId}_askpass.sh
                chmod +x ${WORKSPACE}/${credentialsId}_askpass.sh
                git config user.name \${GIT_USERNAME}
            """
            sourceAskPass = env.GIT_ASKPASS ?: ''
            targetAskPass =  "${WORKSPACE}/${credentialsId}_askpass.sh"
        }
    }
    sh "git config user.email '${gitEmail}'"

    def remoteExistence = sh(script: "git remote -v | grep ${TARGET_URL} | grep target", returnStatus: true)
    if(remoteExistence == 0) {
        // silently try to remove target
        sh(script: "git remote remove target", returnStatus: true)
    }
    sh("git remote add target ${TARGET_URL}")
    if (sshCreds) {
        ssh.agentSh "git remote update --prune"
    } else {
        env.GIT_ASKPASS = sourceAskPass
        sh "git remote update ${sourceRemote} --prune"
        env.GIT_ASKPASS = targetAskPass
        sh "git remote update target --prune"
    }

    for (i=0; i < branches.size; i++) {
        branch = branches[i]
        sh "git branch | grep ${branch} || git checkout -b ${branch}"
        def resetResult = sh(script: "git checkout ${branch} && git reset --hard origin/${branch}", returnStatus: true)
        if(resetResult != 0){
            common.warningMsg("Cannot reset to origin/${branch} for perform git mirror, trying to reset from target/${branch}")
            resetResult = sh(script: "git checkout ${branch} && git reset --hard target/${branch}", returnStatus: true)
            if(resetResult != 0){
                throw new Exception("Cannot reset even to target/${branch}, git mirroring failed!")
            }
        }

        sh "git ls-tree target/${branch} && git merge --no-edit --ff target/${branch} || echo 'Target repository is empty, skipping merge'"
        followTagsArg = followTags ? "--follow-tags" : ""
        if (sshCreds) {
            ssh.agentSh "git push ${followTagsArg} target HEAD:${branch}"
        } else {
            sh "git push ${followTagsArg} target HEAD:${branch}"
        }

        if (pushSource == true) {
            followTagsArg = followTags && pushSourceTags ? "--follow-tags" : ""
            if (sshCreds) {
                ssh.agentSh "git push ${followTagsArg} origin HEAD:${branch}"
            } else {
                sh "git push ${followTagsArg} origin HEAD:${branch}"
            }
        }
    }
    if (followTags == true) {
        if (sshCreds) {
            ssh.agentSh "git push -f target --tags"
        } else {
            sh "git push -f target --tags"
        }

        if (pushSourceTags == true) {
            if (sshCreds) {
                ssh.agentSh "git push -f origin --tags"
            } else {
                sh "git push -f origin --tags"
            }
        }
    }
    sh "git remote rm target"
    if (!sshCreds) {
        sh "set +x; rm -f ${targetAskPass}"
        sh "git config --global --unset credential.${targetUrl}.username"
    }
}


/**
 * Return all branches for the defined git repository that match the matcher.
 *
 * @param repoUrl        URL of git repository
 * @param branchMatcher  matcher to filter out the branches (If '' or '*', returns all branches without filtering)
 * @return branchesList  list of branches
 */

def getBranchesForGitRepo(repoUrl, branchMatcher = ''){

    if (branchMatcher.equals("*")) {
        branchMatcher = ''
    }
    branchesList = sh (
                script: "git ls-remote --heads ${repoUrl} | cut -f2 | grep -e '${branchMatcher}' | sed 's/refs\\/heads\\///g'",
                returnStdout: true
        ).trim()
    return branchesList.tokenize('\n')
}

/**
 * Method for preparing a tag to be SemVer 2 compatible, and can handle next cases:
 * - length of tag splitted by dots is more than 3
 * - first part of splitted tag starts not from digit
 * - length of tag is lower than 3
 *
 * @param   tag       String which contains a git tag from repository
 * @return  HashMap   HashMap in the form: ['version': 'x.x.x', 'extra': 'x.x.x'], extra
 *                    is added only if size of original tag splitted by dots is more than 3
 */

def prepareTag(tag){
    def parts = tag.tokenize('.')
    def res = [:]
    // Handle case with tags like v1.1.1
    parts[0] = parts[0].replaceFirst("[^\\d.]", '')
    // handle different sizes of tags - 1.1.1.1 or 1.1.1.1rc1
    if (parts.size() > 3){
        res['extra'] = parts[3..-1].join('.')
    } else if (parts.size() < 3){
        (parts.size()..2).each {
            parts[it] = '0'
        }
    }
    res['version'] = "${parts[0]}.${parts[1]}.${parts[2]}"
    return res
}

/**
 * Method for incrementing SemVer 2 compatible version
 *
 * @param version  String which contains main part of SemVer2 version - '2.1.0'
 * @return string  String conaining version with Patch part of version incremented by 1
 */

def incrementVersion(version){
    def parts = checkVersion(version)
    return "${parts[0]}.${parts[1]}.${parts[2].toInteger() + 1}"
}

/**
 * Method for checking whether version is compatible with Sem Ver 2
 *
 * @param version  String which contains main part of SemVer2 version - '2.1.0'
 * @return list    With 3 strings as result of splitting version by dots
 */

def checkVersion(version) {
    def parts = version.tokenize('.')
    if (parts.size() != 3 || !(parts[0] ==~ /^\d+/)) {
        error "Bad version ${version}"
    }
    return parts
}

/**
 * Method for constructing SemVer2 compatible version from tag in Git repository:
 * - if current commit matches the last tag, last tag will be returned as version
 * - if no tag found assuming no release was done, version will be 0.0.1 with pre release metadata
 * - if tag found - patch part of version will be incremented and pre-release metadata will be added
 *
 *
 * @param repoDir          String which contains path to directory with git repository
 * @param allowNonSemVer2  Bool   whether to allow working with tags which aren't compatible
 *                                with Sem Ver 2 (not in form X.Y.Z). if set to true tag will be
*                                 converted to Sem Ver 2 version e.g tag 1.1.1.1rc1 -> version 1.1.1-1rc1
 * @return version  String
 */
def getVersion(repoDir, allowNonSemVer2 = false) {
    def common = new com.mirantis.mk.Common()
    dir(repoDir){
        def cmd = common.shCmdStatus('git describe --tags --first-parent --abbrev=0')
        def tag_data = [:]
        def last_tag = cmd['stdout'].trim()
        def commits_since_tag
        if (cmd['status'] != 0){
            if (cmd['stderr'].contains('fatal: No names found, cannot describe anything')){
                common.warningMsg('No parent tag found, using initial version 0.0.0')
                tag_data['version'] = '0.0.0'
                commits_since_tag = sh(script: 'git rev-list --count HEAD', returnStdout: true).trim()
            } else {
                error("Something went wrong, cannot find git information ${cmd['stderr']}")
            }
        } else {
            tag_data['version'] = last_tag
            commits_since_tag = sh(script: "git rev-list --count ${last_tag}..HEAD", returnStdout: true).trim()
        }
        try {
            checkVersion(tag_data['version'])
        } catch (Exception e) {
            if (allowNonSemVer2){
                common.errorMsg(
    """Git tag isn't compatible with SemVer2, but allowNonSemVer2 is set.
    Trying to convert git tag to Sem Ver 2 compatible version
    ${e.message}""")
                tag_data = prepareTag(tag_data['version'])
            } else {
                error("Git tag isn't compatible with SemVer2\n${e.message}")
            }
        }
        // If current commit is exact match to the first parent tag than return it
        def pre_release_meta = []
        if (tag_data.get('extra')){
            pre_release_meta.add(tag_data['extra'])
        }
        if (common.shCmdStatus('git describe --tags --first-parent --exact-match')['status'] == 0){
            if (pre_release_meta){
                return "${tag_data['version']}-${pre_release_meta[0]}"
            } else {
                return tag_data['version']
            }
        }
        // If we away from last tag for some number of commits - add additional metadata and increment version
        pre_release_meta.add(commits_since_tag)
        def next_version = incrementVersion(tag_data['version'])
        def commit_sha = sh(script: 'git rev-parse --short=7 HEAD', returnStdout: true).trim()
        return "${next_version}-${pre_release_meta.join('.')}-${commit_sha}"
    }
}


/**
 * Method for uploading a change request
 *
 * @param repo              String which contains path to directory with git repository
 * @param credentialsId     Credentials id to use for accessing target repositories
 * @param commit            Id of commit which should be uploaded
 * @param branch            Name of the branch for uploading
 * @param topic             Topic of the change
 *
 */
def pushForReview(repo, credentialsId, commit, branch, topic='', remote='origin') {
    def common = new com.mirantis.mk.Common()
    def ssh = new com.mirantis.mk.Ssh()
    common.infoMsg("Uploading commit ${commit} to ${branch} for review...")

    def pushArg = "${commit}:refs/for/${branch}"
    def process = [:]
    if (topic){
        pushArg += '%topic=' + topic
    }
    dir(repo){
        ssh.prepareSshAgentKey(credentialsId)
        ssh.runSshAgentCommand("git push ${remote} ${pushArg}")
    }
}

/**
 * Generates a commit message with predefined or auto generate change id. If change
 * id isn't provided, changeIdSeed and current sha of git head will be used in
 * generation of commit change id.
 *
 * @param repo              String which contains path to directory with git repository
 * @param message           Commit message main part
 * @param changeId          User defined change-id usually sha1 hash
 * @param changeIdSeed      Custom part of change id which can be added during change id generation
 *
 *
 * @return commitMessage    Multiline String with generated commit message
 */
def genCommitMessage(repo, message, changeId = '', changeIdSeed = ''){
    def git = new com.mirantis.mk.Git()
    def common = new com.mirantis.mk.Common()
    def commitMessage
    def id = changeId
    def seed = changeIdSeed
    if (!id) {
        if (!seed){
            seed = common.generateRandomHashString(32)
        }
        def head_sha
        dir(repo){
            head_sha = git.getGitCommit()
        }
        id = 'I' + sh(script: 'echo -n ' + seed + head_sha + ' | sha1sum | awk \'{print $1}\'', returnStdout: true)
    }
    commitMessage =
            """${message}

           |Change-Id: ${id}
        """.stripMargin()

    return commitMessage
}

/**
 * Update (or create if cannot find) gerrit change request
 *
 * @param params   Map of parameters to customize commit
 *   - gerritAuth         A map containing information about Gerrit. Should include HOST, PORT and USER
 *   - credentialsId      Jenkins credentials id for gerrit
 *   - repo               Local directory with repository
 *   - comment            Commit comment
 *   - change_id_seed     Custom part of change id which can be added during change id generation
 *   - branch             Name of the branch for uploading
 *   - topic              Topic of the change
 *   - project            Gerrit project to search in for gerrit change request
 *   - status             Change request's status to search for
 *   - changeAuthorEmail  Author's email of the change
 *   - changeAuthorName   Author's name of the change
 *   - forceUpdate        Whether to update change if no diff between local state and remote
 *   - gerritPatch        Maps with patch information (result of gerrit.findGerritChange)
 *   - amend              Do amend current patch
 */
def updateChangeRequest(Map params) {
    def gerrit = new com.mirantis.mk.Gerrit()
    def common = new com.mirantis.mk.Common()

    def commitMessage
    def creds = params['credentialsId']
    def repo = params['repo']
    def comment = params['comment']
    def change_id_seed = params.get('change_id_seed', JOB_NAME)
    def branch = params['branch']
    def topic = params['topic']
    def changeAuthorEmail = params['changeAuthorEmail']
    def changeAuthorName = params['changeAuthorName']
    def forceUpdate = params.get('forceUpdate', true)
    def amend = params.get('amend', false)
    def jsonChange = params.get('gerritPatch', [:])
    def changeId = params.get('changeId', '')
    def remote = params.get('remote', 'origin')
    def commit

    if (!jsonChange) {
        def auth = params['gerritAuth']
        def status = params.get('status', 'open')
        def project = params['project']
        def changeParams = ['owner': auth['USER'], 'status': status, 'project': project, 'branch': branch, 'topic': topic]
        def gerritChange = gerrit.findGerritChange(creds, auth, changeParams, '--current-patch-set')
        if (gerritChange) {
            jsonChange = readJSON text: gerritChange
        }
    }
    if (jsonChange) {
        changeId = jsonChange['id']
        if(!forceUpdate){
            def ref = jsonChange['currentPatchSet']['ref']
            def res
            dir(repo){
                sshagent (credentials: [creds]){
                    res = common.shCmdStatus("git fetch origin ${ref} && git diff --quiet --exit-code FETCH_HEAD")["status"]
                }
            }
            if (res == 0){
                common.infoMsg("Current patch set ${ref} is up to date, no need to update")
                return
            }
        }
    }
    commitMessage = genCommitMessage(repo, comment, changeId, change_id_seed)
    commitGitChanges(repo, commitMessage, changeAuthorEmail, changeAuthorName, false, amend)
    dir(repo){
        commit = getGitCommit()
    }
    pushForReview(repo, creds, commit, branch, topic, remote)
}

/**
 * Create new working branch for repo from patch if it exists
 *
 * @param params   Map of parameters to customize commit
 *   - gerritAuth         A map containing information about Gerrit. Should include HOST, PORT and USER
 *   - credentialsId      Jenkins credentials id for gerrit
 *   - repo               Local directory with repository
 *   - branch             Name of the branch for uploading
 *   - topic              Topic of the change
 *   - project            Gerrit project to search in for gerrit change request
 *   - status             Change request's status to search for
 */
def createGitBranchFromRef(Map params) {
    def gerrit = new com.mirantis.mk.Gerrit()
    def common = new com.mirantis.mk.Common()

    def auth = params['gerritAuth']
    def creds = params['credentialsId']
    def repo = params['repo']
    def branch = params['branch']
    def topic = params['topic']
    def project = params['project']
    def status = params.get('status', 'open')
    def localBranch = "branch_${topic}"
    def jsonChange = [:]

    def changeParams = ['owner': auth['USER'], 'status': status, 'project': project, 'branch': branch, 'topic': topic]
    def gerritChange = gerrit.findGerritChange(creds, auth, changeParams, '--current-patch-set')
    if (gerritChange) {
        jsonChange = readJSON text: gerritChange
        def ref = jsonChange['currentPatchSet']['ref']
        changeId = jsonChange['id']
        dir(repo){
            sshagent (credentials: [creds]){
                common.shCmdStatus("git fetch origin ${ref} && git checkout -b ${localBranch} FETCH_HEAD")
            }
        }
    }
    else {
        createGitBranch(repo, localBranch)
    }
    return jsonChange
}
