package com.mirantis.mk

import com.cloudbees.groovy.cps.NonCPS
import java.util.stream.Collectors
/**
 * Salt functions
 *
*/

/**
 * Salt connection and context parameters
 *
 * @param url                 Salt API server URL
 * @param credentialsID       ID of credentials store entry
 */
def connection(url, credentialsId = "salt") {
    def common = new com.mirantis.mk.Common()
    params = [
        "url": url,
        "credentialsId": credentialsId,
        "authToken": null,
        "creds": common.getCredentials(credentialsId)
    ]
    params["authToken"] = saltLogin(params)
    return params
}

/**
 * Login to Salt API, return auth token
 *
 * @param master   Salt connection object
 */
def saltLogin(master) {
    def http = new com.mirantis.mk.Http()
    data = [
        'username': master.creds.username,
        'password': master.creds.password.toString(),
        'eauth': 'pam'
    ]
    authToken = http.restGet(master, '/login', data)['return'][0]['token']
    return authToken
}

/**
 * Run action using Salt API (using plain HTTP request from Jenkins master) or Pepper (from slave shell)
 *
 * @param saltId   Salt Connection object or pepperEnv (the command will be sent using the selected method) (determines if command will be sent with Pepper of Salt API )
 * @param client   Client type
 * @param target   Target specification, eg. for compound matches by Pillar
 *                 data: ['expression': 'I@openssh:server', 'type': 'compound'])
 * @param function Function to execute (eg. "state.sls")
 * @param batch    Batch param to salt (integer or string with percents)
 * @param args     Additional arguments to function
 * @param kwargs   Additional key-value arguments to function
 * @param timeout  Additional argument salt api timeout
 * @param read_timeout http session read timeout
 */
@NonCPS
def runSaltCommand(saltId, client, target, function, batch = null, args = null, kwargs = null, timeout = -1, read_timeout = -1) {

    data = [
        'tgt': target.expression,
        'fun': function,
        'client': client,
        'expr_form': target.type,
    ]

    if(batch != null){
        batch = batch.toString()
        if( (batch.isInteger() && batch.toInteger() > 0) || (batch.contains("%"))){
            data['client']= "local_batch"
            data['batch'] = batch
        }
    }

    if (args) {
        data['arg'] = args
    }

    if (kwargs) {
        data['kwarg'] = kwargs
    }

    if (timeout != -1) {
        data['timeout'] = timeout
    }

    // Command will be sent using HttpRequest
    if (saltId instanceof HashMap && saltId.containsKey("authToken") ) {

        def headers = [
          'X-Auth-Token': "${saltId.authToken}"
        ]

        def http = new com.mirantis.mk.Http()
        return http.sendHttpPostRequest("${saltId.url}/", data, headers, read_timeout)
    } else if (saltId instanceof HashMap) {
        throw new Exception("Invalid saltId")
    }

    // Command will be sent using Pepper
    return runPepperCommand(data, saltId)
}

/**
 * Return pillar for given saltId and target
 * @param saltId Salt Connection object or pepperEnv (the command will be sent using the selected method)
 * @param target Get pillar target
 * @param pillar pillar name (optional)
 * @return output of salt command
 */
def getPillar(saltId, target, pillar = null) {
    if (pillar != null) {
        return runSaltCommand(saltId, 'local', ['expression': target, 'type': 'compound'], 'pillar.get', null, [pillar.replace('.', ':')])
    } else {
        return runSaltCommand(saltId, 'local', ['expression': target, 'type': 'compound'], 'pillar.data')
    }
}

/**
 * Return grain for given saltId and target
 * @param saltId Salt Connection object or pepperEnv (the command will be sent using the selected method)
 * @param target Get grain target
 * @param grain grain name (optional)
 * @return output of salt command
 */
def getGrain(saltId, target, grain = null) {
    if(grain != null) {
        return runSaltCommand(saltId, 'local', ['expression': target, 'type': 'compound'], 'grains.item', null, [grain])
    } else {
        return runSaltCommand(saltId, 'local', ['expression': target, 'type': 'compound'], 'grains.items')
    }
}

/**
 * Return config items for given saltId and target
 * @param saltId Salt Connection object or pepperEnv (the command will be sent using the selected method)
 * @param target Get grain target
 * @param config grain name (optional)
 * @return output of salt command
 */
def getConfig(saltId, target, config) {
    return runSaltCommand(saltId, 'local', ['expression': target, 'type': 'compound'], 'config.get', null, [config.replace('.', ':')], '--out=json')
}

/**
 * Enforces state on given saltId and target
 * @param saltId Salt Connection object or pepperEnv (the command will be sent using the selected method)
 * @param target State enforcing target
 * @param state Salt state
 * @param excludedStates states which will be excluded from main state (default empty string)
 * @param output print output (optional, default true)
 * @param failOnError throw exception on salt state result:false (optional, default true)
 * @param batch salt batch parameter integer or string with percents (optional, default null - disable batch)
 * @param optional Optional flag (if true pipeline will continue even if no minions for target found)
 * @param read_timeout http session read timeout (optional, default -1 - disabled)
 * @param retries Retry count for salt state. (optional, default -1 - no retries)
 * @param queue salt queue parameter for state.sls calls (optional, default true) - CANNOT BE USED WITH BATCH
 * @param saltArgs additional salt args eq. ["runas=aptly"]
 * @return output of salt command
 */
def enforceStateWithExclude(Map params) {
    //Set defaults
    defaults = ["excludedStates": "", "output": true, "failOnError": true, "batch": null, "optional": false,
                "read_timeout": -1, "retries": -1, "queue": true, "saltArgs": []]
    params = defaults + params
    params.saltArgs << "exclude=${params.excludedStates}"
    params.remove('excludedStates')
    return enforceState(params)
}


