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

    // 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.headnode.ip
                ? config.headnode.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'

    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:ssZ")
    return formattedDate
}

def getCommitDate = { ->
    def stdOut = new ByteArrayOutputStream()
    exec {
        commandLine "git", "log", "--pretty=format:%cd", "--date=format:%FT%T%z", "-n", "1"
        standardOutput = stdOut
    }
    return stdOut.toString().trim()
}

def getCommitHash = { ->
    def hashStdOut = new ByteArrayOutputStream()
    exec {
        commandLine "git", "log", "--pretty=format:%H", "-n", "1"
        standardOutput = hashStdOut
    }
    return hashStdOut.toString().trim()
}

def isModified = { ->
    def statusOut = new ByteArrayOutputStream()
    def branchesOut = new ByteArrayOutputStream()
    exec {
        commandLine "bash", "-c", "repo --color=never --no-pager status . | tail -n +2 | wc -l"
        standardOutput = statusOut
    }
    exec {
        commandLine "bash", "-c", "repo --color=never --no-pager branches | wc -l"
        standardOutput = branchesOut
    }
    def statusVal = statusOut.toString().trim()
    def branchesVal = branchesOut.toString().trim()

    return statusVal != "0" || branchesVal != "0"
}

def getBranchName = { ->
    def stdout = new ByteArrayOutputStream()
    exec {
        commandLine "bash", "-c", "repo --color=never --no-pager info -l -o | grep 'Manifest branch:' | awk '{print \$NF}'"
        standardOutput = stdout
    }
    def val = stdout.toString().trim()
    if ( isModified() != "0" ) {
        val += '[modified]'
    }
    return val
}

task buildSwitchqImage(type: Exec) {
    workingDir 'switchq'
    commandLine 'make', 'build', 'package'
}

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

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

// IP Allocator Image

task buildAllocationImage(type: Exec) {
    workingDir 'ip-allocator'
    commandLine 'make', 'build', 'package'
}

task tagAllocationImage(type: Exec) {
   dependsOn buildAllocationImage
   commandLine "docker", 'tag', 'cord-ip-allocator:candidate', "$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) {
    workingDir 'provisioner'
    commandLine 'make', 'build', 'package'
}

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

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

// Config Generator Image

task buildConfigGeneratorImage(type: Exec) {
    workingDir 'config-generator'
    commandLine 'make', 'build', 'package'
}

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

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

// Automation Image

task buildAutomationImage(type: Exec) {
    workingDir 'automation'
    commandLine 'make', 'build', 'package'
}

task tagAutomationImage(type: Exec) {
    dependsOn buildAutomationImage
    commandLine "docker", 'tag', 'cord-maas-automation:candidate', "$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) {
    workingDir 'harvester'
    commandLine 'make', 'build', 'package'
}

task tagHarvesterImage(type: Exec) {
    dependsOn buildHarvesterImage
    commandLine "docker", 'tag', 'cord-dhcp-harvester:candidate', "$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 buildHarvesterImage
    dependsOn buildAutomationImage
    dependsOn buildAllocationImage
    dependsOn buildProvisionerImage
    dependsOn buildConfigGeneratorImage
    dependsOn buildSwitchqImage
}

task tagImages {
    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 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)  {
    executable = "ansible-playbook"
    args = ["-i", '../genconfig/cord-inv']

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

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

    def extraVars = []
    if (config.common) {
        extraVars = extraVars.p(config.common.extraVars)
            .p(config.headnode.ansible_ssh_pass, "ansible_ssh_pass")
            .p(config.headnode.ansible_become_pass, "ansible_become_pass")
            .p(config.headnode.ansible_ssh_port, "ansible_ssh_port")
            .p(config.common.fabric_ip, "fabric_ip")
            .p(config.common.fabric_range_low, "fabric_range_low")
            .p(config.common.fabric_range_high, "fabric_range_high")
            .p(config.common.management_ip, "management_ip")
            .p(config.common.management_range_low, "management_range_low")
            .p(config.common.management_range_high, "management_range_high")
            .p(config.common.management_gw, "management_gw")
            .p(config.common.management_bc, "management_bc")
            .p(config.common.management_network, "management_network")
            .p(config.common.management_iface, "management_iface")
            .p(config.common.external_ip, "external_ip")
            .p(config.common.external_gw, "external_gw")
            .p(config.common.external_bc, "external_bc")
            .p(config.common.external_network, "external_network")
            .p(config.common.external_iface, "external_iface")
            .p(config.common.fabric_iface, "fabric_iface")
            .p(config.common.domain, "domain")
            .p(config.common.virtualbox_support, "virtualbox_support")
            .p(config.common.power_helper_user, "power_helper_user")
            .p(config.common.power_helper_host, "power_helper_host")
    }

    if (config.passwords) {
        extraVars = extraVars.p(config.passwords.compute_node, "password_compute_node")
        .p(config.passwords.maas_admin, "password_maas_admin")
        .p(config.passwords.maas_user, "password_maas_user")
    }

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

    extraVars = extraVars.p("$targetReg", "deploy_docker_registry")
        .p("$targetTag", "deploy_docker_tag")

    // the password set on the compute node is skipped because this is being run against the
    // head node and we don't want to change the head node password as this node was manualy
    // set up.
    def skipTags = [].p(config.common.skipTags).p('set_compute_node_password')

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

task deployBase(type: Exec)  {
    executable = "ansible-playbook"
    args = ["-i", '../genconfig/cord-inv']

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

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

    def extraVars = []
    if (config.common) {
        extraVars = extraVars.p(config.common.extraVars)
            .p(config.headnode.ansible_ssh_pass, "ansible_ssh_pass")
            .p(config.headnode.ansible_become_pass, "ansible_become_pass")
            .p(config.headnode.ansible_ssh_port, "ansible_ssh_port")
            .p(config.common.fabric_ip, "fabric_ip")
            .p(config.common.fabric_range_low, "fabric_range_low")
            .p(config.common.fabric_range_high, "fabric_range_high")
            .p(config.common.management_ip, "management_ip")
            .p(config.common.management_range_low, "management_range_low")
            .p(config.common.management_range_high, "management_range_high")
            .p(config.common.management_gw, "management_gw")
            .p(config.common.management_network, "management_network")
            .p(config.common.management_iface, "management_iface")
            .p(config.common.external_ip, "external_ip")
            .p(config.common.external_gw, "external_gw")
            .p(config.common.external_network, "external_network")
            .p(config.common.external_iface, "external_iface")
            .p(config.common.fabric_iface, "fabric_iface")
            .p(config.common.domain, "domain")
            .p(config.common.virtualbox_support, "virtualbox_support")
            .p(config.common.power_helper_user, "power_helper_user")
            .p(config.common.power_helper_host, "power_helper_host")
    }

    if (config.passwords) {
        extraVars = extraVars.p(config.passwords.compute_node, "password_compute_node")
        .p(config.passwords.maas_admin, "password_maas_admin")
        .p(config.passwords.maas_user, "password_maas_user")
    }

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

    extraVars = extraVars.p("$targetReg", "deploy_docker_registry")
        .p("$targetTag", "deploy_docker_tag")

    // the password set on the compute node is skipped because this is being run against the
    // head node and we don't want to change the head node password as this node was manualy
    // set up.
    def skipTags = [].p(config.common.skipTags).p('set_compute_node_password')

    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))


