package com.mirantis.mk

import static groovy.json.JsonOutput.prettyPrint
import static groovy.json.JsonOutput.toJson

import com.cloudbees.groovy.cps.NonCPS
import groovy.json.JsonSlurperClassic

/**
 *
 * Common functions
 *
 */

/**
 * Generate current timestamp
 *
 * @param format Defaults to yyyyMMddHHmmss
 */
def getDatetime(format = "yyyyMMddHHmmss") {
    def now = new Date();
    return now.format(format, TimeZone.getTimeZone('UTC'));
}

/**
 * Return workspace.
 * Currently implemented by calling pwd so it won't return relevant result in
 * dir context
 */
def getWorkspace(includeBuildNum = false) {
    def workspace = sh script: 'pwd', returnStdout: true
    workspace = workspace.trim()
    if (includeBuildNum) {
        if (!workspace.endsWith("/")) {
            workspace += "/"
        }
        workspace += env.BUILD_NUMBER
    }
    return workspace
}

/**
 * Get UID of jenkins user.
 * Must be run from context of node
 */
def getJenkinsUid() {
    return sh(
        script: 'id -u',
        returnStdout: true
    ).trim()
}

/**
 * Get GID of jenkins user.
 * Must be run from context of node
 */
def getJenkinsGid() {
    return sh(
        script: 'id -g',
        returnStdout: true
    ).trim()
}

/**
 * Returns Jenkins user uid and gid in one list (in that order)
 * Must be run from context of node
 */
def getJenkinsUserIds() {
    return sh(script: "id -u && id -g", returnStdout: true).tokenize("\n")
}

/**
 *
 * Find credentials by ID
 *
 * @param credsId Credentials ID
 * @param credsType Credentials type (optional)
 *
 */
def getCredentialsById(String credsId, String credsType = 'any') {
    def credClasses = [ // ordered by class name
                        sshKey    : com.cloudbees.jenkins.plugins.sshcredentials.impl.BasicSSHUserPrivateKey.class,
                        cert      : com.cloudbees.plugins.credentials.common.CertificateCredentials.class,
                        password  : com.cloudbees.plugins.credentials.common.StandardUsernamePasswordCredentials.class,
                        any       : com.cloudbees.plugins.credentials.impl.BaseStandardCredentials.class,
                        dockerCert: org.jenkinsci.plugins.docker.commons.credentials.DockerServerCredentials.class,
                        file      : org.jenkinsci.plugins.plaincredentials.FileCredentials.class,
                        string    : org.jenkinsci.plugins.plaincredentials.StringCredentials.class,
    ]
    return com.cloudbees.plugins.credentials.CredentialsProvider.lookupCredentials(
        credClasses[credsType],
        jenkins.model.Jenkins.instance
    ).findAll { cred -> cred.id == credsId }[0]
}

/**
 * Get credentials from store
 *
 * @param id Credentials name
 */
def getCredentials(id, cred_type = "username_password") {
    warningMsg('You are using obsolete function. Please switch to use `getCredentialsById()`')

    type_map = [
        username_password: 'password',
        key              : 'sshKey',
    ]

    return getCredentialsById(id, type_map[cred_type])
}

/**
 * Abort build, wait for some time and ensure we will terminate
 */
def abortBuild() {
    currentBuild.build().doStop()
    sleep(180)
    // just to be sure we will terminate
    throw new InterruptedException()
}

/**
 * Print pretty-printed string representation of given item
 * @param item item to be pretty-printed (list, map, whatever)
 */
def prettyPrint(item) {
    println prettify(item)
}

/**
 * Return pretty-printed string representation of given item
 * @param item item to be pretty-printed (list, map, whatever)
 * @return pretty-printed string
 */
def prettify(item) {
    return groovy.json.JsonOutput.prettyPrint(toJson(item)).replace('\\n', System.getProperty('line.separator'))
}

/**
 * Print informational message
 *
 * @param msg
 * @param color Colorful output or not
 */
def infoMsg(msg, color = true) {
    printMsg(msg, "cyan")
}

/**
 * Print error message
 *
 * @param msg
 * @param color Colorful output or not
 */
def errorMsg(msg, color = true) {
    printMsg(msg, "red")
}

/**
 * Print success message
 *
 * @param msg
 * @param color Colorful output or not
 */
def successMsg(msg, color = true) {
    printMsg(msg, "green")
}