def enforceStateWithExclude(saltId, target, state, excludedStates = "", output = true, failOnError = true, batch = null, optional = false, read_timeout=-1, retries=-1, queue=true, saltArgs=[]) {
// Deprecated, convert state to use Map as input parameter
    def common = new com.mirantis.mk.Common()
    common.infoMsg("This method will be deprecated. Convert you method call to use Map as input parameter")
    // Convert to Map
    params = ['saltId': saltId, 'target': target, 'state': state, 'excludedStates': excludedStates, 'output': output,
                'failOnError': failOnError, 'batch': batch, 'optional': optional, 'read_timeout': read_timeout,
                'retries': retries, 'queue': queue, 'saltArgs': saltArgs]
    // Call new method with Map as parameter
    return enforceStateWithExclude(params)
}

/**
 * Allows to test the given target for reachability and if reachable enforces the state
* @param saltId Salt Connection object or pepperEnv (the command will be sent using the selected method)
 * @param target State enforcing target
 * @param state Salt state
 * @param testTargetMatcher Salt compound matcher to be tested (default is empty string). If empty string, param `target` will be used for tests
 * @param output print output (optional, default true)
 * @param failOnError throw exception on salt state result:false (optional, default true)
 * @param batch salt batch parameter integer or string with percents (optional, default null - disable batch)
 * @param optional Optional flag (if true pipeline will continue even if no minions for target found)
 * @param read_timeout http session read timeout (optional, default -1 - disabled)
 * @param retries Retry count for salt state. (optional, default -1 - no retries)
 * @param queue salt queue parameter for state.sls calls (optional, default true) - CANNOT BE USED WITH BATCH
 * @param saltArgs additional salt args eq. ["runas=aptly"]
 * @return output of salt command
 */
def enforceStateWithTest(Map params) {
    def common = new com.mirantis.mk.Common()
    //Set defaults
    defaults = ["testTargetMatcher": "", "output": true, "failOnError": true, "batch": null, "optional": false,
                "read_timeout": -1, "retries": -1, "queue": true, "saltArgs":[]]
    params = defaults + params
    if (!params.testTargetMatcher) {
        params.testTargetMatcher = params.target
    }
    if (testTarget(params.saltId, params.testTargetMatcher)) {
        return enforceState(params)
    } else {
        if (!params.optional) {
                common.infoMsg("No Minions matched the target matcher: ${params.testTargetMatcher}, and 'optional' param was set to false. - This may signify missing pillar definition!!")
//              throw new Exception("No Minions matched the target matcher: ${testTargetMatcher}.") TODO: Change the infoMsg to Error once the methods are changed to Use named params and optional param will be set globally
            } else {
                common.infoMsg("No Minions matched the target matcher: ${params.testTargetMatcher}, but 'optional' param was set to true - Pipeline continues. ")
            }
    }
}


def enforceStateWithTest(saltId, target, state, testTargetMatcher = "", output = true, failOnError = true, batch = null, optional = false, read_timeout=-1, retries=-1, queue=true, saltArgs=[]) {
// Deprecated, convert state to use Map as input parameter
    def common = new com.mirantis.mk.Common()
    common.infoMsg("This method will be deprecated. Convert you method call to use Map as input parameter")
    // Convert to Map
    params = ['saltId': saltId, 'target': target, 'state': state, 'testTargetMatcher': testTargetMatcher, 'output': output,
                'failOnError': failOnError, 'batch': batch, 'optional': optional, 'read_timeout': read_timeout,
                'retries': retries, 'queue': queue, 'saltArgs': saltArgs]
    // Call new method with Map as parameter
    return enforceStateWithTest(params)
}

/* Enforces state on given saltId and target
 * @param saltId Salt Connection object or pepperEnv (the command will be sent using the selected method)
 * @param target State enforcing target
 * @param state Salt state
 * @param output print output (optional, default true)
 * @param failOnError throw exception on salt state result:false (optional, default true)
 * @param batch salt batch parameter integer or string with percents (optional, default null - disable batch)
 * @param optional Optional flag (if true pipeline will continue even if no minions for target found)
 * @param read_timeout http session read timeout (optional, default -1 - disabled)
 * @param retries Retry count for salt state. (optional, default -1 - no retries)
 * @param queue salt queue parameter for state.sls calls (optional, default true) - CANNOT BE USED WITH BATCH
 * @param saltArgs additional salt args eq. ["runas=aptly", exclude="opencontrail.database"]
 * @param minionRestartWaitTimeout specifies timeout that we should wait after minion restart.
 * @return output of salt command
 */
def enforceState(Map params) {
    def common = new com.mirantis.mk.Common()
    //Set defaults
    defaults = ["output": true, "failOnError": true, "batch": null, "optional": false,
                "read_timeout": -1, "retries": -1, "queue": true, "saltArgs": [], "minionRestartWaitTimeout": 10]
    params = defaults + params
    // add state to salt args
    if (params.state instanceof String) {
        params.saltArgs << params.state
    } else {
        params.saltArgs << params.state.join(',')
    }

    common.infoMsg("Running state ${params.state} on ${params.target}")
    def out
    def kwargs = [:]

    if (params.queue && params.batch == null) {
      kwargs["queue"] = true
    }

    if (params.optional == false || params.testTarget(params.saltId, params.target)){
        if (params.retries > 0){
            def retriesCounter = 0
            retry(params.retries){
                retriesCounter++
                // we have to reverse order in saltArgs because salt state have to be first
                out = runSaltCommand(params.saltId, 'local', ['expression': params.target, 'type': 'compound'], 'state.sls', params.batch, params.saltArgs.reverse(), kwargs, -1, params.read_timeout)
                // failOnError should be passed as true because we need to throw exception for retry block handler
                checkResult(out, true, params.output, true, retriesCounter < params.retries) //disable ask on error for every interation except last one
            }
        } else {
            // we have to reverse order in saltArgs because salt state have to be first
            out = runSaltCommand(params.saltId, 'local', ['expression': params.target, 'type': 'compound'], 'state.sls', params.batch, params.saltArgs.reverse(), kwargs, -1, params.read_timeout)
            checkResult(out, params.failOnError, params.output)
        }
        waitForMinion(out, params.minionRestartWaitTimeout)
        return out
    } else {
        common.infoMsg("No Minions matched the target given, but 'optional' param was set to true - Pipeline continues. ")
    }
}

