/*
* 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.
*/
package com.urbancode.air.plugin.fortify

import org.apache.http.client.HttpClient
import org.apache.http.client.methods.HttpPost
import org.apache.http.entity.StringEntity
import org.apache.http.impl.client.DefaultHttpClient
import org.xml.sax.InputSource

import com.urbancode.commons.httpcomponentsutil.HttpClientBuilder
import com.urbancode.commons.util.IO

public class XmlHelper {
    
    public void uploadResult(String reportName, fvdlFile) {
        def buildLifeId = System.getenv("BUILD_LIFE_ID")
        
        // define a closure for parsing the Fortify output file and writing out air XML format
        def reportXml = new java.io.StringWriter()
        new groovy.xml.MarkupBuilder(reportXml).
        "analytics"("name":reportName, "buildLifeId":buildLifeId, "type":"Fortify") {
            def addFinding = { findingId, findingFile, findingLine, findingName, findingSeverity, findingDesc, findingStatus ->
                "finding"() {
                    "id"(findingId)
                    "file"(findingFile)
                    "line"(findingLine)
                    "name"(findingName)
                    "severity"(findingSeverity)
                    "description"(findingDesc)
                    "status"(findingStatus)
                }
            }
            
            def handler = new FortifyHandler(addFinding)
            def reader = javax.xml.parsers.SAXParserFactory.newInstance().newSAXParser().XMLReader
            reader.setContentHandler(handler)
            def inputStream = new FileInputStream(reportFile)
            reader.parse(new InputSource(inputStream))
        }
        
        if (reportXml) {
            // uncomment to debug content sent to the server
            // println reportXml
            sendPostRequest(reportName, reportXml.toString())
        }
        else {
            println 'No report was able to be generated'
        }
    }
    
    //------------------------------------------------------------------------------
    // Construct XML message and upload
    //------------------------------------------------------------------------------
    private void sendPostRequest(String reportName, String xml) {
        def authToken = System.getenv("AUTH_TOKEN")
        def buildLifeId = System.getenv("BUILD_LIFE_ID")
        
        // construct the URL with property replacements
        String baseUrl = System.getenv("WEB_URL")
        
        baseUrl += baseUrl.endsWith("/") ? "" : "/"
        def encodedReportName = URLEncoder.encode(reportName)
        String url = baseUrl + "rest/buildlife/${buildLifeId}/sourceanalytics?reportName=${encodedReportName}"
        
        println "Sending request to $url"

        HttpClientBuilder clientBuilder = new HttpClientBuilder();
        clientBuilder.setTrustAllCerts(true);
        DefaultHttpClient client = clientBuilder.buildClient();
        
        HttpPost postMethod = new HttpPost(url);
        if (authToken) {
            postMethod.setHeader("Authorization-Token", authToken)
            postMethod.setHeader("Content-Type", "application/xml")
        }
       
        postMethod.setEntity(new StringEntity(xml));
    
        def httpResponse = client.execute(postMethod)
        def responseCode = httpResponse.getStatusLine().getStatusCode()
        if (isGoodResponseCode(responseCode)) {
            IO.copy(postMethod.getEntity().getContent(), System.out)
            println ""
        }
        else {
            IO.copy(postMethod.getEntity().getContent(), System.err)
            throw new RuntimeException("Failed to upload HP Fortify report. StatusCode: ${responseCode}")
        }
    }
    
    private boolean isGoodResponseCode(int responseCode) {
        return responseCode >= 200 && responseCode < 300;
    }

}