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

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

import org.apache.http.HttpResponse
import org.apache.http.client.HttpClient
import org.apache.http.client.methods.HttpGet

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

class BuildLifeHelper {
    String authToken = System.getenv("AUTH_TOKEN")
    String webUrl = System.getenv("WEB_URL")
    def buildlifeId

    public BuildLifeHelper(def buildlifeId) {
        webUrl += webUrl.endsWith("/") ? "" : "/"
        this.buildlifeId = buildlifeId
    }

    public Properties getTestSuccessPercentage() {
        Properties testPercentage = new Properties()
        String testPercentageRestUrl = webUrl + "rest2/build-lives/${buildlifeId}/tests"

        println "Getting test success percentage for buildlife ${buildlifeId}."

        try {
            String content = getRestContent(testPercentageRestUrl)
            def jsonResult = new JSONObject(content)
            JSONArray reports = jsonResult['reports']
            for (def i = 0; i < reports.length(); i++){
                def report = reports.get(i)
                String reportName = report['name'].replaceAll(" ", "")
                String propertyName = "uc.testsuccess.${reportName}"
                testPercentage.put(propertyName, String.valueOf(report['successPercent']))
            }
        }
        catch (Exception e) {
            e.printStackTrace()
            System.exit(1)
        }

        return testPercentage
    }

    public Properties getCodeCoverage() {
        Properties codeCoverage = new Properties()
        String codeCoverageRestUrl = webUrl + "rest2/build-lives/${buildlifeId}/codeCoverage"

        println "Getting code coverage for buildlife ${buildlifeId}."

        try {
            String content = getRestContent(codeCoverageRestUrl)
            def jsonResult = new JSONObject(content)
            JSONArray reports = jsonResult['reports']
            for (def i = 0; i < reports.length(); i++) {
                def report = reports.get(i);
                String reportName = report['name'].replaceAll(" ", "")
                String propertyName = "uc.coverage.${reportName}"
                String linePercentageName = "${propertyName}.linePercentage"
                String methodPercentageName = "${propertyName}.methodPercentage"
                String branchPercentageName = "${propertyName}.branchPercentage"
                codeCoverage.put(linePercentageName, String.valueOf(report['linePercentage']))
                codeCoverage.put(methodPercentageName, String.valueOf(report['methodPercentage']))
                codeCoverage.put(branchPercentageName, String.valueOf(report['branchPercentage']))
            }
        }
        catch (Exception e) {
            e.printStackTrace()
            System.exit(1)
        }

        return codeCoverage
    }

    public Properties getCodeAnalytics() {
        Properties codeAnalytics = new Properties()
        String codeAnalyticsRestUrl = webUrl + "rest2/build-lives/${buildlifeId}/analyticSummaries"

        println "Getting code analytics for buildlife ${buildlifeId}."

        try {
            String content = getRestContent(codeAnalyticsRestUrl)
            def jsonResult = new JSONObject(content)
            JSONArray reports = jsonResult['records']
            for (def i = 0; i < reports.length(); i++) {
                def report = reports.get(i);
                String reportName = report['name'].replaceAll(" ", "")
                String propertyName = "uc.analytics.${reportName}.count"
                codeAnalytics.put(propertyName, String.valueOf(report['count']))
            }
        }
        catch (Exception e) {
            e.printStackTrace()
            System.exit(1)
        }

        return codeAnalytics
    }

    public Properties getIssues() {
        Properties issues = new Properties()
        String issuesRestUrl = webUrl + "rest2/build-lives/${buildlifeId}/issues"

        println "Getting issues for buildlife ${buildlifeId}."

        try {
            String content = getRestContent(issuesRestUrl)
            def jsonResult = new JSONObject(content)
            JSONArray issuesJson = jsonResult['issues']
            String propertyName = "uc.issues"
            issues.put(propertyName, issuesJson.toString())
        }
        catch (Exception e) {
            e.printStackTrace()
            System.exit(1)
        }

        return issues
    }

    public Properties getSourceChange() {
        Properties sourceChange = new Properties()
        String sourceChangeRestUrl = webUrl + "rest2/build-lives/${buildlifeId}/sourceChange"

        println "Getting source changes for buildlife ${buildlifeId}."

        try {
            String content = getRestContent(sourceChangeRestUrl)
            def jsonArray = new JSONArray(content)
            String propertyName = "uc.sourcechanges"
            sourceChange.put(propertyName, jsonArray.toString())
        }
        catch (Exception e) {
            e.printStackTrace()
            System.exit(1)
        }

        return sourceChange
    }

    protected boolean isGoodResponseCode(int responseCode) {
        return responseCode >= 200 && responseCode < 300;
    }

    protected String getRestContent(String restUrl) {
        HttpGet getMethod = new HttpGet(restUrl)
        if (authToken) {
            getMethod.addHeader("Authorization-Token", authToken)
        }

        HttpClientBuilder builder = new HttpClientBuilder()
        builder.setTrustAllCerts(true)
        HttpClient client = builder.buildClient()
        HttpResponse response = client.execute(getMethod)
        def responseCode = response.statusLine.statusCode
        String content = IO.readText(response.entity.content)

        if (!isGoodResponseCode(responseCode)) {
            throw new Exception("Failed to get content: ${content}")
        }

        getMethod.releaseConnection()
        return content
    }

    public Properties addBuildLifeMetricsProperties(boolean testPercentage, boolean codeAnalytics, boolean codeCoverage, boolean sourceChange, boolean workItem) {
        Properties propertiesList = new Properties()
        if (testPercentage) {
            Properties properties = getTestSuccessPercentage()
            propertiesList.putAll(properties)
        }

        if (codeAnalytics) {
            Properties properties = getCodeAnalytics()
            propertiesList.putAll(properties)
        }

        if (codeCoverage) {
            Properties properties = getCodeCoverage()
            propertiesList.putAll(properties)
        }

        if (sourceChange) {
            Properties properties = getSourceChange()
            propertiesList.putAll(properties)
        }

        if (workItem) {
            Properties properties = getIssues()
            propertiesList.putAll(properties)
        }
        return propertiesList
    }
}