def enforceState(saltId, target, state, output = true, failOnError = true, batch = null, optional = false, read_timeout=-1, retries=-1, queue=true, saltArgs = [], minionRestartWaitTimeout=10) {
// Deprecated, convert state to use Map as input parameter
    def common = new com.mirantis.mk.Common()
    common.infoMsg("This method will be deprecated. Convert you method call to use Map as input parameter")
    // Convert to Map
    params = ['saltId': saltId, 'target': target, 'state': state, 'output': output,
                'failOnError': failOnError, 'batch': batch, 'optional': optional, 'read_timeout': read_timeout,
                'retries': retries, 'queue': queue, 'saltArgs': saltArgs, 'minionRestartWaitTimeout': minionRestartWaitTimeout]
    // Call new method with Map as parameter
    return enforceState(params)
}

/**
 * Run command on salt minion (salt cmd.run wrapper)
 * @param saltId Salt Connection object or pepperEnv (the command will be sent using the selected method)
 * @param target Get pillar target
 * @param cmd command
 * @param checkResponse test command success execution (default true)
 * @param batch salt batch parameter integer or string with percents (optional, default null - disable batch)
 * @param output do you want to print output
 * @param saltArgs additional salt args eq. ["runas=aptly"]
 * @return output of salt command
 */
def cmdRun(saltId, target, cmd, checkResponse = true, batch=null, output = true, saltArgs = []) {
    def common = new com.mirantis.mk.Common()
    def originalCmd = cmd
    common.infoMsg("Running command ${cmd} on ${target}")
    if (checkResponse) {
      cmd = cmd + " && echo Salt command execution success"
    }

    // add cmd name to salt args list
    saltArgs << cmd

    def out = runSaltCommand(saltId, 'local', ['expression': target, 'type': 'compound'], 'cmd.run', batch, saltArgs.reverse())
    if (checkResponse) {
        // iterate over all affected nodes and check success return code
        if (out["return"]){
            for(int i=0;i<out["return"].size();i++){
                def node = out["return"][i];
                for(int j=0;j<node.size();j++){
                    def nodeKey = node.keySet()[j]
                    if (node[nodeKey] instanceof String) {
                        if (!node[nodeKey].contains("Salt command execution success")) {
                            throw new Exception("Execution of cmd ${originalCmd} failed. Server returns: ${node[nodeKey]}")
                        }
                    } else if (node[nodeKey] instanceof Boolean) {
                        if (!node[nodeKey]) {
                            throw new Exception("Execution of cmd ${originalCmd} failed. Server returns: ${node[nodeKey]}")
                        }
                    } else {
                        throw new Exception("Execution of cmd ${originalCmd} failed. Server returns unexpected data type: ${node[nodeKey]}")
                    }
                }
            }
        } else {
            throw new Exception("Salt Api response doesn't have return param!")
        }
    }
    if (output == true) {
        printSaltCommandResult(out)
    }
    return out
}

/**
 * Checks if salt minion is in a list of salt master's accepted keys
 * @usage minionPresent(saltId, 'I@salt:master', 'ntw', true, null, true, 200, 3)
 * @param saltId Salt Connection object or pepperEnv (the command will be sent using the selected method)
 * @param target Get pillar target
 * @param minion_name unique identification of a minion in salt-key command output
 * @param waitUntilPresent return after the minion becomes present (default true)
 * @param batch salt batch parameter integer or string with percents (optional, default null - disable batch)
 * @param output print salt command (default true)
 * @param maxRetries finite number of iterations to check status of a command (default 200)
 * @param answers how many minions should return (optional, default 1)
 * @return output of salt command
 */
def minionPresent(saltId, target, minion_name, waitUntilPresent = true, batch=null, output = true, maxRetries = 180, answers = 1) {
    minion_name = minion_name.replace("*", "")
    def common = new com.mirantis.mk.Common()
    common.infoMsg("Looking for minion: " + minion_name)
    def cmd = 'salt-key | grep ' + minion_name
    if (waitUntilPresent){
        def count = 0
        while(count < maxRetries) {
            try {
                def out = runSaltCommand(saltId, 'local', ['expression': target, 'type': 'compound'], 'cmd.shell', batch, [cmd], null, 5)
                if (output) {
                    printSaltCommandResult(out)
                }
                def valueMap = out["return"][0]
                def result = valueMap.get(valueMap.keySet()[0])
                def resultsArray = result.tokenize("\n")
                def size = resultsArray.size()
                if (size >= answers) {
                    return out
                }
                count++
                sleep(time: 1000, unit: 'MILLISECONDS')
                common.infoMsg("Waiting for ${cmd} on ${target} to be in correct state")
            } catch (Exception er) {
                common.infoMsg('[WARNING]: runSaltCommand command read timeout within 5 seconds. You have very slow or broken environment')
            }
        }
    } else {
        try {
            def out = runSaltCommand(saltId, 'local', ['expression': target, 'type': 'compound'], 'cmd.shell', batch, [cmd], null, 5)
            if (output) {
                printSaltCommandResult(out)
            }
            return out
        } catch (Exception er) {
            common.infoMsg('[WARNING]: runSaltCommand command read timeout within 5 seconds. You have very slow or broken environment')
        }
    }
    // otherwise throw exception
    common.errorMsg("Status of command ${cmd} on ${target} failed, please check it.")
    throw new Exception("${cmd} signals failure of status check!")
}

