/**
 * 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)
                .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
}