/**
 * Print warning message
 *
 * @param msg
 * @param color Colorful output or not
 */
def warningMsg(msg, color = true) {
    printMsg(msg, "yellow")
}

/**
 * Print debug message, this message will show only if DEBUG global variable is present
 * @param msg
 * @param color Colorful output or not
 */
def debugMsg(msg, color = true) {
    // if debug property exists on env, debug is enabled
    if (env.getEnvironment().containsKey('DEBUG') && env['DEBUG'] == "true") {
        printMsg("[DEBUG] ${msg}", "red")
    }
}

/**
 * Print message
 *
 * @param msg Message to be printed
 * @param level Level of message (default INFO)
 * @param color Color to use for output or false (default)
 */
def printMsg(msg, color = false) {
    colors = [
        'red'   : '\u001B[31m',
        'black' : '\u001B[30m',
        'green' : '\u001B[32m',
        'yellow': '\u001B[33m',
        'blue'  : '\u001B[34m',
        'purple': '\u001B[35m',
        'cyan'  : '\u001B[36m',
        'white' : '\u001B[37m',
        'reset' : '\u001B[0m'
    ]
    if (color != false) {
        print "${colors[color]}${msg}${colors.reset}"
    } else {
        print "[${level}] ${msg}"
    }
}

/**
 * Traverse directory structure and return list of files
 *
 * @param path Path to search
 * @param type Type of files to search (groovy.io.FileType.FILES)
 */
@NonCPS
def getFiles(path, type = groovy.io.FileType.FILES) {
    files = []
    new File(path).eachFile(type) {
        files[] = it
    }
    return files
}

/**
 * Helper method to convert map into form of list of [key,value] to avoid
 * unserializable exceptions
 *
 * @param m Map
 */
@NonCPS
def entries(m) {
    m.collect { k, v -> [k, v] }
}

/**
 * Opposite of build-in parallel, run map of steps in serial
 *
 * @param steps Map of String<name>: CPSClosure2<step> (or list of closures)
 */
def serial(steps) {
    stepsArray = entries(steps)
    for (i = 0; i < stepsArray.size; i++) {
        def step = stepsArray[i]
        def dummySteps = [:]
        def stepKey
        if (step[1] instanceof List || step[1] instanceof Map) {
            for (j = 0; j < step[1].size(); j++) {
                if (step[1] instanceof List) {
                    stepKey = j
                } else if (step[1] instanceof Map) {
                    stepKey = step[1].keySet()[j]
                }
                dummySteps.put("step-${step[0]}-${stepKey}", step[1][stepKey])
            }
        } else {
            dummySteps.put(step[0], step[1])
        }
        parallel dummySteps
    }
}

/**
 * Partition given list to list of small lists
 * @param inputList input list
 * @param partitionSize (partition size, optional, default 5)
 */
def partitionList(inputList, partitionSize = 5) {
    List<List<String>> partitions = new ArrayList<>();
    for (int i = 0; i < inputList.size(); i += partitionSize) {
        partitions.add(new ArrayList<String>(inputList.subList(i, Math.min(i + partitionSize, inputList.size()))));
    }
    return partitions
}

/**
 * Get password credentials from store
 *
 * @param id Credentials name
 */
def getPasswordCredentials(id) {
    return getCredentialsById(id, 'password')
}

/**
 * Get SSH credentials from store
 *
 * @param id Credentials name
 */
def getSshCredentials(id) {
    return getCredentialsById(id, 'sshKey')
}

/**
 * Tests Jenkins instance for existence of plugin with given name
 * @param pluginName plugin short name to test
 * @return boolean result
 */
@NonCPS
def jenkinsHasPlugin(pluginName) {
    return Jenkins.instance.pluginManager.plugins.collect { p -> p.shortName }.contains(pluginName)
}

@NonCPS
def _needNotification(notificatedTypes, buildStatus, jobName) {
    if (notificatedTypes && notificatedTypes.contains("onchange")) {
        if (jobName) {
            def job = Jenkins.instance.getItem(jobName)
            def numbuilds = job.builds.size()
            if (numbuilds > 0) {
                //actual build is first for some reasons, so last finished build is second
                def lastBuild = job.builds[1]
                if (lastBuild) {
                    if (lastBuild.result.toString().toLowerCase().equals(buildStatus)) {
                        println("Build status didn't changed since last build, not sending notifications")
                        return false;
                    }
                }
            }
        }
    } else if (!notificatedTypes.contains(buildStatus)) {
        return false;
    }
    return true;
}