/**
 * Checks if salt minions are in a list of salt master's accepted keys by matching compound
 * @usage minionsPresent(saltId, 'I@salt:master', 'I@salt:minion', true, null, true, 200, 3)
 * @param saltId Salt Connection object or pepperEnv (the command will be sent using the selected method)
 * @param target Performs tests on this target node
 * @param target_minions all targeted minions to test (for ex. I@salt:minion)
 * @param waitUntilPresent return after the minion becomes present (default true)
 * @param batch salt batch parameter integer or string with percents (optional, default null - disable batch)
 * @param output print salt command (default true)
 * @param maxRetries finite number of iterations to check status of a command (default 200)
 * @param answers how many minions should return (optional, default 1)
 * @return output of salt command
 */
def minionsPresent(saltId, target = 'I@salt:master', target_minions = '', waitUntilPresent = true, batch=null, output = true, maxRetries = 200, answers = 1) {
    def target_hosts = getMinionsSorted(saltId, target_minions)
    for (t in target_hosts) {
        def tgt = stripDomainName(t)
        minionPresent(saltId, target, tgt, waitUntilPresent, batch, output, maxRetries, answers)
    }
}

/**
 * Checks if salt minions are in a list of salt master's accepted keys by matching a list
 * @usage minionsPresentFromList(saltId, 'I@salt:master', ["cfg01.example.com", "bmk01.example.com"], true, null, true, 200, 3)
 * @param saltId Salt Connection object or pepperEnv (the command will be sent using the selected method)
 * @param target Performs tests on this target node
 * @param target_minions list to test (for ex. ["cfg01.example.com", "bmk01.example.com"])
 * @param waitUntilPresent return after the minion becomes present (default true)
 * @param batch salt batch parameter integer or string with percents (optional, default null - disable batch)
 * @param output print salt command (default true)
 * @param maxRetries finite number of iterations to check status of a command (default 200)
 * @param answers how many minions should return (optional, default 1)
 * @return output of salt command
 */
def minionsPresentFromList(saltId, target = 'I@salt:master', target_minions = [], waitUntilPresent = true, batch=null, output = true, maxRetries = 200, answers = 1) {
    def common = new com.mirantis.mk.Common()
    for (tgt in target_minions) {
        common.infoMsg("Checking if minion " + tgt + " is present")
        minionPresent(saltId, target, tgt, waitUntilPresent, batch, output, maxRetries, answers)
    }
}

/**
 * You can call this function when salt-master already contains salt keys of the target_nodes
 * @param saltId Salt Connection object or pepperEnv (the command will be sent using the selected method)
 * @param target Should always be salt-master
 * @param target_nodes unique identification of a minion or group of salt minions
 * @param batch salt batch parameter integer or string with percents (optional, default null - disable batch)
 * @param wait timeout for the salt command if minions do not return (default 10)
 * @param maxRetries finite number of iterations to check status of a command (default 200)
 * @return output of salt command
 */
def minionsReachable(saltId, target, target_nodes, batch=null, wait = 10, maxRetries = 200) {
    def common = new com.mirantis.mk.Common()
    def cmd = "salt -t${wait} -C '${target_nodes}' test.ping"
    common.infoMsg("Checking if all ${target_nodes} minions are reachable")
    def count = 0
    while(count < maxRetries) {
        Calendar timeout = Calendar.getInstance();
        timeout.add(Calendar.SECOND, wait);
        def out = runSaltCommand(saltId, 'local', ['expression': target, 'type': 'compound'], 'cmd.shell', batch, [cmd], null, wait)
        Calendar current = Calendar.getInstance();
        if (current.getTime().before(timeout.getTime())) {
           printSaltCommandResult(out)
           return out
        }
        common.infoMsg("Not all of the targeted '${target_nodes}' minions returned yet. Waiting ...")
        count++
        sleep(time: 500, unit: 'MILLISECONDS')
    }
}

/**
 * Run command on salt minion (salt cmd.run wrapper)
 * @param saltId Salt Connection object or pepperEnv (the command will be sent using the selected method)
 * @param target Get pillar target
 * @param cmd name of a service
 * @param correct_state string that command must contain if status is in correct state (optional, default 'running')
 * @param find bool value if it is suppose to find some string in the output or the cmd should return empty string (optional, default true)
 * @param waitUntilOk return after the minion becomes present (optional, default true)
 * @param batch salt batch parameter integer or string with percents (optional, default null - disable batch)
 * @param output print salt command (default true)
 * @param maxRetries finite number of iterations to check status of a command (default 200)
 * @param answers how many minions should return (optional, default 0)
 * @return output of salt command
 */
