/*
 * Copyright 2012 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import org.opencord.gradle.rules.*
import org.yaml.snakeyaml.Yaml
import org.yaml.snakeyaml.DumperOptions

allprojects {
    apply plugin: 'base'
    apply plugin: 'de.gesellix.docker'
    //apply plugin: 'com.tmiyamon.config'

    docker {
        // dockerHost = System.env.DOCKER_HOST ?: 'unix:///var/run/docker.sock'
        // dockerHost = System.env.DOCKER_HOST ?: 'https://192.168.99.100:2376'
        // certPath = System.getProperty('docker.cert.path') ?: "${System.getProperty('user.home')}/.docker/machine/machines/default"
        // authConfigPlain = [
        //   "username"       : "joe",
        //   "password"       : "some-pw-as-needed",
        //   "email"          : "joe@acme.com",
        //   "serveraddress"  : "https://index.docker.io/v1/"
        //  ]
    }
}

def getCordAppVersion = { ->
    def StdOut = new ByteArrayOutputStream()
    exec {
        commandLine "xpath", "-q", "-e", "project/version/text()", "../../onos-apps/apps/pom.xml"
        standardOutput = StdOut
    }
    return StdOut.toString().trim()
}

ext {

    // Upstream registry to simplify filling out the comps table below
    upstreamReg = project.hasProperty('upstreamReg') ? project.getProperty('upstreamReg') : 'docker.io'

    // Deployment target config file (yaml format); this can be overwritten from the command line
    // using the -PdeployConfig=<file-path> syntax.
    deployConfig = project.hasProperty('deployConfig') ? project.getProperty('deployConfig') : './config/default.yml'

    println "Using deployment config: $deployConfig"
    File configFile = new File(deployConfig)
    def yaml = new Yaml()
    config = yaml.load(configFile.newReader())

    // Target registry to be used to publish docker images needed for deployment
    targetReg = project.hasProperty('targetReg')
        ? project.getProperty('targetReg')
        : config.docker && config.docker.registry
            ? config.docker.registry
            : config.seedServer.ip
                ? config.seedServer.ip + ":5000"
                : 'localhost:5000'

    // The tag used to tag the docker images push to the target registry
    targetTag = project.hasProperty('targetTag')
        ? project.getProperty('targetTag')
        : config.docker && config.docker.imageVersion
            ? config.docker.imageVersion
            : 'candidate'

    println "targetReg = $targetReg, targetTag = $targetTag"


    // Version of the CORD apps to load into ONOS
    cordAppVersion = project.hasProperty('cordAppVersion')
        ? project.getProperty('cordAppVersion')
        : getCordAppVersion()

    println "CORD app version: $cordAppVersion"

    // Component table
    comps = [
    ]
}

task copyAnsibleInventory(type: Copy) {
  from 'inventory/templates/single-prod'
    into 'inventory'
    expand([
        prod: config.seedServer.ip,
    ])
}

task writeYamlConfig {
  def outvar = config.seedServer
  def outfilename = "genconfig/deployconf.yml"

  DumperOptions options = new DumperOptions()

  options.setExplicitStart(true);
  options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK)
  options.setPrettyFlow(true);
  options.setIndent(2);

  def yaml = new Yaml(options)
  Writer outfile = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outfilename), "utf-8"))

  yaml.dump(outvar, outfile)

  outfile.close()
}

// ------------- PlaceHolders ----------------

task prime {
    // TODO this is a place-holder.
}

// ---------------- Useful tasks ----------------

task fetch << {
    logger.info 'Platform install has nothing to fetch'
}

task buildImages << {
    logger.info 'Platform install has nothing to build'
}

task publishImages {
    comps.each { name, spec -> if (spec.type == 'image') { dependsOn "publish" + name } }
}

task publish {
    dependsOn publishImages
}

tasks.addRule(new DockerFetchRule(project))
tasks.addRule(new DockerPublishRule(project))
tasks.addRule(new DockerTagRule(project))
tasks.addRule(new GitSubmoduleUpdateRule(project))

task prepPlatform(type: Exec) {
    dependsOn copyAnsibleInventory
    dependsOn writeYamlConfig

    executable = "ansible-playbook"
    args = ["-i", "inventory/single-prod", "--extra-vars", "@../genconfig/deployconf.yml", "cord-prep-platform.yml"]
}

task deployOpenStack (type: Exec) {
    executable = "ansible-playbook"
    args = ["-i", "inventory/single-prod", "--extra-vars", "@../genconfig/deployconf.yml", "cord-deploy-openstack.yml"]
}

task deployONOS (type: Exec) {
    executable = "ansible-playbook"
    args = ["-i", "inventory/single-prod", "--extra-vars", "@../genconfig/deployconf.yml", "cord-deploy-onos.yml"]
}

task deployXOS (type: Exec) {

    executable = "ansible-playbook"
    args = ["-i", "inventory/single-prod", "--extra-vars", "@../genconfig/deployconf.yml", "cord-deploy-xos.yml"]
}

task setupAutomation (type: Exec) {

    executable = "ansible-playbook"
    args = ["-i", "inventory/single-prod", "--extra-vars", "@../genconfig/deployconf.yml", "cord-automation.yml"]
}

deployOpenStack.mustRunAfter prepPlatform
deployONOS.mustRunAfter deployOpenStack
deployXOS.mustRunAfter deployONOS
setupAutomation.mustRunAfter deployXOS

task deployPlatform {
     dependsOn prepPlatform
     dependsOn deployOpenStack
     dependsOn deployONOS
     dependsOn deployXOS
     dependsOn setupAutomation
}

task postDeployTests (type: Exec) {

    executable = "ansible-playbook"
    args = ["-i", "inventory/single-prod", "--extra-vars", "@../genconfig/deployconf.yml", "cord-post-deploy-playbook.yml"]
}

