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

package com.urbancode.air.plugin.docker

import javax.net.ssl.SSLException
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 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?.text
        }
        catch (SSLException 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?.text
                    if (status != 200) {
                        println "[Ok] Response from registry server:"
                        println statusLine.toString()
                        println body
                        throw new RuntimeException("[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 (SSLException 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.')
            }
        }
    }
}