def commandStatus(saltId, target, cmd, correct_state='running', find = true, waitUntilOk = true, batch=null, output = true, maxRetries = 200, answers = 0) {
    def common = new com.mirantis.mk.Common()
    common.infoMsg("Checking if status of verification command ${cmd} on ${target} is in correct state")
    if (waitUntilOk){
        def count = 0
        while(count < maxRetries) {
            def out = runSaltCommand(saltId, 'local', ['expression': target, 'type': 'compound'], 'cmd.shell', batch, [cmd], null, 5)
            if (output) {
                printSaltCommandResult(out)
            }
            def resultMap = out["return"][0]
            def success = 0
            if (answers == 0){
                answers = resultMap.size()
            }
            for (int i=0;i<answers;i++) {
                result = resultMap.get(resultMap.keySet()[i])
                // if the goal is to find some string in output of the command
                if (find) {
                    if(result == null || result instanceof Boolean || result.isEmpty()) { result='' }
                    if (result.toLowerCase().contains(correct_state.toLowerCase())) {
                        success++
                        if (success == answers) {
                            return out
                        }
                    }
                // else the goal is to not find any string in output of the command
                } else {
                    if(result instanceof String && result.isEmpty()) {
                        success++
                        if (success == answers) {
                            return out
                        }
                    }
                }
            }
            count++
            sleep(time: 500, unit: 'MILLISECONDS')
            common.infoMsg("Waiting for ${cmd} on ${target} to be in correct state")
        }
    } else {
        def out = runSaltCommand(saltId, 'local', ['expression': target, 'type': 'compound'], 'cmd.shell', batch, [cmd], null, 5)
        def resultMap = out["return"][0]
        if (output) {
            printSaltCommandResult(out)
        }
        for (int i=0;i<resultMap.size();i++) {
            result = resultMap.get(resultMap.keySet()[i])
        // if the goal is to find some string in output of the command
            if (find) {
                if(result == null || result instanceof Boolean || result.isEmpty()) { result='' }
                if (result.toLowerCase().contains(correct_state.toLowerCase())) {
                    return out
                }

            // else the goal is to not find any string in output of the command
            } else {
                if(result instanceof String && result.isEmpty()) {
                    return out
                }
            }
        }
    }
    // otherwise throw exception
    common.errorMsg("Status of command ${cmd} on ${target} failed, please check it.")
    throw new Exception("${cmd} signals failure of status check!")
}

/**
 * Perform complete salt sync between master and target
 * @param saltId Salt Connection object or pepperEnv (the command will be sent using the selected method)
 * @param target Get pillar target
 * @return output of salt command
 */
def syncAll(saltId, target) {
    return runSaltCommand(saltId, 'local', ['expression': target, 'type': 'compound'], 'saltutil.sync_all')
}

/**
 * Perform complete salt refresh between master and target
 * Method will call saltutil.refresh_pillar, saltutil.refresh_grains and saltutil.sync_all
 * @param saltId Salt Connection object or pepperEnv (the command will be sent using the selected method)
 * @param target Get pillar target
 * @return output of salt command
 */
def fullRefresh(saltId, target){
    runSaltProcessStep(saltId, target, 'saltutil.refresh_pillar', [], null, true)
    runSaltProcessStep(saltId, target, 'saltutil.refresh_grains', [], null, true)
    runSaltProcessStep(saltId, target, 'saltutil.sync_all', [], null, true)
}

/**
 * Enforce highstate on given targets
 * @param saltId Salt Connection object or pepperEnv (the command will be sent using the selected method)
 * @param target Highstate enforcing target
 * @param excludedStates states which will be excluded from main state (default empty string)
 * @param output print output (optional, default true)
 * @param failOnError throw exception on salt state result:false (optional, default true)
 * @param batch salt batch parameter integer or string with percents (optional, default null - disable batch)
 * @param saltArgs additional salt args eq. ["runas=aptly", exclude="opencontrail.database"]
 * @return output of salt command
 */
def enforceHighstateWithExclude(saltId, target, excludedStates = "", output = false, failOnError = true, batch = null, saltArgs = []) {
    saltArgs << "exclude=${excludedStates}"
    return enforceHighstate(saltId, target, output, failOnError, batch, saltArgs)
}
/**
 * Enforce highstate on given targets
 * @param saltId Salt Connection object or pepperEnv (the command will be sent using the selected method)
 * @param target Highstate enforcing target
 * @param output print output (optional, default true)
 * @param failOnError throw exception on salt state result:false (optional, default true)
 * @param batch salt batch parameter integer or string with percents (optional, default null - disable batch)
 * @return output of salt command
 */
def enforceHighstate(saltId, target, output = false, failOnError = true, batch = null, saltArgs = []) {
    def out = runSaltCommand(saltId, 'local', ['expression': target, 'type': 'compound'], 'state.highstate', batch, saltArgs)
    def common = new com.mirantis.mk.Common()

    common.infoMsg("Running state highstate on ${target}")

    checkResult(out, failOnError, output)
    return out
}

/**
 * Get running minions IDs according to the target
 * @param saltId Salt Connection object or pepperEnv (the command will be sent using the selected method)
 * @param target Get minions target
 * @return list of active minions fitin
 */
def getMinions(saltId, target) {
    def minionsRaw = runSaltCommand(saltId, 'local', ['expression': target, 'type': 'compound'], 'test.ping')
    return new ArrayList<String>(minionsRaw['return'][0].keySet())
}

/**
 * Get sorted running minions IDs according to the target
 * @param saltId Salt Connection object or pepperEnv
 * @param target Get minions target
 * @return list of sorted active minions fitin
 */
def getMinionsSorted(saltId, target) {
    return getMinions(saltId, target).sort()
}

/**
 * Get first out of running minions IDs according to the target
 * @param saltId Salt Connection object or pepperEnv
 * @param target Get minions target
 * @return first of active minions fitin
 */
def getFirstMinion(saltId, target) {
    def minionsSorted = getMinionsSorted(saltId, target)
    return minionsSorted[0]
}

/**
 * Get running salt minions IDs without it's domain name part and its numbering identifications
 * @param saltId Salt Connection object or pepperEnv
 * @param target Get minions target
 * @return list of active minions fitin without it's domain name part name numbering
 */
