/**
 * This method creates config Map object and calls upload(Map) method
 *
 * @param  server  a server ID - file name at resources/../servers
 * @param  spec    a JSON representation of upload spec
 * @return         a List object that contains upload results
 */
List upload(String server, String spec) {
    return upload(server: server, spec: spec)
}


/**
 * This method converts JSON representation of spec into Map object and calls
 * upload(String, Map)
 *
 * @param  config  a Map object with params `[ server: String, spec: String or Map ]`
 * @return         a List object that contains upload results
 */
List upload(Map config) {
    if (config.spec?.getClass() in [java.util.LinkedHashMap, net.sf.json.JSONObject]) {
        return upload(config.server, config.spec)
    }
    return upload(config.server, parseJSON(config.spec))
}


/**
 * This method uploads files into artifactory instance
 *
 * Input spec example:
 *     [ files: [[
 *          pattern: "**",
 *          target: "my-repository/path/to/upload",
 *          props: "myPropKey1=myPropValue1;myPropKey2=myPropValue2", // optional
 *     ],]
 *
 * Result example:
 *     [[
 *        localPath: "local/path/to/file.name",
 *        remotePath: "/path/to/upload/local/path/to/file.name",
 *        repo: "my-repository",
 *        size: 12345,
 *        uri: ... ,
 *        checksums: [
 *            md5: ... ,
 *            sha1: ... ,
 *            sha256: ... "
 *        ],
 *     ],]
 *
 * @param  server  a server ID - server name at resources/../servers
 * @param  spec    a Map object with upload spec
 * @return         a List object that contains upload results
 */
List upload(String server, Map spec) {
    List result = []

    Map artConfig = parseJSON(loadResource("artifactory/servers/${server}.json"))
    String uploadScript = loadResource("artifactory/scripts/upload.sh")

    List artCredentials = [usernamePassword(
        credentialsId: artConfig.credentialsId,
        usernameVariable: 'ARTIFACTORY_USERNAME',
        passwordVariable: 'ARTIFACTORY_PASSWORD')]

    List files = createFileListBySpec(spec)

    retry(artConfig.get('connectionRetry', 1)) {
        withCredentials(artCredentials) {
            files.each{ file ->
                String scriptRawResult
                List envList = [
                    "ARTIFACTORY_URL=${artConfig.artifactoryUrl}",
                    "ARTIFACTORY_TARGET=${file.target}",
                    "ARTIFACTORY_PROPS=${file.props}",
                    "FILE_TO_UPLOAD=${file.name}"
                ]
                withEnv(envList) {
                    scriptRawResult = sh \
                        script: uploadScript,
                        returnStdout: true
                }

                Map scriptResult = parseScriptResult(scriptRawResult)
                Map uploadResult = parseJSON(scriptResult.stdout)
                ['created', 'createdBy', 'downloadUri', 'mimeType', 'originalChecksums'].each {
                    uploadResult.remove(it)
                }
                uploadResult.localPath = file.name
                uploadResult.put('remotePath', uploadResult.remove('path'));
                result << uploadResult
            }
        }
    }
    return result
}


/**
 * This method looks up for local files to upload according to the spec
 *
 * @param  spec   a Map object with upload spec
 * @return        a List object that contains found local files to upload
 */
List createFileListBySpec(Map spec) {
    List result = []

    Map jenkinsProps = [
        "build.name": env.JOB_NAME,
        "build.number": env.BUILD_NUMBER,
        "build.timestamp": currentBuild.startTimeInMillis
    ]

    spec.files?.each{ specItem ->
        Map targetProps = specItem.props?.split(';')?.findAll{ it.contains('=') }?.collectEntries{
                List parts = it.split('=', 2)
                return [(parts[0]): parts[1]]
            } ?: [:]

        String props = (jenkinsProps + targetProps)
            .collect{ "${it.key}=${it.value}" }
            .join(';')

        if (!(specItem.pattern && specItem.target)) {
            error "ArtifactoryUploader: Malformed upload spec:\n${spec}"
        }

        List targetFiles = []
        try {
            targetFiles = findFiles(glob: specItem.pattern.replaceFirst("^${env.WORKSPACE}/?", ""))
                .findAll{ !it.directory }
                .collect{ it.path }
        } catch (Exception e) {
            error "ArtifactoryUploader: Unable to find files by pattern: ${specItem.pattern}"
        }

        targetFiles.each{ file ->
            result << [ name: file, target: specItem.target, props: props ]
        }
    }
    return result
}


/**
 * This method parses uploading results
 *
 * @param  scriptRawResult   a JSON representation of uploading results
 * @return                   a Map object that contains uploading results
 */
Map parseScriptResult(String scriptRawResult) {
    Map result = parseJSON scriptRawResult

    if (result.exit_code == 0 &&
        result.response_code &&
        result.response_code in 200..299 &&
        result.stdout) { return result }

    String errorMessage = "ArtifactoryUploader: Upload failed"
    if (result.stdout) {
        errorMessage += "\nStdout: ${result.stdout}"
    }
    if (result.stderr) {
        errorMessage += "\nStderr: ${result.stderr}"
    }
    if (result.response_code) {
        errorMessage += "\nResponse code: ${result.response_code}"
    }
    error errorMessage
}


/**
 * This method loads resourcse file from the library
 *
 * @param  path   path to the resource file
 * @return        content of the resource file
 */
String loadResource(String path) {
    try {
        return libraryResource(path)
    } catch (Exception e) {
        error "ArtifactoryUploader: Unable to load resource: ${path}"
    }
}


/**
 * This method converts a JSON representation into an object
 *
 * @param  text   a JSON content
 * @return        a Map or List object
 */
Map parseJSON(String text) {
    def json = new groovy.json.JsonSlurper()
    Map result
    try {
        // result = readJSON text: text
        result = json.parseText(text)
    } catch (Exception e) {
        json = null
        error "ArtifactoryUploader: Unable to parse JSON:\n${text}"
    }
    json = null
    return result
}
