package com.mirantis.mcp

/*
  Example usage:

  def ccpCiCd = new com.mirantis.mcp.CCPCICD().newInstance(this, env)

  ccpCiCd.applyPipelineParameters()

  ccpCiCd.fetchEnvConfiguration()
  ccpCiCd.parametrizeConfig()

  ccpCiCd.build()
  ccpCiCd.deploy()
  ccpCiCd.cleanup()
*/

/*
  Since groovy-cps demands that local variables may be serialized,
  any locally defined classes must also be serializable

  More details: https://issues.jenkins-ci.org/browse/JENKINS-32213
*/

public class ccpCICD implements Serializable {

  /*
    Endless loop in DefaultInvoker.getProperty when accessing field
    via getter/setter without @

    This issue fixed in groovy pipeline plugin 2.25

    More details https://issues.jenkins-ci.org/browse/JENKINS-31484
  */

  /*
    nodeContext - is a context of which node the job is executed
    through this context, CCPCICD class able to use
    dir() writeFile() sh() and other workflow basic steps

    See more https://jenkins.io/doc/pipeline/steps/workflow-basic-steps/

    nodeContext must be passed in class constructor
  */
  def nodeContext = null

  /*
    Job parameters are accessed through environment
  */
  def env = null

  /*
    Directory where stored environment configuration
  */
  def envConfigurationPath = null
  def File envConfiguration = null

  /*
    Path to entry point yaml in environment directory
  */
  def ccpConfigPath = null

  def File virtualEnv = null // Currently not supported

  def URI configurationRepo = null

  /*
    parsed `ccp config dump` output
  */

  def Map ccpConfig = null

  /*
    Part of ccp parameters which will be overwritten by job
    parametrizeConfig() method

  */
  def Map ciConfig = [
    'registry'    : [
      'address'   : null,
      'username'  : null,
      'password'  : null,
    ],
    'kubernetes'  : [
      'namespace' : 'ccp',
      'server'    : null,
      'insecure'  : true,
      'username'  : null,
      'password'  : null
    ],
    'repositories': [
      'path'      : null
    ]

  ]

  // Using loadYAML and dumpYAML from common library
  def common = new com.mirantis.mcp.Common()

  // default CCP repo (using in upgrade)
  def URI ccpSource = new URI('git+https://gerrit.mcp.mirantis.net/ccp/fuel-ccp')

  def public void setConfURL(URI confURI) {
    if (confURI == null) {
      throw new IllegalArgumentException('Invalid argument')
    }
    this.@configurationRepo = confURI
  }

  def public URI getConfURL() {
    return this.@configurationRepo
  }

  /*
    According JENKINS-31314 constructor can be used only for assignments properties
    More details: https://issues.jenkins-ci.org/browse/JENKINS-31314
  */
  def public ccpCICD(nodeContext, env) {
    this.@nodeContext = nodeContext
    this.@env = env
  }

  /*
    Transform jenkins job arguments to ccp configuration
    Parameters can be overriden with customParameters Map

    Example usage:
    applyPipelineParameters([

      'images': [
        'image_specs': [
            'etcd': [
                'tag': '41a45e5a9db5'
            ]
        ]
      ]

    ])

  */

  def public void applyPipelineParameters(Map customParameters = null) {

    if (this.@env.CONF_GERRIT_URL != null) {
      this.setConfURL(new URI(this.@env.CONF_GERRIT_URL))
    }


    if (this.@env.CONF_ENTRYPOINT != null) {
      this.setCcpConfigPath(new File(this.@env.CONF_ENTRYPOINT))
    }

    if (this.@env.KUBERNETES_URL != null) {
      this.setKubernetesURL(new URI(this.@env.KUBERNETES_URL), this.@env.CREDENTIALS_ID)
    } else {
      this.@ciConfig.remove('kubernetes')
    }

    if (this.@env.DOCKER_REGISTRY != null) {
      this.setRegistry(new URI(this.@env.DOCKER_REGISTRY), this.env.DOCKER_REGISTRY_CREDENTIAL_ID ? this.env.DOCKER_REGISTRY_CREDENTIAL_ID : 'artifactory')
    } else {
      this.@ciConfig.remove('registry')
    }


    this.@ciConfig['repositories']['path'] = env.WORKSPACE + '/repos'

    if (customParameters != null) {
      this.@ciConfig = this.@ciConfig + customParameters
    }
  }

  def public File getCcpConfigPath() {
    return this.@ccpConfigPath
  }

  def public void setCcpConfigPath(File configPath) {
    this.@ccpConfigPath = configPath
  }

  /*
    Set k8s endpoint and credentials

    Example usage:
      this.setKubernetesURL(new URI('https://host:443'), 'kubernetes-api')
  */

  def public void setKubernetesURL(URI kubernetesURL, String credentialId) {
    if (credentialId != null) {
      this.@nodeContext.withCredentials([
        [
          $class           : 'UsernamePasswordMultiBinding',
          credentialsId    :  credentialId,
          passwordVariable : 'K8S_PASSWORD',
          usernameVariable : 'K8S_USERNAME'
        ]
      ]) {
        this.@ciConfig['kubernetes']['username'] = env.K8S_USERNAME
        this.@ciConfig['kubernetes']['password'] = env.K8S_PASSWORD
      }
    }

    /*
    //TODO(sryabin) properly parse return from getUserInfo()
    if (kubernetesURL.getUserInfo()) {
        this.@ciConfig['kubernetes']['username'] = kubernetesURL.getUserInfo()
    }
    */

    this.@ciConfig['kubernetes']['server'] = kubernetesURL.toString()
  }