def getMinionsGeneralName(saltId, target) {
    def minionsSorted = getMinionsSorted(saltId, target)
    return stripDomainName(minionsSorted[0]).replaceAll('\\d+$', "")
}

/**
 * Get domain name of the env
 * @param saltId Salt Connection object or pepperEnv
 * @return domain name
 */
def getDomainName(saltId) {
    return getReturnValues(getPillar(saltId, 'I@salt:master', '_param:cluster_domain'))
}

/**
 * Remove domain name from Salt minion ID
 * @param name String of Salt minion ID
 * @return Salt minion ID without its domain name
 */
def stripDomainName(name) {
    return name.split("\\.")[0]
}

/**
 * Gets return values of a salt command
 * @param output String of Salt minion ID
 * @return Return values of a salt command
 */
def getReturnValues(output) {
    if(output.containsKey("return") && !output.get("return").isEmpty()) {
        return output['return'][0].values()[0]
    }
    def common = new com.mirantis.mk.Common()
    common.errorMsg('output does not contain return key')
    return ''
}

/**
 * Get minion ID of one of KVM nodes
 * @param saltId Salt Connection object or pepperEnv (the command will be sent using the selected method)
 * @return Salt minion ID of one of KVM nodes in env
 */
def getKvmMinionId(saltId) {
    return getReturnValues(getGrain(saltId, 'I@salt:control', 'id')).values()[0]
}

/**
 * Get Salt minion ID of KVM node hosting 'name' VM
 * @param saltId Salt Connection object or pepperEnv
 * @param name Name of the VM (for ex. ctl01)
 * @return Salt minion ID of KVM node hosting 'name' VM
 */
def getNodeProvider(saltId, nodeName) {
    def salt = new com.mirantis.mk.Salt()
    def common = new com.mirantis.mk.Common()
    def kvms = salt.getMinions(saltId, 'I@salt:control')
    for (kvm in kvms) {
        try {
            vms = salt.getReturnValues(salt.runSaltProcessStep(saltId, kvm, 'virt.list_domains', [], null, true))
            if (vms.toString().contains(nodeName)) {
                return kvm
            }
        } catch (Exception er) {
            common.infoMsg("${nodeName} not present on ${kvm}")
        }
    }
}

/**
 * Test if there are any minions to target
 * @param saltId Salt Connection object or pepperEnv (the command will be sent using the selected method)
 * @param target Target to test
 * @return bool indicating if target was succesful
 */

def testTarget(saltId, target) {
    return getMinions(saltId, target).size() > 0
}

/**
 * Generates node key using key.gen_accept call
 * @param saltId Salt Connection object or pepperEnv (the command will be sent using the selected method)
 * @param target Key generating target
 * @param host Key generating host
 * @param keysize generated key size (optional, default 4096)
 * @return output of salt command
 */
def generateNodeKey(saltId, target, host, keysize = 4096) {
    return runSaltCommand(saltId, 'wheel', target, 'key.gen_accept', [host], ['keysize': keysize])
}

/**
 * Generates node reclass metadata
 * @param saltId Salt Connection object or pepperEnv (the command will be sent using the selected method)
 * @param target Metadata generating target
 * @param host Metadata generating host
 * @param classes Reclass classes
 * @param parameters Reclass parameters
 * @return output of salt command
 */
def generateNodeMetadata(saltId, target, host, classes, parameters) {
    return runSaltCommand(saltId, 'local', target, 'reclass.node_create', [host, '_generated'], ['classes': classes, 'parameters': parameters])
}

/**
 * Run salt orchestrate on given targets
 * @param saltId Salt Connection object or pepperEnv (the command will be sent using the selected method)
 * @param target Orchestration target
 * @param orchestrate Salt orchestrate params
 * @param kwargs Salt orchestrate params
 * @return output of salt command
 */
def orchestrateSystem(saltId, target, orchestrate=[], kwargs = null) {
    //Since the runSaltCommand uses "arg" (singular) for "runner" client this won`t work correctly on old salt 2016
    //cause this version of salt used "args" (plural) for "runner" client, see following link for reference:
    //https://github.com/saltstack/salt/pull/32938
    def common = new com.mirantis.mk.Common()
    def result = runSaltCommand(saltId, 'runner', target, 'state.orchestrate', true, orchestrate, kwargs, 7200, 7200)
        if(result != null){
            if(result['return']){
                def retcode = result['return'][0].get('retcode')
                if (retcode != 0) {
                    throw new Exception("Orchestration state failed while running: "+orchestrate)
                }else{
                    common.infoMsg("Orchestrate state "+orchestrate+" succeeded")
                }
            }else{
                common.errorMsg("Salt result has no return attribute! Result: ${result}")
            }
        }else{
            common.errorMsg("Cannot check salt result, given result is null")
        }
}

/**
 * Run salt pre or post orchestrate tasks
 *
 * @param  saltId       Salt Connection object or pepperEnv (the command will be sent using the selected method)
 * @param  pillar_tree  Reclass pillar that has orchestrate pillar for desired stage
 * @param  extra_tgt    Extra targets for compound
 *
 * @return              output of salt command
 */
def orchestratePrePost(saltId, pillar_tree, extra_tgt = '') {

    def common = new com.mirantis.mk.Common()
    def salt = new com.mirantis.mk.Salt()
    def compound = 'I@' + pillar_tree + " " + extra_tgt

    common.infoMsg("Refreshing pillars")
    runSaltProcessStep(saltId, '*', 'saltutil.refresh_pillar', [], null, true)

    common.infoMsg("Looking for orchestrate pillars")
    if (salt.testTarget(saltId, compound)) {
        for ( node in salt.getMinionsSorted(saltId, compound) ) {
            def pillar = salt.getPillar(saltId, node, pillar_tree)
            if ( !pillar['return'].isEmpty() ) {
                for ( orch_id in pillar['return'][0].values() ) {
                    def orchestrator = orch_id.values()['orchestrator']
                    def orch_enabled = orch_id.values()['enabled']
                    if ( orch_enabled ) {
                        common.infoMsg("Orchestrating: ${orchestrator}")
                        salt.printSaltCommandResult(salt.orchestrateSystem(saltId, ['expression': node], [orchestrator]))
                    }
                }
            }
        }
    }
}

