/*
* Licensed Materials - Property of IBM Corp.
* IBM UrbanCode Build
* (c) Copyright IBM Corporation 2012, 2014. All Rights Reserved.
*
* U.S. Government Users Restricted Rights - Use, duplication or disclosure restricted by
* GSA ADP Schedule Contract with IBM Corp.
*/
import javax.ws.rs.core.UriBuilder
import com.urbancode.air.*
import com.urbancode.ubuild.codestation.client.*
import com.urbancode.commons.util.IO
import org.apache.http.client.methods.HttpGet
import org.apache.http.HttpStatus;

import org.apache.log4j.BasicConfigurator
import org.apache.log4j.ConsoleAppender
import org.apache.log4j.Level
import org.apache.log4j.Logger
import org.apache.log4j.PatternLayout

import org.codehaus.jettison.json.JSONArray
import org.codehaus.jettison.json.JSONObject

BasicConfigurator.resetConfiguration()
Logger.getRootLogger().setLevel(Level.ERROR)
Logger.getRootLogger().addAppender(new ConsoleAppender(new PatternLayout("%m%n")))
Logger.getLogger("com.urbancode.ubuild.codestation").setLevel(Level.DEBUG)
Logger.getLogger("com.urbancode.vfs.client").setLevel(Level.INFO)

final def javaHome                  = System.getenv('JAVA_HOME')
final def webUrl                    = System.getenv('WEB_URL')
final def authToken                 = System.getenv('AUTH_TOKEN')
final def buildLifeId               = System.getenv('BUILD_LIFE_ID')
final def pluginHome                = System.getenv("PLUGIN_HOME")

final def apTool                    = new AirPluginTool(this.args[0], this.args[1])
final def workDir                   = new File('.').canonicalFile
final def javaFile                  = new File(new File(javaHome), 'bin/java' + (apTool.isWindows ? '.exe' : ''))
final def udClientJarFile           = new File(new File(pluginHome), 'lib/udclient.jar');

final def props                     = apTool.getStepProperties()
String url                          = props['automation/url']
def user                            = props['automation/user']
def ucdAuthToken                    = props['automation/authToken']
def password                        = props['automation/passScript']?.trim() ?: props['automation/password']
def ucdVersionSelection             = props['automation/ucdVersionSelection']
def componentName                   = props['componentName']
def versionName                     = props['versionName']
def description                     = props['versionDesc']
def propertiesTextArea              = props['propertiesTextArea']
def testPercentage                  = Boolean.valueOf(props['testPercentage'])
def codeAnalytics                   = Boolean.valueOf(props['codeAnalytics'])
def codeCoverage                    = Boolean.valueOf(props['codeCoverage'])
def sourceChange                    = Boolean.valueOf(props['sourceChange'])
def workItem                        = Boolean.valueOf(props['workItem'])

UCDBase ucd = new UCDBase()
ucd.workDir = workDir
ucd.javaFile = javaFile
ucd.udClientJarFile = udClientJarFile

ucd.url = url
ucd.user = user
ucd.password = password
ucd.ucdAuthToken = ucdAuthToken

ucd.component = componentName
ucd.version = versionName

// Try to create the version
def versionId = ucd.createVersion(description)
if (versionId) {
    println "Created version ${versionName} on component ${componentName} with id ${versionId}"
    apTool.setOutputProperty("buildlife/udeploy.versionId", versionId)
    apTool.setOutputProperties()
}

Properties propertiesList = new Properties()
if (propertiesTextArea) {
    propertiesList.load(new StringReader(propertiesTextArea))
}

Properties properties = new BuildLifeHelper(buildLifeId).addBuildLifeMetricsProperties(testPercentage, codeAnalytics, codeCoverage, sourceChange, workItem)
propertiesList.putAll(properties)

if (propertiesList) {
    def httpHelper = new HttpHelper()
    httpHelper.setHttpClient(ucd.getHttpClient())
    def propsHelper = new PropsHelper(httpHelper)
    propsHelper.setComponentVersionProperties(url, componentName, versionName, propertiesList)
}

// get the component repository id
def repositoryId = ''
if ("6.0".equals(ucdVersionSelection)) {
    def componentUrl =
        UriBuilder.fromPath(url).segment("rest", "deploy", "component", componentName).build().toString()
    HttpGet getComponentMethod = new HttpGet(componentUrl);
    try {
        def httpResponse = ucd.getHttpClient().execute(getComponentMethod);
        def code = httpResponse.getStatusLine().getStatusCode();
        def content = httpResponse.getEntity().getContent();

        switch (code) {
            case HttpStatus.SC_OK:
                String body = IO.readText(content);
                JSONObject json = new JSONObject(body)
                JSONArray componentProps = json.getJSONArray('properties')
                for (int i=0; i<componentProps.length(); i++) {
                    JSONObject componentProp = componentProps.getJSONObject(i)
                    if ('code_station/repository'.equals(componentProp.getString('name'))) {
                        repositoryId = componentProp.getString('value')
                        break;
                    }
                }
                break;

            case HttpStatus.SC_NOT_FOUND:
                throw new Exception("Component not found: " + componentUrl);

            case HttpStatus.SC_INTERNAL_SERVER_ERROR:
                throw new Exception("Server error getting component: " + IO.readText(content));

            default:
                throw new Exception("Unexpected response from server: " + code);
        }
    }
    finally {
        getComponentMethod.releaseConnection();
    }

    if (!repositoryId) {
        throw new Exception("Unable to retrieve repository id from the component.")
    }
}

// copy artifacts
try {
    if (ucdAuthToken) {
        user = "PasswordIsAuthToken"

        JSONObject tokenJson = new JSONObject()
        tokenJson.put("token", ucdAuthToken)
        password = tokenJson.toString()
    }

    def csCredentials = AuthenticationCredentials.createAuthTokenCredentials(authToken)
    def codestationBaseUrl = webUrl.endsWith("/") ? webUrl + "rest2" : webUrl + "/rest2"
    def codestationClient = new CodestationClient(codestationBaseUrl, csCredentials)
    def buildLife = codestationClient.buildLifeLookup.findBuildLife(buildLifeId)
    println "Initiating copy build life ${buildLifeId} artifacts to ${url}"
    if ("6.0".equals(ucdVersionSelection)) {
        def targetUrl = UriBuilder.fromPath(url).path('vfs').build().toString()
        codestationClient.copyAllArtifacts(buildLife, targetUrl, repositoryId, user, password, null, versionName)
    }
    else {
        codestationClient.copyAllArtifactsToUrbanCodeDeploy(buildLife, url, componentName, user, password, null, versionName)
    }
    println "Artifacts copied"
}
catch (Exception e) {
    println "Artifact copy failed"
    e.printStackTrace()
    System.exit(1)
}