/**
 * Send notification to all enabled notifications services
 * @param buildStatus message type (success, warning, error), null means SUCCESSFUL
 * @param msgText message text
 * @param enabledNotifications list of enabled notification types, types: slack, hipchat, email, default empty
 * @param notificatedTypes types of notifications will be sent, default onchange - notificate if current build result not equal last result;
 *                         otherwise use - ["success","unstable","failed"]
 * @param jobName optional job name param, if empty env.JOB_NAME will be used
 * @param buildNumber build number param, if empty env.BUILD_NUM will be used
 * @param buildUrl build url param, if empty env.BUILD_URL will be used
 * @param mailFrom mail FROM param, if empty "jenkins" will be used, it's mandatory for sending email notifications
 * @param mailTo mail TO param, it's mandatory for sending email notifications, this option enable mail notification
 */
def sendNotification(buildStatus, msgText = "", enabledNotifications = [], notificatedTypes = ["onchange"], jobName = null, buildNumber = null, buildUrl = null, mailFrom = "jenkins", mailTo = null) {
    // Default values
    def colorName = 'blue'
    def colorCode = '#0000FF'
    def buildStatusParam = buildStatus != null && buildStatus != "" ? buildStatus : "SUCCESS"
    def jobNameParam = jobName != null && jobName != "" ? jobName : env.JOB_NAME
    def buildNumberParam = buildNumber != null && buildNumber != "" ? buildNumber : env.BUILD_NUMBER
    def buildUrlParam = buildUrl != null && buildUrl != "" ? buildUrl : env.BUILD_URL
    def subject = "${buildStatusParam}: Job '${jobNameParam} [${buildNumberParam}]'"
    def summary = "${subject} (${buildUrlParam})"

    if (msgText != null && msgText != "") {
        summary += "\n${msgText}"
    }
    if (buildStatusParam.toLowerCase().equals("success")) {
        colorCode = "#00FF00"
        colorName = "green"
    } else if (buildStatusParam.toLowerCase().equals("unstable")) {
        colorCode = "#FFFF00"
        colorName = "yellow"
    } else if (buildStatusParam.toLowerCase().equals("failure")) {
        colorCode = "#FF0000"
        colorName = "red"
    }
    if (_needNotification(notificatedTypes, buildStatusParam.toLowerCase(), jobNameParam)) {
        if (enabledNotifications.contains("slack") && jenkinsHasPlugin("slack")) {
            try {
                slackSend color: colorCode, message: summary
            } catch (Exception e) {
                println("Calling slack plugin failed")
                e.printStackTrace()
            }
        }
        if (enabledNotifications.contains("hipchat") && jenkinsHasPlugin("hipchat")) {
            try {
                hipchatSend color: colorName.toUpperCase(), message: summary
            } catch (Exception e) {
                println("Calling hipchat plugin failed")
                e.printStackTrace()
            }
        }
        if (enabledNotifications.contains("email") && mailTo != null && mailTo != "" && mailFrom != null && mailFrom != "") {
            try {
                mail body: summary, from: mailFrom, subject: subject, to: mailTo
            } catch (Exception e) {
                println("Sending mail plugin failed")
                e.printStackTrace()
            }
        }
    }
}

/**
 * Execute linux command and catch nth element
 * @param cmd command to execute
 * @param index index to retrieve
 * @return index-th element
 */

def cutOrDie(cmd, index) {
    def common = new com.mirantis.mk.Common()
    def output
    try {
        output = sh(script: cmd, returnStdout: true)
        def result = output.tokenize(" ")[index]
        return result;
    } catch (Exception e) {
        common.errorMsg("Failed to execute cmd: ${cmd}\n output: ${output}")
    }
}

/**
 * Check variable contains keyword
 * @param variable keywork is searched (contains) here
 * @param keyword string to look for
 * @return True if variable contains keyword (case insensitive), False if do not contains or any of input isn't a string
 */

def checkContains(variable, keyword) {
    if (env.getEnvironment().containsKey(variable)) {
        return env[variable] && env[variable].toLowerCase().contains(keyword.toLowerCase())
    } else {
        return false
    }
}

/**
 * Parse JSON string to hashmap
 * @param jsonString input JSON string
 * @return created hashmap
 */