/**
 * Run salt process step
 * @param saltId Salt Connection object or pepperEnv (the command will be sent using the selected method)
 * @param tgt Salt process step target
 * @param fun Salt process step function
 * @param arg process step arguments (optional, default [])
 * @param batch salt batch parameter integer or string with percents (optional, default null - disable batch)
 * @param output print output (optional, default true)
 * @param timeout  Additional argument salt api timeout
 * @return output of salt command
 */
def runSaltProcessStep(saltId, tgt, fun, arg = [], batch = null, output = true, timeout = -1, kwargs = null) {
    def common = new com.mirantis.mk.Common()
    def salt = new com.mirantis.mk.Salt()
    def out

    common.infoMsg("Running step ${fun} ${arg} on ${tgt}")

    if (batch == true) {
        out = runSaltCommand(saltId, 'local_batch', ['expression': tgt, 'type': 'compound'], fun, String.valueOf(batch), arg, kwargs, timeout)
    } else {
        out = runSaltCommand(saltId, 'local', ['expression': tgt, 'type': 'compound'], fun, batch, arg, kwargs, timeout)
    }

    if (output == true) {
        salt.printSaltCommandResult(out)
    }
    return out
}

/**
 * Check result for errors and throw exception if any found
 *
 * @param result    Parsed response of Salt API
 * @param failOnError Do you want to throw exception if salt-call fails (optional, default true)
 * @param printResults Do you want to print salt results (optional, default true)
 * @param printOnlyChanges If true (default), print only changed resources
 * @param disableAskOnError Flag for disabling ASK_ON_ERROR feature (optional, default false)
 */
def checkResult(result, failOnError = true, printResults = true, printOnlyChanges = true, disableAskOnError = false) {
    def common = new com.mirantis.mk.Common()
    if(result != null){
        if(result['return']){
            for (int i=0;i<result['return'].size();i++) {
                def entry = result['return'][i]
                if (!entry) {
                    if (failOnError) {
                        throw new Exception("Salt API returned empty response: ${result}")
                    } else {
                        common.errorMsg("Salt API returned empty response: ${result}")
                    }
                }
                for (int j=0;j<entry.size();j++) {
                    def nodeKey = entry.keySet()[j]
                    def node=entry[nodeKey]
                    def outputResources = []
                    def errorResources = []
                    common.infoMsg("Node ${nodeKey} changes:")
                    if(node instanceof Map || node instanceof List){
                        for (int k=0;k<node.size();k++) {
                            def resource;
                            def resKey;
                            if(node instanceof Map){
                                resKey = node.keySet()[k]
                                if (resKey == "retcode")
                                    continue
                            }else if(node instanceof List){
                                resKey = k
                            }
                            resource = node[resKey]
                           // print
                            if(printResults){
                                if(resource instanceof Map && resource.keySet().contains("result")){
                                    //clean unnesaccary fields
                                    if(resource.keySet().contains("__run_num__")){
                                        resource.remove("__run_num__")
                                    }
                                    if(resource.keySet().contains("__id__")){
                                        resource.remove("__id__")
                                    }
                                    if(resource.keySet().contains("pchanges")){
                                        resource.remove("pchanges")
                                    }
                                    if(!resource["result"] || (resource["result"] instanceof String && resource["result"] != "true")){
                                        if(resource["result"] != null){
                                            outputResources.add(String.format("Resource: %s\n\u001B[31m%s\u001B[0m", resKey, common.prettify(resource)))
                                        }else{
                                            outputResources.add(String.format("Resource: %s\n\u001B[33m%s\u001B[0m", resKey, common.prettify(resource)))
                                        }
                                    }else{
                                        if(!printOnlyChanges || resource.changes.size() > 0){
                                            outputResources.add(String.format("Resource: %s\n\u001B[32m%s\u001B[0m", resKey, common.prettify(resource)))
                                        }
                                    }
                                }else{
                                    outputResources.add(String.format("Resource: %s\n\u001B[36m%s\u001B[0m", resKey, common.prettify(resource)))
                                }
                            }
                            common.debugMsg("checkResult: checking resource: ${resource}")
                            if(resource instanceof String || (resource["result"] != null && !resource["result"]) || (resource["result"] instanceof String && resource["result"] == "false")){
                                errorResources.add(resource)
                            }
                        }
                    }else if(node!=null && node!=""){
                        outputResources.add(String.format("Resource: %s\n\u001B[36m%s\u001B[0m", nodeKey, common.prettify(node)))
                    }
                    if(printResults && !outputResources.isEmpty()){
                        println outputResources.stream().collect(Collectors.joining("\n"))
                    }
                    if(!errorResources.isEmpty()){
                        for(resource in errorResources){
                            def prettyResource = common.prettify(resource)
                            if (!disableAskOnError && env["ASK_ON_ERROR"] && env["ASK_ON_ERROR"] == "true") {
                                timeout(time:1, unit:'HOURS') {
                                   input message: "False result on ${nodeKey} found, resource ${prettyResource}. \nDo you want to continue?"
                                }
                            } else {
                                def errorMsg = "Salt state on node ${nodeKey} failed. Resource: ${prettyResource}"
                                if (failOnError) {
                                    throw new Exception(errorMsg)
                                } else {
                                    common.errorMsg(errorMsg)
                                }
                            }
                        }
                    }
                }
            }
        }else{
            common.errorMsg("Salt result hasn't return attribute! Result: ${result}")
        }
    }else{
        common.errorMsg("Cannot check salt result, given result is null")
    }
}

