package com.mirantis.mcp

import static org.yaml.snakeyaml.DumperOptions.FlowStyle.BLOCK
import java.util.zip.GZIPInputStream
import java.util.zip.GZIPOutputStream

@Grab(group='org.yaml', module='snakeyaml', version='1.17')
import org.yaml.snakeyaml.Yaml
import org.yaml.snakeyaml.DumperOptions

/**
 * https://issues.jenkins-ci.org/browse/JENKINS-26481
 * fix groovy List.collect()
 **/
@NonCPS
def constructString(ArrayList options, String keyOption, String separator = ' ') {
    return options.collect { keyOption + it }.join(separator).replaceAll('\n', '')
}

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

/**
 * Run tox with or without specified environment
 * @param env String, name of environment
 */
def runTox(String env = null) {
  if (env) {
    sh "tox -v -e ${env}"
  } else {
    sh 'tox -v'
  }
}

/**
 * Convert YAML document to Map object
 * @param data YAML string
 */
@NonCPS
def loadYAML(String data) {
  def yaml = new Yaml()
  return yaml.load(data)
}

/**
 * Convert Map object to YAML string
 * @param map Map object
 */
@NonCPS
def dumpYAML(Map map) {
  DumperOptions options = new DumperOptions()
  options.setPrettyFlow(true)
  options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK)
  def yaml = new Yaml(options)
  return yaml.dump(map)
}

/**
 * Render jinja template
 * @param templateVars String, A dict, a dict subclass, json or some keyword arguments
 * @param templateFile String, jinja template file path
 * @param resultFile String, result/generate file path
 *
 * Usage example:
 *
 * def common = new com.mirantis.mcp.Common()
 * common.renderJinjaTemplate(
 *     "${NODE_JSON}",
 *     "${WORKSPACE}/inventory/inventory.cfg",
 *     "${WORKSPACE}/inventory/inventory.cfg")
 * where NODE_JSON= data in json format
 */
def renderJinjaTemplate(String templateVars, String templateFile, String resultFile) {

  sh """
    python -c "
import sys
import jinja2
from jinja2 import Template

# Useful for very coarse version differentiation.
PY2 = sys.version_info[0] == 2
PY3 = sys.version_info[0] == 3
PY34 = sys.version_info[0:2] >= (3, 4)

if PY3:
    string_types = str,
else:
    string_types = basestring


def to_bool(a):
    ''' return a bool for the arg '''
    if a is None or type(a) == bool:
        return a
    if isinstance(a, string_types):
        a = a.lower()
    if a in ['yes', 'on', '1', 'true', 1]:
        return True
    else:
        return False


def generate(templateVars, templateFile, resultFile):
    templateLoader = jinja2.FileSystemLoader(searchpath='/')
    templateEnv = jinja2.Environment(loader=templateLoader)
    templateEnv.filters['bool'] = to_bool
    template = templateEnv.get_template(templateFile)
    outputText = template.render(templateVars)
    Template(outputText).stream().dump(resultFile)

generate(${templateVars}, '${templateFile}', '${resultFile}')
"
  cat ${resultFile}
  """
}

/**
 * Run function on k8s cluster
 *
 * @param config LinkedHashMap
 *        config includes next parameters:
 *          - label, pod label
 *          - function, code that should be run on k8s cluster
 *          - jnlpImg, jnlp slave image
 *          - slaveImg, slave image
 *
 * Usage example:
 *
 * def runFunc = new com.mirantis.mcp.Common()
 * runFunc.runOnKubernetes ([
 *   function : this.&buildCalicoContainers,
 *   jnlpImg: 'docker-prod-virtual.docker.mirantis.net/mirantis/jenkins-slave-images/jnlp-slave:latest',
 *   slaveImg : 'sandbox-docker-dev-local.docker.mirantis.net/skulanov/jenkins-slave-images/calico-slave:1'
 * ])
 * // promotion example. In case of promotion we need only jnlp container
 * def runFunc = new com.mirantis.mcp.Common()
 * runFunc.runOnKubernetes ([
 *   jnlpImg: 'docker-prod-virtual.docker.mirantis.net/mirantis/jenkins-slave-images/jnlp-slave:latest',
 *   function : this.&promote_artifacts
 * ])
 */
def runOnKubernetes(LinkedHashMap config) {


  def jenkinsSlaveImg = config.get('slaveImg', 'none')
  def jnlpSlaveImg = config.get('jnlpImg', 'none')
  def lbl = config.get('label', "buildpod.${env.JOB_NAME}.${env.BUILD_NUMBER}".replace('-', '_').replace('/', '_'))
  def toRun = config.get('function', 'none')

  if (jnlpSlaveImg == 'none') {
    error('jnlp Slave image MUST be defined')
  }

  if (toRun == 'none'){
    error('Code that should be run on k8s MUST be passed along with function parameter')
  }

  if (jenkinsSlaveImg == 'none'){
    // we are running jnlp container only, since no jenkinsSlaveImg is specified, so
    // we are in promotion mode
    podTemplate(label: lbl,
      containers: [
          containerTemplate(
              name: 'jnlp',
              image: jnlpSlaveImg,
              args: '${computer.jnlpmac} ${computer.name}'
          )
      ],
      ) {
      node(lbl){
        container('jnlp') {
          toRun()
        }
      }
    }

  } else {
    podTemplate(label: lbl,
      containers: [
          containerTemplate(
              name: 'jnlp',
              image: jnlpSlaveImg,
              args: '${computer.jnlpmac} ${computer.name}'
          ),
          containerTemplate(
              name: 'k8s-slave',
              image: jenkinsSlaveImg,
              alwaysPullImage: false,
              ttyEnabled: true,
              privileged: true
          )
      ],
      ) {
      node(lbl){
        container('k8s-slave') {
          return toRun()
        }
      }
    }
  } //else

}

/**
 * Compress a string with Gzip and encode result with Base64 encoding,
 * useful for wire transfer of large text data over text-based protocols like HTTP
 * @param s string to encode
 * @return base64-encoded gzipped string
*/
def zipBase64(String s){
    def targetStream = new ByteArrayOutputStream()
    def zipStream = new GZIPOutputStream(targetStream)
    zipStream.write(s.getBytes('UTF-8'))
    zipStream.close()
    def zippedBytes = targetStream.toByteArray()
    targetStream.close()
    return zippedBytes.encodeBase64().toString()
}

/**
 * De-compress a base64-encoded gzipped string, reverts result of zipBase64
 * @param compressed base64-endcoded gzipped string
 * @return decoded decompressed string
*/
def unzipBase64(String compressed){
    def inflaterStream = new GZIPInputStream(new ByteArrayInputStream(compressed.decodeBase64()))
    def uncompressedStr = inflaterStream.getText('UTF-8')
    return uncompressedStr
}
