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

import groovy.json.JsonSlurper
import com.urbancode.air.AirPluginTool
import com.urbancode.air.CommandHelper
import com.urbancode.air.plugin.docker.DockerHelper

def apTool = new AirPluginTool(this.args[0], this.args[1])
def props = apTool.getStepProperties()

def image = props["image"].trim()
def globalOptions = props["globalOptions"]?.trim()
def envVars = props["envVars"]

def String getAWSAuthToken(user, password, awsCli, region) {
    def command = [awsCli, "--output", "json", "ecr", "get-authorization-token"]

    CommandHelper ch = new CommandHelper(new File("."))
    ch.addEnvironmentVariable("AWS_ACCESS_KEY_ID", user)
    ch.addEnvironmentVariable("AWS_SECRET_ACCESS_KEY", password)

    if (!region) {
        def defaultRegion = System.getenv("AWS_DEFAULT_REGION")

        if (!defaultRegion) {
            region = "us-east-1"
            println "Could not find environment variable AWS_DEFAULT_REGION. Setting to '${region}'"
        }
        else {
            region = defaultRegion
            println "Setting region to '${region}' based on environment variable, AWS_DEFAULT_REGION"
        }
    }

    ch.addEnvironmentVariable("AWS_DEFAULT_REGION", region)

    def raw
    ch.runCommand("Authenticating with ECS", command, { proc ->
        proc.out.close() // close stdin
        proc.consumeProcessErrorStream(System.out) // forward stderr
        raw = proc.text.trim();
    })
    def authData = new JsonSlurper().parseText(raw).authorizationData[0]
    def decodedToken = new String(authData.authorizationToken.decodeBase64())

    return new String(decodedToken.replaceFirst("AWS:", ""))
}

def srcRegistry = props["srcRegistry"].trim()
def srcRegistryUserName = props["srcRegistryUserName"].trim()
def srcRegistryPassword = props["srcRegistryPassword"].trim()
def srcRegistryEmail = props["srcRegistryEmail"]?.trim()
def srcRegistryType = props["srcRegistryType"]
def srcAwsCli = props["srcAwsCli"]?.trim()
def srcAwsRegion = props["srcAwsRegion"]?.trim()
def srcIcsApi = props["srcIcsApi"]?.trim()
def srcIcsSpace = props["srcIcsSpace"]?.trim()
def srcIcsOrg = props["srcIcsOrg"]?.trim()
def srcIcsApiKey = props["srcIcsApiKey"]?.trim()

def destTag = props["destTag"]?.trim()
def destRegistry = props["destRegistry"].trim()
def destRegistryUserName = props["destRegistryUserName"].trim()
def destRegistryPassword = props["destRegistryPassword"].trim()
def destRegistryEmail = props["destRegistryEmail"]?.trim()
def destRegistryType = props["destRegistryType"]
def destAwsCli = props["destAwsCli"]?.trim()
def destAwsRegion = props["destAwsRegion"]?.trim()
def destIcsApi = props["destIcsApi"]?.trim()
def destIcsSpace = props["destIcsSpace"]?.trim()
def destIcsOrg = props["destIcsOrg"]?.trim()
def destIcsApiKey = props["destIcsApiKey"]?.trim()

Properties cmdProps = new Properties()
cmdProps["globalOptions"] = globalOptions
cmdProps["envVars"] = envVars
cmdProps["registry"] = srcRegistry
cmdProps["image"] = image
cmdProps["dockerRegistryUserEmail"] = srcRegistryEmail
if (srcRegistryType == "amazon-ecr" && srcAwsCli) {
    awsAuthToken = getAWSAuthToken(srcRegistryUserName, srcRegistryPassword, srcAwsCli, srcAwsRegion)
    cmdProps["dockerRegistryUserName"] = "AWS"
    cmdProps["dockerRegistryUserPassword"] = awsAuthToken
}
else {
    cmdProps["dockerRegistryUserName"] = srcRegistryUserName
    cmdProps["dockerRegistryUserPassword"] = srcRegistryPassword
}

// Login to source registry.  Eventually change Docker Login step to support this directly, then can just call runDockerCommand("login", cmdProps)
def loginHelper = new DockerHelper(apTool)
if (srcRegistryType == "ibm-containers") {
    cmdProps["icsApi"] = srcIcsApi
    cmdProps["icsSpace"] = srcIcsSpace
    cmdProps["icsOrg"] = srcIcsOrg
    cmdProps["icsApiKey"] = srcIcsApiKey
    loginHelper.icsLogin(cmdProps)
}
else {
    loginHelper.runDockerCommand("login", cmdProps)
}

// Pull image from source registry
def pullHelper = new DockerHelper(apTool)
cmdProps["image"] = pullHelper.getImageTag(srcRegistry, image, "")
pullHelper.runDockerCommand("pull", cmdProps)

// Tag with destination registry and optionally new tag
def tagHelper = new DockerHelper(apTool)
if (destTag) {
    def imageStr = image
    int lastColon = image.lastIndexOf(":")
    if (lastColon >= 0) {
        imageStr = image.substring(0, lastColon)
    }
    cmdProps["tag"] = tagHelper.getImageTag(destRegistry, imageStr, destTag)
}
else {
    cmdProps["tag"] = tagHelper.getImageTag(destRegistry, image, "")
}
tagHelper.runDockerCommand("tag", cmdProps)

// Login to destination registry.  Eventually change Docker Login step to support this directly, then can just call runDockerCommand("login", cmdProps)
cmdProps["registry"] = destRegistry
cmdProps["dockerRegistryUserEmail"] = destRegistryEmail
if (destRegistryType == "amazon-ecr" && destAwsCli) {
    awsAuthToken = getAWSAuthToken(destRegistryUserName, destRegistryPassword, destAwsCli, destAwsRegion)
    cmdProps["dockerRegistryUserName"] = "AWS"
    cmdProps["dockerRegistryUserPassword"] = awsAuthToken
}
else {
    cmdProps["dockerRegistryUserName"] = destRegistryUserName
    cmdProps["dockerRegistryUserPassword"] = destRegistryPassword
}
loginHelper = new DockerHelper(apTool)
if (destRegistryType == "ibm-containers") {
    cmdProps["icsApi"] = destIcsApi
    cmdProps["icsSpace"] = destIcsSpace
    cmdProps["icsOrg"] = destIcsOrg
    cmdProps["icsApiKey"] = destIcsApiKey
    loginHelper.icsLogin(cmdProps)
}
else {
    loginHelper.runDockerCommand("login", cmdProps)
}

// Push to destination registry
def pushHelper = new DockerHelper(apTool)
cmdProps["image"] = cmdProps["tag"] // The full image name was set when we tagged the image earlier
pushHelper.runDockerCommand("push", cmdProps)

apTool.storeOutputProperties()