  def public void setRegistry(String registryEndpoint, String credentialId) {
    if (credentialId) {
      this.@nodeContext.withCredentials([
        [
          $class           : 'UsernamePasswordMultiBinding',
          credentialsId    :  credentialId,
          passwordVariable : 'REGISTRY_PASSWORD',
          usernameVariable : 'REGISTRY_USERNAME'
        ]
      ]) {
        this.@ciConfig['registry']['username'] = env.REGISTRY_USERNAME
        this.@ciConfig['registry']['password'] = env.REGISTRY_PASSWORD
      }
    } else {
      this.@ciConfig['registry'].remove('username')
      this.@ciConfig['registry'].remove('password')
    }

    this.@ciConfig['registry']['address'] = registryEndpoint;
  }

  def public setEnvConfigurationDir() {
    // TODO(sryabin) cleanup this dir in desctructor
    this.@envConfigurationPath = File.createTempDir(this.@env.WORKSPACE + '/envConfiguration', 'ccpci')
  }

  def public File getEnvConfigurationDir() {
    return this.@envConfigurationPath
  }



  def public File fetchEnvConfiguration() {

    def gitTools = new com.mirantis.mcp.Git()

    this.setEnvConfigurationDir()

    gitTools.gitSSHCheckout ([
        credentialsId : this.@env.CONF_GERRIT_CREDENTIAL_ID,
        branch : "master",
        host : this.getConfURL().getHost(),
        port : this.getConfURL().getPort(),
        project: this.getConfURL().getPath(),
        targetDir: this.getEnvConfigurationDir().toString()
    ])

    return this.getEnvConfigurationDir()
  }

  def public String configDump() {
    return this.ccpExecute('config dump')
  }

  /*
    merge ccp configuration from repo and custom parameters from job arguments
  */
  def public Map parametrizeConfig() {
    this.fetchEnvConfiguration()
    this.@ccpConfig = this.@common.loadYAML(this.configDump())
    this.setCcpConfigPath(new File('parametrized.yaml'));
    this.@nodeContext.writeFile file: this.getEnvConfigurationDir().toString() + '/' + this.getCcpConfigPath().toString(), \
      text: this.@common.dumpYAML(this.@ccpConfig + this.@ciConfig)
  }

  def public Map getConfig() {
    return this.@ccpConfig
  }


  /*
    Example usage:
      ci.ccpExecute('config dump')
  */
  def public String ccpExecute(args) {
    // TODO(sryabin) pass custom args from class property, like debug
    def String output = null;
    this.@nodeContext.dir(this.getEnvConfigurationDir().toString()) {
      output = this.@nodeContext.sh(
        script: "PYTHONWARNINGS='ignore:Unverified HTTPS request' ccp --config-file " + this.getCcpConfigPath().toString() +  " ${args}",
        returnStdout: true
      )
    }
    return output
  }

  /*
    Update fuel-ccp

    @param virtualEnv File, path to python virtual environment, currently not supported
    @param source URI, if not present, use upstream
    @param upgradePip Boolean, upgrade pip if required

    Usage example:
      upgradeCcp(new File('/home/ubuntu/.venv'), new URI('http://github.com/openstack/fuel-ccp'))
  */
  def public void upgradeCcp(File virtualEnv = null, URI source, Boolean upgradePip = false) {
    if (virtualEnv) {
      throw new UnsupportedOperationException('Python virtual environments not implemented')
    }

    try {
      def output = this.@nodeContext.sh(
        script: 'pip install --user --upgrade ' + ((source != null) ? source : this.@ccpSource).toString(),
        returnStdout: true
      )
    } catch (e) {
      // TODO(sryabin) catch in stderr "You should consider upgrading via the 'pip install --upgrade pip' command."
      if (upgradePip == true) {
        this.@nodeContext.sh(
          script: 'pip install --upgrade pip',
          returnStdout: true
        )
      }
      // FIXME(sryabin) infinity loop
      //this.upgradeCcp(virtualEnv, source, false)
    }
  }
  def public void upgradeCcp() {
    this.upgradeCcp(null, null, true)
  }

  def build() {
    //TODO(sryabin) implement build -c functionality
    return this.ccpExecute('build')
  }

  def deploy() {
    //TODO(sryabin) implement build -c functionality
    return this.ccpExecute('deploy')
  }

  def cleanup() {
    try {
      this.ccpExecute('cleanup')
    } catch (err) {
      this.ccpExecute('cleanup --skip-os-cleanup')
    }
  }

  def fetch() {
    // TODO(sryabin) implement fetch -f functioanlity
    return this.ccpExecute('fetch')
  }
}

/*
  Workaround for scope limitation, and
    org.jenkinsci.plugins.scriptsecurity.sandbox.RejectedAccessException: unclassified new

  def ccpCiCd = new com.mirantis.mcp.CCPCICD()
  def CCPCICD ci = new ccpCiCd.ccpCICD(this, env) return no such CCPCICD()

  Example usage:
    def ccpCiCd = new com.mirantis.mcp.CCPCICD().newInstance(this, env)

*/

def newInstance(nodeContext, env) {
  return new ccpCICD(nodeContext,env)
}
