/*
 * 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

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/"
        //  ]
    }
}

ext {

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

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

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

    // 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'

    comps = [
            'consul': [
                    'type':     'image',
                    'upstream': upstreamReg,
                    'name':     'consul',
                    'digest':   'sha256:0dc990ff3c44d5b5395475bcc5ebdae4fc8b67f69e17942a8b9793b3df74d290'
            ]
    ]
}

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

// Switch Configuration Image

def getBuildTimestamp() {
    def cal = Calendar.getInstance(TimeZone.getTimeZone("UTC"))
    def date = cal.getTime()
    def formattedDate = date.format("yyyy-MM-dd'T'HH:mm:ss.ss'Z'")
    return formattedDate
}

def getCommitHash = { ->
    def hashStdOut = new ByteArrayOutputStream()
    exec {
        commandLine "git", "rev-parse", "HEAD"
        standardOutput = hashStdOut
    }
    return hashStdOut.toString().trim()
}

def getBranchName = { ->
    def branchStdOut = new ByteArrayOutputStream()
    exec {
        commandLine "git", "rev-parse", "--abbrev-ref", "HEAD"
        standardOutput = branchStdOut
    }
    return branchStdOut.toString().trim()
}
 
task buildSwitchqImage(type: Exec) {
    commandLine "docker", 'build', '--label', 'org.label-schema.build-date=' + getBuildTimestamp(), '--label', 'org.label-schema.vcs-ref=' + getCommitHash(), '--label', 'org.label-schema.version=' + getBranchName(), '-t', 'cord-maas-switchq', './switchq'
}

task tagSwitchqImage(type: Exec) {
   dependsOn buildSwitchqImage
   commandLine "docker", 'tag', 'cord-maas-switchq', "$targetReg/cord-maas-switchq:$targetTag"
}

task publishSwitchqImage(type: Exec) {
    dependsOn tagSwitchqImage
    commandLine "docker", 'push', "$targetReg/cord-maas-switchq:$targetTag"
}

// Bootstrap Image

task buildBootstrapImage(type: Exec) {
    commandLine "docker", 'build', '--label', 'org.label-schema.build-date=' + getBuildTimestamp(), '--label', 'org.label-schema.vcs-ref=' + getCommitHash(), '--label', 'org.label-schema.version=' + getBranchName(), '-t', 'cord-maas-bootstrap', './bootstrap'
}

task tagBootstrapImage(type: Exec) {
   dependsOn buildBootstrapImage
   commandLine "docker", 'tag', 'cord-maas-bootstrap', "$targetReg/cord-maas-bootstrap:$targetTag"
}

task publishBootstrapImage(type: Exec) {
    dependsOn tagBootstrapImage
    commandLine "docker", 'push', "$targetReg/cord-maas-bootstrap:$targetTag"
}

// IP Allocator Image

task buildAllocationImage(type: Exec) {
    commandLine "docker", 'build', '--label', 'org.label-schema.build-date=' + getBuildTimestamp(), '--label', 'org.label-schema.vcs-ref=' + getCommitHash(), '--label', 'org.label-schema.version=' + getBranchName(), '-t', 'cord-ip-allocator', './ip-allocator'
}

task tagAllocationImage(type: Exec) {
   dependsOn buildAllocationImage
   commandLine "docker", 'tag', 'cord-ip-allocator', "$targetReg/cord-ip-allocator:$targetTag"
}

task publishAllocationImage(type: Exec) {
    dependsOn tagAllocationImage
    commandLine "docker", 'push', "$targetReg/cord-ip-allocator:$targetTag"
}

// Provisioner Image

task buildProvisionerImage(type: Exec) {
    commandLine "docker", 'build', '--label', 'org.label-schema.build-date=' + getBuildTimestamp(), '--label', 'org.label-schema.vcs-ref=' + getCommitHash(), '--label', 'org.label-schema.version=' + getBranchName(), '-t', 'cord-provisioner', './provisioner'
}

task tagProvisionerImage(type: Exec) {
   dependsOn buildProvisionerImage
   commandLine "docker", 'tag', 'cord-provisioner', "$targetReg/cord-provisioner:$targetTag"
}

task publishProvisionerImage(type: Exec) {
    dependsOn tagProvisionerImage
    commandLine "docker", 'push', "$targetReg/cord-provisioner:$targetTag"
}

// Config Generator Image

task buildConfigGeneratorImage(type: Exec) {
    commandLine "docker", 'build', '--label', 'org.label-schema.build-date=' + getBuildTimestamp(), '--label', 'org.label-schema.vcs-ref=' + getCommitHash(), '--label', 'org.label-schema.version=' + getBranchName(), '-t', 'config-generator', './config-generator'
}

task tagConfigGeneratorImage(type: Exec) {
   dependsOn buildConfigGeneratorImage
   commandLine "docker", 'tag', 'config-generator', "$targetReg/config-generator:$targetTag"
}

task publishConfigGeneratorImage(type: Exec) {
    dependsOn tagConfigGeneratorImage
    commandLine "docker", 'push', "$targetReg/config-generator:$targetTag"
}

// Automation Image

task buildAutomationImage(type: Exec) {
    commandLine "docker", 'build', '--label', 'org.label-schema.build-date=' + getBuildTimestamp(), '--label', 'org.label-schema.vcs-ref=' + getCommitHash(), '--label', 'org.label-schema.version=' + getBranchName(), '-t', "cord-maas-automation", "-f", "./automation/Dockerfile", "./automation"
}

task tagAutomationImage(type: Exec) {
    dependsOn buildAutomationImage
    commandLine "docker", 'tag', 'cord-maas-automation', "$targetReg/cord-maas-automation:$targetTag"
}

task publishAutomationImage(type: Exec) {
    dependsOn tagAutomationImage
    commandLine "docker", 'push', "$targetReg/cord-maas-automation:$targetTag"
}

// DHCP Harvester Images

task buildHarvesterImage(type: Exec) {
    commandLine "docker", 'build', '--label', 'org.label-schema.build-date=' + getBuildTimestamp(), '--label', 'org.label-schema.vcs-ref=' + getCommitHash(), '--label', 'org.label-schema.version=' + getBranchName(), '-t', "cord-dhcp-harvester", "./harvester"
}

task tagHarvesterImage(type: Exec) {
    dependsOn buildHarvesterImage
    commandLine "docker", 'tag', 'cord-dhcp-harvester', "$targetReg/cord-dhcp-harvester:$targetTag"
}

task publishHarvesterImage(type: Exec) {
    dependsOn tagHarvesterImage
    commandLine "docker", 'push', "$targetReg/cord-dhcp-harvester:$targetTag"
}

// ~~~~~~~~~~~~~~~~~~~ Global tasks ~~~~~~~~~~~~~~~~~~~~~~~

task updateDocker (type: Exec)  {
    commandLine 'sudo', 'utils/enable-remote-docker-registry', "$targetReg"
}

// To be used to fetch upstream binaries, clone repos, etc.
task fetch(type: Exec) {
    // this is where we fetch upstream artifacts that we do not need internet for the build phase"
    // Placeholdr example:
    dependsOn fetchUpstreamImages
    commandLine "docker", "pull", "golang:alpine"
    commandLine "docker", "pull", "python:2.7-alpine"
}

// To be used to generate all needed binaries that need to be present on the target
// as docker images in the local docker runner.
task buildImages {
    dependsOn buildBootstrapImage
    dependsOn buildHarvesterImage
    dependsOn buildAutomationImage
    dependsOn buildAllocationImage
    dependsOn buildProvisionerImage
    dependsOn buildConfigGeneratorImage
    dependsOn buildSwitchqImage
}

task tagImages {
    dependsOn tagBootstrapImage
    dependsOn tagHarvesterImage
    dependsOn tagAutomationImage
    dependsOn tagAllocationImage
    dependsOn tagProvisionerImage
    dependsOn tagConfigGeneratorImage
    dependsOn tagSwitchqImage
}

task publish {
    //FIXME: This works because the upstream project primes the nodes before running this.
    comps.each { name, spec -> if (spec.type == 'image') { dependsOn "publish" + name } }
    dependsOn publishBootstrapImage
    dependsOn publishHarvesterImage
    dependsOn publishAutomationImage
    dependsOn publishAllocationImage
    dependsOn publishProvisionerImage
    dependsOn publishConfigGeneratorImage
    dependsOn publishSwitchqImage
}


// ~~~~~~~~~~~~~~~~~~~ Deployment / Test Tasks  ~~~~~~~~~~~~~~~~~~~~~~~

List.metaClass.asParam = { prefix, sep ->
  if (delegate.size() == 0) {
    ""
  }
  String result = "--" + prefix + "="
  String p = ""
  delegate.each {
    result += p + "${it}"
    p = sep
  }
  result
}

List.metaClass.p = { value, name ->
  if (value != null && value != "") {
      delegate << name + "=" + value
  } else {
      delegate
  }
}

List.metaClass.p = { spec ->
  if (spec != null && spec != "") {
      delegate += spec
  } else {
      delegate
  }
}

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

    executable = "ansible-playbook"
    args = ["-i", config.seedServer.ip + ',']

    if ( config.seedServer.user != null && config.seedServer.user != "" ) {
        args = args << "--user=$config.seedServer.user"
    }

    if ( config.debug ) {
        args = args << "-vvvv"
    }

    def extraVars = []
    if (config.seedServer) {
        extraVars = extraVars.p(config.seedServer.extraVars)
            .p(config.seedServer.password, "ansible_ssh_pass")
            .p(config.seedServer.sudoPassword, "ansible_sudo_pass")
            .p(config.seedServer.fabric_ip, "fabric_ip")
            .p(config.seedServer.management_ip, "management_ip")
            .p(config.seedServer.management_gw, "management_gw")
            .p(config.seedServer.management_bc, "management_bc")
            .p(config.seedServer.management_network, "management_network")
            .p(config.seedServer.management_iface, "management_iface")
            .p(config.seedServer.external_ip, "external_ip")
            .p(config.seedServer.external_gw, "external_gw")
            .p(config.seedServer.external_bc, "external_bc")
            .p(config.seedServer.external_network, "external_network")
            .p(config.seedServer.external_iface, "external_iface")
            .p(config.seedServer.fabric_ip, "fabric_ip")
            .p(config.seedServer.fabric_network, "fabric_network")
            .p(config.seedServer.fabric_iface, "fabric_iface")
            .p(config.seedServer.fabric_iface_spec, "fabric_iface_spec")
            .p(config.seedServer.domain, "domain")
	    .p(config.seedServer.virtualbox_support, "virtualbox_support")
            .p(config.seedServer.power_helper_user, "power_helper_user")
            .p(config.seedServer.power_helper_host, "power_helper_host")
            .p(config.seedServer.port, "ansible_ssh_port")
    }

    if (config.otherServers) {
        extraVars = extraVars.p(config.otherServers.location, "prov_location")
        .p(config.otherServers.rolesPath, "prov_role_path")
        .p(config.otherServers.role, "prov_role")
    }

    if (config.docker) {
        extraVars = extraVars.p(config.docker.registry, "docker_registry")
            .p(config.docker.imageVersion, "docker_image_version")
    }

    def skipTags = [].p(config.seedServer.skipTags)

    args = args.p(skipTags.asParam("skip-tags", ",")).p(extraVars.asParam("extra-vars", " ")) << "prime-node.yml"
}

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

    executable = "ansible-playbook"
    args = ["-i", config.seedServer.ip + ',']

    if ( config.seedServer.user != null && config.seedServer.user != "" ) {
        args = args << "--user=$config.seedServer.user"
    }


    if ( config.debug ) {
        args = args << "-vvvv"
    }

    def extraVars = []
    if (config.seedServer) {
        extraVars = extraVars.p(config.seedServer.extraVars)
            .p(config.seedServer.password, "ansible_ssh_pass")
            .p(config.seedServer.sudoPassword, "ansible_sudo_pass")
            .p(config.seedServer.fabric_ip, "fabric_ip")
	    .p(config.seedServer.management_ip, "management_ip")
            .p(config.seedServer.management_gw, "management_gw")
            .p(config.seedServer.management_network, "management_network")
	    .p(config.seedServer.management_iface, "management_iface")
	    .p(config.seedServer.external_ip, "external_ip")
            .p(config.seedServer.external_gw, "external_gw")
            .p(config.seedServer.external_network, "external_network")
            .p(config.seedServer.external_iface, "external_iface")
	    .p(config.seedServer.fabric_ip, "fabric_ip")
	    .p(config.seedServer.fabric_network, "fabric_network")
	    .p(config.seedServer.fabric_iface, "fabric_iface")
            .p(config.seedServer.fabric_iface_spec, "fabric_iface_spec")
            .p(config.seedServer.domain, "domain")
            .p(config.seedServer.virtualbox_support, "virtualbox_support")
	    .p(config.seedServer.power_helper_user, "power_helper_user")
	    .p(config.seedServer.power_helper_host, "power_helper_host")
            .p(config.seedServer.port, "ansible_ssh_port")
    }

    if (config.otherServers) {
        extraVars = extraVars.p(config.otherServers.location, "prov_location")
        .p(config.otherServers.rolesPath, "prov_role_path")
        .p(config.otherServers.role, "prov_role")
    }

    if (config.docker) {
        extraVars = extraVars.p(config.docker.registry, "docker_registry")
            .p(config.docker.imageVersion, "docker_image_version")
    }

    def skipTags = [].p(config.seedServer.skipTags)

    args = args.p(skipTags.asParam("skip-tags", ",")).p(extraVars.asParam("extra-vars", " ")) << "head-node.yml"
}

prime.dependsOn {
    updateDocker
}

tasks.addRule(new DockerFetchRule(project))
tasks.addRule(new DockerPublishRule(project, project(':maas').prime))
tasks.addRule(new DockerTagRule(project))


