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

    appVersion = null

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

    comps = [
            'aaa' : [
                    'type':     'gitmodule',
                    'upstream': 'https://gerrit.opencord.org/aaa',
                    'branch' : 'master',
                    'tag' : appVersion,
                    'componentDir': './apps/aaa'
            ],
            'vtn' : [
                    'type':     'gitmodule',
                    'upstream': 'https://gerrit.opencord.org/vtn',
                    'branch' : 'master',
                    'tag' : appVersion,
                    'componentDir': './apps/vtn'
            ],
            'mcast' : [
                    'type':     'gitmodule',
                    'upstream': 'https://gerrit.opencord.org/mcast',
                    'branch' : 'master',
                    'tag' : appVersion,
                    'componentDir': './apps/mcast'
            ],
            'igmp' : [
                    'type':     'gitmodule',
                    'upstream': 'https://gerrit.opencord.org/igmp',
                    'branch' : 'master',
                    'tag' : appVersion,
                    'componentDir': './apps/igmp'
            ],
            'olt' : [
                    'type':     'gitmodule',
                    'upstream': 'https://gerrit.opencord.org/olt',
                    'branch' : 'master',
                    'tag' : appVersion,
                    'componentDir': './apps/olt'
            ],
            'config' : [
                    'type':     'gitmodule',
                    'upstream': 'https://gerrit.opencord.org/config',
                    'branch' : 'master',
                    'tag' : appVersion,
                    'componentDir': './apps/config'
            ]
    ]
}


task fetchGitSubmodules {
    comps.each { name, spec -> if (spec.type == 'gitmodule') { dependsOn "gitupdate" + name } }
}

task buildOnosApps (type: Exec) {
    workingDir './apps'
    commandLine 'mvn', 'clean', 'install'
}

task copyLocalRepo (dependsOn: buildOnosApps, type: Exec) {
    workingDir './'
    commandLine 'cp', '-R', System.env.HOME + '/.m2/repository', 'repository'
}

task buildRepoImage (dependsOn: copyLocalRepo, type: Exec) {
    commandLine 'docker', 'build', '-t', 'opencord/mavenrepo', '.'
}

task tagMavenRepoImage (type: Exec) {
    commandLine 'docker', 'tag', 'opencord/mavenrepo', "$targetReg/mavenrepo:$targetTag"
}

task publishMavenRepoImage (type: Exec) {
    dependsOn tagMavenRepoImage
    commandLine 'docker', 'push', "$targetReg/mavenrepo:$targetTag"
}

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

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

task fetch {
    dependsOn fetchGitSubmodules
}

task buildImages (dependsOn: fetch) {
    dependsOn buildOnosApps
    dependsOn copyLocalRepo
    dependsOn buildRepoImage
}

task publish (dependsOn: buildImages) {
    dependsOn publishMavenRepoImage
}

task deploy (dependsOn: publishMavenRepoImage, 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"
    }

    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.domain, "domain")
    }

    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", " ")) << "mavenrepo.yml"   
}


// Depending on the version of the apps this will either make a release or publish a snapshot
task release (type: Exec) {
    workingDir './apps'
    commandLine 'mvn', 'clean', 'deploy'
}

tasks.addRule(new GitSubmoduleUpdateRule(project))
