/*
* Licensed Materials - Property of IBM Corp.
* IBM UrbanCode Build
* IBM UrbanCode Deploy
* IBM UrbanCode Release
* IBM AnthillPro
* (c) Copyright IBM Corporation 2016. All Rights Reserved.
*
* U.S. Government Users Restricted Rights - Use, duplication or disclosure restricted by
* GSA ADP Schedule Contract with IBM Corp.
*/
import java.io.File

import com.urbancode.air.AirPluginTool
import com.urbancode.air.CommandHelper
import com.urbancode.air.ExitCodeException
import com.urbancode.air.plugin.docker.DockerUtils
import com.urbancode.air.XTrustProvider
import com.urbancode.ud.client.ResourceClient
import com.urbancode.ud.client.ComponentClient
import com.urbancode.ud.client.ApplicationClient
import com.urbancode.ud.client.EnvironmentClient

XTrustProvider.install()

// Get step properties
def airTool = new AirPluginTool(this.args[0], this.args[1])
def props = airTool.getStepProperties()
def workdir = new File('.')
String composeFilesRaw           = props['composeFiles']
String composeProjectName        = props['composeProjectName']
String composeOptions            = props['composeOptions']
String command                   = props['command']
String optsAndServs              = props['optsAndServs']
String envPropValues             = props['envPropValues']
String scriptPathsRaw            = props['scriptPaths']
String commandPath               = props['commandPath']?:"docker-compose"
Boolean saveScript               = Boolean.valueOf(props['saveScript'])

// Sanitize properties
List<String> scriptPaths = DockerUtils.toTrimmedList(scriptPathsRaw, ',')
List<String> composeFilePaths = DockerUtils.toTrimmedList(composeFilesRaw, '\n')
if (!composeFilePaths) {
    composeFilePaths << 'docker-compose.yml'
}

CommandHelper ch = new CommandHelper(workdir)


// compose up arguments
final String DOCKER_COMPOSE = DockerUtils.findDockerComposeExecutable(commandPath)
List<String> composeArgs = [DOCKER_COMPOSE]
if (composeOptions) {
    composeArgs << composeOptions
}
if (composeProjectName) {
    composeArgs << '-p'
    composeArgs << composeProjectName
}
composeFilePaths.each { path ->
    composeArgs << '-f'
    composeArgs << path
}
composeArgs << command

// Command Options and Services
List<String> argVals = DockerUtils.toTrimmedList(optsAndServs,"\\s+")
composeArgs.addAll(argVals)

// Environment properties
Map<String, String> envVars = [:]
if(envPropValues) {
    List tempEnvVals = DockerUtils.toTrimmedList(envPropValues,'\n|,')
    envVars = DockerUtils.toKeyValueMap(tempEnvVals, "=")
}

// command helper arguments
List<String> args = []
File script
final Boolean isWindows = System.getProperty('os.name').contains('Windows')
if (isWindows) {
    script = File.createTempFile("script", ".bat", workdir)

    // Write the Environment Variables
    envVars.each { var ->
        script << "set ${var.getKey()}=${var.getValue()}\n"
    }

    args << 'cmd'
    args << '/C'
}
else {
    script = File.createTempFile("script", ".sh", workdir)

    // Environment files
    scriptPaths.each { filePath ->
        def envScript = new File(filePath)
        if (envScript.exists()) {
            envScript.setExecutable(true)
            script << "source \"${filePath}\"\n"
        }
        else {
            throw new RuntimeException("Could not find env file at ${filePath}")
        }
    }

    // Write the Environment Variables
    envVars.each { var ->
        script << "export ${var.getKey()}=\"${var.getValue()}\"\n"
    }
}
if (!saveScript) {
    script.deleteOnExit()
}
script.setExecutable(true)
script << composeArgs.join(' ')

args << script.getCanonicalPath()

// Print Script Contents
println "============ Script Contents ============"
println script.getText()

// Run Compose
try {
    println "\n============ Runtime Output ============="
    ch.runCommand("Executing Compose ${command}...", args)
}
catch (ExitCodeException ex) {
    println "\n\n[Error] Unable to run docker-compose ${command}. Running the CLI's --help output for additional assistance."
    println "============ Compose --help Output ============"
    List<String> helpArgs = [DOCKER_COMPOSE, command, "--help"]
    ch.runCommand("Executing Compose ${command} --help", helpArgs)

    println "\n============ Stack Trace Output ==============="
    ex.printStackTrace()
    System.exit(1)
}