def parseJSON(jsonString) {
    def m = [:]
    def lazyMap = new JsonSlurperClassic().parseText(jsonString)
    m.putAll(lazyMap)
    return m
}

/**
 * Test pipeline input parameter existence and validity (not null and not empty string)
 * @param paramName input parameter name (usually uppercase)
 */
def validInputParam(paramName) {
    return env.getEnvironment().containsKey(paramName) && env[paramName] != null && env[paramName] != ""
}

/**
 * Take list of hashmaps and count number of hashmaps with parameter equals eq
 * @param lm list of hashmaps
 * @param param define parameter of hashmap to read and compare
 * @param eq desired value of hashmap parameter
 * @return count of hashmaps meeting defined condition
 */

@NonCPS
def countHashMapEquals(lm, param, eq) {
    return lm.stream().filter { i -> i[param].equals(eq) }.collect(java.util.stream.Collectors.counting())
}

/**
 * Execute shell command and return stdout, stderr and status
 *
 * @param cmd Command to execute
 * @return map with stdout, stderr, status keys
 */

def shCmdStatus(cmd) {
    def res = [:]
    def stderr = sh(script: 'mktemp', returnStdout: true).trim()
    def stdout = sh(script: 'mktemp', returnStdout: true).trim()

    try {
        def status = sh(script: "${cmd} 1>${stdout} 2>${stderr}", returnStatus: true)
        res['stderr'] = sh(script: "cat ${stderr}", returnStdout: true)
        res['stdout'] = sh(script: "cat ${stdout}", returnStdout: true)
        res['status'] = status
    } finally {
        sh(script: "rm ${stderr}", returnStdout: true)
        sh(script: "rm ${stdout}", returnStdout: true)
    }

    return res
}

/**
 * Retry commands passed to body
 *
 * @param times Number of retries
 * @param delay Delay between retries (in seconds)
 * @param body Commands to be in retry block
 * @return calling commands in body
 * @example retry ( 3 , 5 ) { function body }*          retry{ function body }
 */

def retry(int times = 5, int delay = 0, Closure body) {
    int retries = 0
    def exceptions = []
    while (retries++ < times) {
        try {
            return body.call()
        } catch (e) {
            sleep(delay)
        }
    }
    currentBuild.result = "FAILURE"
    throw new Exception("Failed after $times retries")
}

/**
 * Wait for user input with timeout
 *
 * @param timeoutInSeconds Timeout
 * @param options Options for input widget
 */
def waitForInputThenPass(timeoutInSeconds, options = [message: 'Ready to go?']) {
    def userInput = true
    try {
        timeout(time: timeoutInSeconds, unit: 'SECONDS') {
            userInput = input options
        }
    } catch (err) { // timeout reached or input false
        def user = err.getCauses()[0].getUser()
        if ('SYSTEM' == user.toString()) { // SYSTEM means timeout.
            println("Timeout, proceeding")
        } else {
            userInput = false
            println("Aborted by: [${user}]")
            throw err
        }
    }
    return userInput
}

/**
 * Function receives Map variable as input and sorts it
 * by values ascending. Returns sorted Map
 * @param _map Map variable
 */
@NonCPS
def SortMapByValueAsc(_map) {
    def sortedMap = _map.sort { it.value }
    return sortedMap
}

/**
 *  Compare 'old' and 'new' dir's recursively
 * @param diffData =' Only in new/XXX/infra: secrets.yml
 Files old/XXX/init.yml and new/XXX/init.yml differ
 Only in old/XXX/infra: secrets11.yml '
 *
 * @return
 *   - new:
 - XXX/secrets.yml
 - diff:
 - XXX/init.yml
 - removed:
 - XXX/secrets11.yml

 */
def diffCheckMultidir(diffData) {
    common = new com.mirantis.mk.Common()
    // Some global constants. Don't change\move them!
    keyNew = 'new'
    keyRemoved = 'removed'
    keyDiff = 'diff'
    def output = [
        new    : [],
        removed: [],
        diff   : [],
    ]
    String pathSep = '/'
    diffData.each { line ->
        def job_file = ''
        def job_type = ''
        if (line.startsWith('Files old/')) {
            job_file = new File(line.replace('Files old/', '').tokenize()[0])
            job_type = keyDiff
        } else if (line.startsWith('Only in new/')) {
            // get clean normalized filepath, under new/
            job_file = new File(line.replace('Only in new/', '').replace(': ', pathSep)).toString()
            job_type = keyNew
        } else if (line.startsWith('Only in old/')) {
            // get clean normalized filepath, under old/
            job_file = new File(line.replace('Only in old/', '').replace(': ', pathSep)).toString()
            job_type = keyRemoved
        } else {
            common.warningMsg("Not parsed diff line: ${line}!")
        }
        if (job_file != '') {
            output[job_type].push(job_file)
        }
    }
    return output
}