/**
* Parse salt API output to check minion restart and wait some time to be sure minion is up.
* See https://mirantis.jira.com/browse/PROD-16258 for more details
* TODO: change sleep to more tricky procedure.
*
* @param result    Parsed response of Salt API
*/
def waitForMinion(result, minionRestartWaitTimeout=10) {
    def common = new com.mirantis.mk.Common()
    //In order to prevent multiple sleeps use bool variable to catch restart for any minion.
    def isMinionRestarted = false
    if(result != null){
        if(result['return']){
            for (int i=0;i<result['return'].size();i++) {
                def entry = result['return'][i]
                // exit in case of empty response.
                if (!entry) {
                    return
                }
                // Loop for nodes
                for (int j=0;j<entry.size();j++) {
                    def nodeKey = entry.keySet()[j]
                    def node=entry[nodeKey]
                    if(node instanceof Map || node instanceof List){
                        // Loop for node resources
                        for (int k=0;k<node.size();k++) {
                            def resource;
                            def resKey;
                            if(node instanceof Map){
                                resKey = node.keySet()[k]
                            }else if(node instanceof List){
                                resKey = k
                            }
                            resource = node[resKey]
                            // try to find if salt_minion service was restarted
                            if(resKey instanceof String && resKey.contains("salt_minion_service_restart") && resource instanceof Map && resource.keySet().contains("result")){
                                if((resource["result"] instanceof Boolean && resource["result"]) || (resource["result"] instanceof String && resource["result"] == "true")){
                                    if(resource.changes.size() > 0){
                                        isMinionRestarted=true
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
    if (isMinionRestarted){
      common.infoMsg("Salt minion service restart detected. Sleep ${minionRestartWaitTimeout} seconds to wait minion restart")
        sleep(minionRestartWaitTimeout)
    }
}

/**
 * Print salt command run results in human-friendly form
 *
 * @param result        Parsed response of Salt API
 */
def printSaltCommandResult(result) {
    def common = new com.mirantis.mk.Common()
    if(result != null){
        if(result['return']){
            for (int i=0; i<result['return'].size(); i++) {
                def entry = result['return'][i]
                for (int j=0; j<entry.size(); j++) {
                    common.debugMsg("printSaltCommandResult: printing salt command entry: ${entry}")
                    def nodeKey = entry.keySet()[j]
                    def node=entry[nodeKey]
                    common.infoMsg(String.format("Node %s changes:\n%s",nodeKey, common.prettify(node)))
                }
            }
        }else{
            common.errorMsg("Salt result hasn't return attribute! Result: ${result}")
        }
    }else{
        common.errorMsg("Cannot print salt command result, given result is null")
    }
}


/**
 * Return content of file target
 *
 * @param saltId    Salt Connection object or pepperEnv (the command will be sent using the selected method)
 * @param target    Compound target (should target only one host)
 * @param file      File path to read (/etc/hosts for example)
 */

def getFileContent(saltId, target, file, checkResponse = true, batch=null, output = true, saltArgs = []) {
    result = cmdRun(saltId, target, "cat ${file}", checkResponse, batch, output, saltArgs)
    return result['return'][0].values()[0].replaceAll('Salt command execution success','')
}

/**
 * Set override parameters in Salt cluster metadata
 *
 * @param saltId         Salt Connection object or pepperEnv (the command will be sent using the selected method)
 * @param salt_overrides YAML formatted string containing key: value, one per line
 * @param reclass_dir    Directory where Reclass git repo is located
 * @param extra_tgt      Extra targets for compound
 */

def setSaltOverrides(saltId, salt_overrides, reclass_dir="/srv/salt/reclass", extra_tgt = '') {
    def common = new com.mirantis.mk.Common()
    def salt_overrides_map = readYaml text: salt_overrides
    for (entry in common.entries(salt_overrides_map)) {
         def key = entry[0]
         def value = entry[1]

         common.debugMsg("Set salt override ${key}=${value}")
         runSaltProcessStep(saltId, "I@salt:master ${extra_tgt}", 'reclass.cluster_meta_set', [key, value], false)
    }
    runSaltProcessStep(saltId, "I@salt:master ${extra_tgt}", 'cmd.run', ["git -C ${reclass_dir} update-index --skip-worktree classes/cluster/overrides.yml"])
}

/**
* Execute salt commands via salt-api with
* CLI client salt-pepper
*
* @param data   Salt command map
* @param venv   Path to virtualenv with
*/

def runPepperCommand(data, venv)   {
    def common = new com.mirantis.mk.Common()
    def python = new com.mirantis.mk.Python()
    def dataStr = new groovy.json.JsonBuilder(data).toString()

    def pepperCmdFile = "${venv}/pepper-cmd.json"
    writeFile file: pepperCmdFile, text: dataStr
    def pepperCmd = "pepper -c ${venv}/pepperrc --make-token -x ${venv}/.peppercache --json-file ${pepperCmdFile}"

    if (venv) {
        output = python.runVirtualenvCommand(venv, pepperCmd, true)
    } else {
        echo("[Command]: ${pepperCmd}")
        output = sh (
            script: pepperCmd,
            returnStdout: true
        ).trim()
    }

    def outputObj
    try {
       outputObj = new groovy.json.JsonSlurperClassic().parseText(output)
    } catch(Exception e) {
       common.errorMsg("Parsing Salt API JSON response failed! Response: " + output)
       throw e
    }
    return outputObj
}
