
/*
 * Copyright 2017-present Open Networking Foundation

 * 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', "DOCKER_TAG=$targetTag", "DOCKER_REGISTRY=$targetReg", 'build'
}

task publishSwitchqImage(type: Exec) {
    workingDir 'switchq'
    commandLine 'make', "DOCKER_TAG=$targetTag", "DOCKER_REGISTRY=$targetReg", 'publish'
}

// IP Allocator Image

task buildAllocationImage(type: Exec) {
    workingDir 'ip-allocator'
    commandLine 'make', "DOCKER_TAG=$targetTag", "DOCKER_REGISTRY=$targetReg", 'build'
}

task publishAllocationImage(type: Exec) {
    workingDir 'ip-allocator'
    commandLine 'make', "DOCKER_TAG=$targetTag", "DOCKER_REGISTRY=$targetReg", 'publish'
}

// Provisioner Image

task buildProvisionerImage(type: Exec) {
    workingDir 'provisioner'
    commandLine 'make', "DOCKER_TAG=$targetTag", "DOCKER_REGISTRY=$targetReg", 'build'
}

task publishProvisionerImage(type: Exec) {
    workingDir 'provisioner'
    commandLine 'make', "DOCKER_TAG=$targetTag", "DOCKER_REGISTRY=$targetReg", 'publish'
}

// Config Generator Image

task buildConfigGeneratorImage(type: Exec) {
    workingDir 'config-generator'
    commandLine 'make', "DOCKER_TAG=$targetTag", "DOCKER_REGISTRY=$targetReg", 'build'
}

task publishConfigGeneratorImage(type: Exec) {
    workingDir 'config-generator'
    commandLine 'make', "DOCKER_TAG=$targetTag", "DOCKER_REGISTRY=$targetReg", 'publish'
}

// Automation Image

task buildAutomationImage(type: Exec) {
    workingDir 'automation'
    commandLine 'make', "DOCKER_TAG=$targetTag", "DOCKER_REGISTRY=$targetReg", 'build'
}

task publishAutomationImage(type: Exec) {
    workingDir 'automation'
    commandLine 'make', "DOCKER_TAG=$targetTag", "DOCKER_REGISTRY=$targetReg", 'publish'
}

// DHCP Harvester Images

task buildHarvesterImage(type: Exec) {
    workingDir 'harvester'
    commandLine 'make', "DOCKER_TAG=$targetTag", "DOCKER_REGISTRY=$targetReg", 'build'
}

task publishHarvesterImage(type: Exec) {
    workingDir 'harvester'
    commandLine 'make', "DOCKER_TAG=$targetTag", "DOCKER_REGISTRY=$targetReg", 'publish'
}

// ~~~~~~~~~~~~~~~~~~~ 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 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")
            .p(config.common.kernel_opts, "kernel_opts")
    }

    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")
            .p(config.common.kernel_opts, "kernel_opts")
    }

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


