/*
* Licensed Materials - Property of IBM* and/or HCL**
* UrbanCode Deploy
* UrbanCode Build
* UrbanCode Release
* AnthillPro
* (c) Copyright IBM Corporation 2014, 2017. All Rights Reserved.
* (c) Copyright HCL Technologies Ltd. 2018. All Rights Reserved.
*
* U.S. Government Users Restricted Rights - Use, duplication or disclosure restricted by
* GSA ADP Schedule Contract with IBM Corp.
*
* * Trademark of International Business Machines
* ** Trademark of HCL Technologies Limited
*/

import org.apache.commons.lang.ObjectUtils;
import org.apache.http.impl.client.DefaultHttpClient;
import com.urbancode.commons.httpcomponentsutil.HttpClientBuilder;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.methods.HttpGet;
import java.security.NoSuchAlgorithmException;

import com.urbancode.commons.util.IO;
import com.urbancode.commons.fileutils.digest.DigestUtil;
import com.urbancode.commons.fileutils.FileUtils;
import com.urbancode.air.AirPluginTool

final AirPluginTool airPluginTool = new AirPluginTool(this.args[0], this.args[1])
final Properties props = airPluginTool.getStepProperties()

final def workDir = new File('.').canonicalFile

final def ARTIFACT_FILE_HASH_EXT = ".sha1";
final def REPO_PATH_SEPARATOR = "/";
final def ARTIFACT_FILE_HASH_ALGORITHM = "sha1";
def repoUrl = props['repositoryUrl'];
while (repoUrl.endsWith(REPO_PATH_SEPARATOR)) {
    repoUrl = repoUrl.substring(0, repoUrl.length() - 1);
}
def artifacts = props['artifacts'].split('\n');
def username = props['username'];
def password = props['password'];
def proxyHost = props['proxyHost']
def proxyPortString = props['proxyPort']
def proxyUsername = props['proxyUsername']
def proxyPassword = props['proxyPassword']
def checkHash = props['checkHash'];
def baseVersion = props['baseVersion'];

def exitVal = 0;

HttpClientBuilder builder = new HttpClientBuilder();
if (username) {
    builder.setPreemptiveAuthentication(true);
    builder.setUsername(username);
    builder.setPassword(password);
}
if (proxyHost) {
    def proxyPort = Integer.parseInt(proxyPortString)
    builder.setProxyHost(proxyHost);
    builder.setProxyPort(proxyPort);
    if (proxyUsername) {
        builder.setProxyUsername(proxyUsername);
        builder.setProxyPassword(proxyPassword);
    }
}
DefaultHttpClient client = builder.buildClient();

def downloadFileFromRepo = { url ->
    HttpGet get = new HttpGet(url);
    HttpResponse response = client.execute(get);
    int status = response.getStatusLine().getStatusCode();
    if (status == HttpStatus.SC_OK) {
        String tempFileSuffix = ".maven2";
        int extIndex = url.lastIndexOf(".");
        if (extIndex >= 0) {
            tempFileSuffix = url.substring(extIndex);
        }
        artifactFile = File.createTempFile("maven2-", tempFileSuffix, workDir);
        artifactFile.deleteOnExit()
        FileUtils.writeInputToFile(response.getEntity().getContent(), artifactFile);
        return artifactFile;
    }
    else {
        throw new Exception("Exception downloading file : " + url + "\nErrorCode : " + status.toString());
    }
}

def verifyHash = { fileToVerify, hashFile ->
    BufferedReader reader = null;
    String storedDigest = null;
    try {
        try {
            reader = new BufferedReader(new FileReader(hashFile));
            storedDigest = reader.readLine();
            if (storedDigest != null) {
                storedDigest = storedDigest.trim();

                // There can be extra stuff in the hash files after the hash value
                if (storedDigest.indexOf(" ") > 0) {
                    String[] strings = storedDigest.split(" ");
                    storedDigest = strings[0];
                }
            }

        }
        finally {
            if (reader != null) {
                reader.close();
            }
        }
    }
    catch (Exception e) {
        throw new Exception("Error reading digest value from downloaded Maven remote digest " +
                "file: " + e.getMessage(), e);
    }

    if (storedDigest != null) {
        String computedDigest;
        try {
            computedDigest = DigestUtil.getHexDigest(fileToVerify, ARTIFACT_FILE_HASH_ALGORITHM);
            if (!ObjectUtils.equals(storedDigest, computedDigest)) {
                throw new Exception("Artifact file verification of " + fileToVerify.getName() +
                        " failed. Expected digest of " + storedDigest + " but the downloaded file was " + computedDigest);
            }
        }
        catch (NoSuchAlgorithmException e) {
            throw new Exception("Algorithm to verify Maven remote artifacts not supported: " +
                    ARTIFACT_FILE_HASH_ALGORITHM);
        }
        catch (IOException e) {
            throw new Exception("Error verifying downloaded Maven remote artifacts: " +
                    e.getMessage(), e);
        }
    }
}

try {
    artifacts.each { artifact ->
        def segments = artifact.split('/');
        String filename = null;
        String version = null;
        String artifactId = null;
        String groupId = null;
        try {
            if (segments.length == 4) {
                filename = segments[3];
                version = segments[2];
                artifactId = segments[1];
                groupId = segments[0];
            } else {
                filename = segments[2];
                version = segments[1];
                def firstDot = segments[0].lastIndexOf(".");
                artifactId = segments[0].substring(firstDot+1);
                groupId = segments[0].substring(0, firstDot);
            }
        }
        catch (Exception e){
            println ("[Error] Error splitting artifacts: " + e.getMessage());
            System.exit(1);
        }
        String downloadUrl
        if (baseVersion) {
            println("[Info] Snapshot version detected with base name: " + baseVersion)
            downloadUrl = repoUrl + REPO_PATH_SEPARATOR +
                    groupId.replace(".", REPO_PATH_SEPARATOR) + REPO_PATH_SEPARATOR +
                    artifactId + REPO_PATH_SEPARATOR + baseVersion + REPO_PATH_SEPARATOR + filename;
        }
        else {
            downloadUrl = repoUrl + REPO_PATH_SEPARATOR +
                    groupId.replace(".", REPO_PATH_SEPARATOR) + REPO_PATH_SEPARATOR +
                    artifactId + REPO_PATH_SEPARATOR + version + REPO_PATH_SEPARATOR + filename
        }
        println "[Action] Downloading from url : " + downloadUrl;

        File artifactFile = downloadFileFromRepo(downloadUrl);

        if (artifactFile == null) {
            throw new Exception("[Error] Failed to download artifact : " + artifact);
        }

        if (checkHash && Boolean.valueOf(checkHash)) {
            String hashFileUrl = downloadUrl + ARTIFACT_FILE_HASH_EXT;
            println "[Action] Downloading from url : " + hashFileUrl;
            File hashFile = downloadFileFromRepo(hashFileUrl);
            verifyHash(artifactFile, hashFile);
            println "[Ok] Verification for file : " + artifactFile + " : succeeded!";
        }


        //copy the temp file to this directory with the file name
        File finalFile = new File(workDir, filename);
        println "[Action] Moving downloaded artifact to : " + finalFile.getAbsolutePath();
        IO.move(artifactFile, finalFile);
        artifactFile.delete();
    }
}
catch (Exception e) {
    e.printStackTrace();
    exitVal=1;
}
System.exit(exitVal);
