/**
 * Licensed Materials - Property of IBM* and/or HCL**
 * UrbanCode Deploy
 * (c) Copyright IBM Corporation 2011, 2018. All Rights Reserved.
 * (c) Copyright HCL Technologies Ltd. 2018, 2019. 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
 */

package com.urbancode.air.plugin.docker

import org.apache.http.client.utils.HttpClientUtils
import org.apache.http.client.utils.URIBuilder
import org.apache.http.StatusLine

import com.urbancode.air.plugin.docker.Docker

public class RegistryClient extends Docker {

    public RegistryClient(def props) {
        super(props)

        // Confirm registry does exist with the given information
        println "[Ok] Connecting to registry..."
        pingRegistry()
        println "[Ok] Connected successfully."
        println ""
    }

    private def getBaseUri() {
        return new URIBuilder("${protocol}${registry}").build()
    }

    private def getPingUri() {
        return new URIBuilder(getBaseUri()).setPath("/v2/").build()
    }

    private def getTagsUri() {
        return new URIBuilder(getBaseUri()).setPath("/v2/${imageName}/tags/list").build()
    }

    private def getManifestsUri = { tag ->
        return new URIBuilder(getBaseUri()).setPath("/v2/${imageName}/manifests/${tag}").build()
    }

    private def getArtifactsUri = { tag ->
        return new URIBuilder(getBaseUri()).setPath("/api/v2.0/projects/${harborProject}/repositories/${harborRepository}/artifacts/${tag}").build()
    }

    private URI getLinkUri(String link) {
        return new URIBuilder("${protocol}${registry}" + link).build()
    }

    private pingRegistry() {
        // Assumes using protocol of https://
        def response
        int status
        StatusLine statusLine
        String body
        try {
            response = requestWithAuth(getPingUri())
            status = response.statusLine.statusCode
            statusLine = response.statusLine
            body = response.entity?.content?.getText("UTF-8")
        }
        catch (Exception ex) {
            println "[Error] Response from registry server: ${ex.getMessage()}"
            // Continue and try to connect with insecure
        }
        finally {
            HttpClientUtils.closeQuietly(response)
        }
        if (status != 200) {
            if (status) {
                println "[Warning] Unexpected response from registry server:"
                println statusLine.toString()
                println body
            }

            // Try using http:// instead
            if (allowInsecure) {
                try {
                    this.protocol = "http://"
                    response = requestWithAuth(getPingUri())
                    status = response.statusLine.statusCode
                    statusLine = response.statusLine
                    body = response.entity?.content?.getText("UTF-8")
                    if (status != 200) {
                        println "[Ok] Response from registry server:"
                        println statusLine.toString()
                        println body
                        throw new java.net.ConnectException("[Error] Unable to ping registry using http and https protocols. Please check credentials and make sure that registry supports v2 api.")
                    }
                    println "[Warning] Connected to registry using the unsecure http protocol."
                }
                catch (Exception ex) {
                    println "[Error] Response from registry server: ${ex.getMessage()}"
                    throw ex
                }
                finally {
                    HttpClientUtils.closeQuietly(response)
                }
            }
            else {
                throw new java.net.ConnectException('[Possible Solution] Allow Insecure to attempt the connection over HTTP protocol.')
            }
        }
    }
}
