/*
 - Licensed Materials - Property of IBM* and/or HCL**
 * IBM UrbanCode Build
 * IBM UrbanCode Deploy
 * IBM UrbanCode Release
 * IBM AnthillPro
 * (c) Copyright IBM Corporation 2002, 2016. 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
 */
package com.ibm.urbancode.zos.common;

import groovyx.net.http.*

import java.security.cert.CertificateException
import java.security.cert.X509Certificate

import org.apache.http.conn.scheme.Scheme
import org.apache.http.conn.ssl.SSLSocketFactory
import org.apache.http.conn.ssl.TrustStrategy


public abstract class zOSMFRESTService {
    def count = 0;
    def baseURL;
    def client;
    def CURRENT_VERSION = "1.0";
    def printRESTLOG = true;

    def zOSMFRESTService(baseURL, username, password, untrustedSSL){
        this.baseURL = baseURL;
        client = new RESTClient(baseURL);
        client.encoder.setCharset("UTF-8");
        client.auth.basic username, password;
        client.headers['X-CSRF-ZOSMF-HEADER']="UCD Discovery Process";
    
        if(untrustedSSL){
            TrustStrategy trustStrat = new TrustStrategy(){
                public boolean isTrusted(X509Certificate[] chain, String authtype)
                      throws CertificateException {
                             return true;
                      }
            };
            SSLSocketFactory sslSocketFactory = new SSLSocketFactory(trustStrat,SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);                       
            client.client.connectionManager.schemeRegistry.register(new Scheme("https",443,sslSocketFactory ) );
        }
    }
    
    def processRespose(resp){
        if(printRESTLOG){
            println "Status line:"
            println resp.statusLine
            println ""
            println "Response body:"
            println resp.data ? resp.data : ""
            println ""
        }
        if(processSpecificRespose(resp)){
            return true;
        }else{ 
            if(resp.status == 200){
                return true;
            }else if(resp.status == 201){
                return true;
            }else if(resp.status == 202){
                return true;
            }else if(resp.status == 204){
                return true;
            }else{
                println "Unknown status"
                return false;
            }
        }
    }
    
    def processResponseException(e){
        //any HTTP status code > 399 will end up here.
        def resp = e.response;
        println "Status line:"
        println resp.statusLine
        println ""
        println "Response body:"
        println resp.data ? resp.data : ""
        println ""
        
        if(resp.status == 400){
            return false;
        }else if(resp.status == 401){
            println "The request cannot be processed because the client is not authorized. This status is returned if the request contained an incorrect user ID or password, or both. Or, the client did not authenticate to z/OSMF by using a valid WWW-Authenticate header."
            return false;
        }else if(resp.status == 404){
            return false;
        }else if(resp.status == 409){
            return false;
        }else if(resp.status == 500 ){
            println "The server encountered an error when it processed the request. For a more specific indication of the error, check the response for a reason code."
            return false;
        }else if(resp.status == 501){
            return false;
        }else if(resp.status == 503){
            return false;
        }else if(resp.status == 504){
            return false;
        }else{
            println "Unknown status"
            return false;
        }
    }
    
    def printRequest(path,body){
        if(printRESTLOG) {
            println "Reuqest URL:"
            println path
            println ""
            println "Request body:"
            println body? body : ""
            println ""
        }
    }
    
    abstract boolean processSpecificRespose(resp);
}