/**
 * Compare 2 folder, file by file
 * Structure should be:
 * ${compRoot}/
 └── diff - diff results will be save here
 ├── new  - input folder with data
 ├── old  - input folder with data
 ├── pillar.diff - globall diff will be saved here
 * b_url - usual env.BUILD_URL, to be add into description
 * grepOpts -   General grep cmdline; Could be used to pass some magic
 *              regexp into after-diff listing file(pillar.diff)
 *              Example: '-Ev infra/secrets.yml'
 * return - html-based string
 * TODO: allow to specify subdir for results?
 **/
def comparePillars(compRoot, b_url, grepOpts) {
    common = new com.mirantis.mk.Common()
    // Some global constants. Don't change\move them!
    keyNew = 'new'
    keyRemoved = 'removed'
    keyDiff = 'diff'
    def diff_status = 0
    // FIXME
    httpWS = b_url + '/artifact/'
    dir(compRoot) {
        // If diff empty - exit 0
        diff_status = sh(script: 'diff -q -r old/ new/  > pillar.diff',
            returnStatus: true,
        )
    }
    // Unfortunately, diff not able to work with dir-based regexp
    if (diff_status == 1 && grepOpts) {
        dir(compRoot) {
            grep_status = sh(script: """
                cp -v pillar.diff pillar_orig.diff
                grep ${grepOpts} pillar_orig.diff  > pillar.diff
                """,
                returnStatus: true
            )
            if (grep_status == 1){
                common.warningMsg("Grep regexp ${grepOpts} removed all diff!")
                diff_status = 0
            }
        }
    }
    // Set job description
    String description = ''
    if (diff_status == 1) {
        // Analyse output file and prepare array with results
        String data_ = readFile file: "${compRoot}/pillar.diff"
        def diff_list = diffCheckMultidir(data_.split("\\r?\\n"))
        common.infoMsg(diff_list)
        dir(compRoot) {
            if (diff_list[keyDiff].size() > 0) {
                if (!fileExists('diff')) {
                    sh('mkdir -p diff')
                }
                description += '<b>CHANGED</b><ul>'
                common.infoMsg('Changed items:')
                for (item in diff_list[keyDiff]) {
                    // We don't want to handle sub-dirs structure. So, simply make diff 'flat'
                    item_f = item.toString().replace('/', '_')
                    description += "<li><a href=\"${httpWS}/diff/${item_f}/*view*/\">${item}</a></li>"
                    // Generate diff file
                    def diff_exit_code = sh([
                        script      : "diff -U 50 old/${item} new/${item} > diff/${item_f}",
                        returnStdout: false,
                        returnStatus: true,
                    ])
                    // catch normal errors, diff should always return 1
                    if (diff_exit_code != 1) {
                        error 'Error with diff file generation'
                    }
                }
            }
            if (diff_list[keyNew].size() > 0) {
                description += '<b>ADDED</b><ul>'
                for (item in diff_list[keyNew]) {
                    description += "<li><a href=\"${httpWS}/new/${item}/*view*/\">${item}</a></li>"
                }
            }
            if (diff_list[keyRemoved].size() > 0) {
                description += '<b>DELETED</b><ul>'
                for (item in diff_list[keyRemoved]) {
                    description += "<li><a href=\"${httpWS}/old/${item}/*view*/\">${item}</a></li>"
                }
            }

        }
    }

    if (description != '') {
        dir(compRoot) {
            archiveArtifacts([
                artifacts        : '**',
                allowEmptyArchive: true,
            ])
        }
        return description.toString()
    } else {
        return 'No job changes'
    }
}

/**
 * Simple function, to get basename from string.
 * line - path-string
 * remove_ext - string, optionl. Drop file extenstion.
 **/
def GetBaseName(line, remove_ext) {
    filename = line.toString().split('/').last()
    if (remove_ext && filename.endsWith(remove_ext.toString())) {
        filename = filename.take(filename.lastIndexOf(remove_ext.toString()))
    }
    return filename
}