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

import groovy.json.JsonSlurper

import org.codehaus.jettison.json.JSONObject



class UCDBase extends HelperBase {
    def component
    def version
    def isWindows

    public def getVersionStatuses(def status) {
        StatusBase statusFoundInBuild = null
        StatusBase statusFoundInDeploy = null
        CommandHelper helper = getCommandHelper()
        def command = [javaFile.absolutePath, '-jar', udClientJarFile.absolutePath,
                       "--weburl", url,
                       "getStatuses",
                       "--type", "version"
        ]
        addCredentials(command)

        def statusOutput
        helper.ignoreExitValue(true)
        int exitCode = helper.runCommand("Getting the list of version statuses", command) { proc ->
            proc.out.close() // close stdin
            Thread t = proc.consumeProcessErrorStream(System.out)
            statusOutput = proc.in.text.trim()
            t.join(10000L)
        }
        helper.ignoreExitValue(false)

        StatusHelper statusHelper = new StatusHelper()
        statusHelper.workDir = workDir
        statusHelper.javaFile = javaFile
        statusHelper.udClientJarFile = udClientJarFile
        statusHelper.url = url
        statusHelper.user = user
        statusHelper.password = password
        statusHelper.ucdAuthToken = ucdAuthToken
        statusHelper.cmdHelper = getCommandHelper()

        if (exitCode == 0) {
            def statusList = new JsonSlurper().parseText(statusOutput).name
            if (!statusList) {
                println "No statuses were found in the IBM UrbanCode Deploy server."
            }
            else if (!statusList.contains(status)) {
                println "The status '${status}' does not exist in the IBM UrbanCode Deploy server. Valid statuses: ${statusList}"
            }
            else {
                statusFoundInDeploy = statusHelper.checkUCDStatus(statusOutput, status);
            }
        }
        else {
            println "Could not get any status information from IBM UrbanCode Deploy server. Trying to add the status to the version anyway."
        }

        statusFoundInBuild = statusHelper.checkUCBStatus(status)
        statusHelper.syncStatusBetweenBuildAndDeploy(statusFoundInBuild, statusFoundInDeploy, status)
    }


    public def addVersionStatus(def status) {
        CommandHelper helper = getCommandHelper()
        def command = [javaFile.absolutePath, '-jar', udClientJarFile.absolutePath,
                                 "--weburl", url,
                                 "addVersionStatus",
                                 "--component", component,
                                 "--version", version,
                                 "--status", status
        ]
        addCredentials(command)

        try {
            helper.runCommand("Adding status '${status}' to version '${version}' on component '${component}'", command)
        }
        catch (Exception e) {
            println "Failed to assign status ''${status}' to version '${version}' on component '${component}'. " +
                    "This is typically caused by using a status that does not exist."
            System.exit(1)
        }
    }

    public def createVersion(def description) {
        CommandHelper helper = getCommandHelper()
        helper.ignoreExitValue(true)
        def command = [javaFile.absolutePath, '-jar', udClientJarFile.absolutePath,
                       "--weburl", url,
                       "createVersion",
                       "--component", component,
                       "--name", version]

        if (description) {
            command << '--description'
            command << description
        }

        addCredentials(command)

        def versionId
        def createVersionOutput
        def outBuffer
        int exitCode = helper.runCommand("Creating IBM UrbanCode Deploy Component Version", command) { Process proc ->
            proc.out.close() // close stdin
            Thread t = proc.consumeProcessErrorStream(System.out)
            createVersionOutput = proc.in.text.trim()
            t.join(10000L)
        }
        helper.ignoreExitValue(false)

        // Only try to parse as JSON if there was no error
        if (exitCode == 0) {
            def versionJson = new JSONObject(createVersionOutput)
            versionId = versionJson.getString("id")
        }
        else {
            println "Unable to create version ${version} on component ${component}: " + createVersionOutput
        }

        return versionId
    }

    public void publishFiles(def baseDir, def includes, def excludes) {
        CommandHelper helper = getCommandHelper()
        def command = [javaFile.absolutePath, '-jar', udClientJarFile.absolutePath,
                   "--weburl", url,
                   "addVersionFiles",
                   "--component", component,
                   "--version", version,
                   "--base", baseDir,
                   "--verbose"]

        if (includes) {
            includes.split("\\n").each { include ->
                if (isWindows) {
                    include = "\"${include}\""
                }
                command << "--include" << include
            }
        }

        if (excludes) {
            excludes.split("\\n").each { exclude ->
                if (isWindows) {
                    exclude = "\"${exclude}\""
                }
                command << "--exclude" << exclude
            }
        }

        addCredentials(command)

        def commandOutput
        println "Publishing files for version ${version} on component ${component}"
        helper.runCommand("Publish IBM UrbanCode Deploy Component Version Files", command) { proc ->
            def out = new StringBuffer()
            def err = new StringBuffer()
            proc.out.close() // close stdin
            proc.waitForProcessOutput(out, err)
            commandOutput = err.toString().trim()
            println commandOutput
        }
        if (commandOutput.contains("Request error")) {
            System.exit(1)
        }
        println "Files published"
    }

    public void addVersionLink(def linkName, def linkUrl) {
        CommandHelper helper = getCommandHelper()
        def command = [javaFile.absolutePath, '-jar', udClientJarFile.absolutePath,
                   "--weburl", url,
                   "addVersionLink",
                   "--component", component,
                   "--version", version,
                   "--linkName", linkName,
                   "--link", linkUrl]
        addCredentials(command)
        helper.runCommand("Adding link ${linkName} (${linkUrl}) to version ${version} on component ${component}", command)
    }
}
