/**
 * (c) Copyright IBM Corporation 2016, 2017.
 * (c) Copyright HCL Technologies Ltd. 2018, 2019. All Rights Reserved.
 * This is licensed under the following license.
 * The Eclipse Public 1.0 License (http://www.eclipse.org/legal/epl-v10.html)
 * U.S. Government Users Restricted Rights:  Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
 */
package com.urbancode.air.plugin.ibmace;

import groovy.json.JsonSlurper
import java.text.SimpleDateFormat
import java.util.Properties
import org.apache.http.HttpResponse
import org.apache.http.HttpStatus
import org.apache.http.util.EntityUtils
import org.apache.log4j.Logger
import org.codehaus.jettison.json.JSONArray
import org.codehaus.jettison.json.JSONObject

class ACERestClient {

    private RestClientHelper restHelper
    private Logger logger

    private String host
    private String port
    private String serverUrl
    

    public ACERestClient(Properties props) {

        // Local fields
        this.host = props['brokerHost'].toString().trim()

        
        if (props['port']) {
            this.port = props['port'].toString().trim()
        }

        /* Default to http unless otherwise specified */
        if (!host.startsWith("http://") && !host.startsWith("https://")) {
            host = "http://" + host;
        }

        logger = Logger.getLogger(getClass())

        if (this.host && this.port) {

            this.serverUrl = host + ":" + port
            
            println("${getTimestamp()} Establishing connection with a remote broker...")

            restHelper = new RestClientHelper(this.serverUrl, "", "", true)

        }else {
            throw new IllegalStateException("Must specify either an 'IP' and 'Port'.")
        }
        
        println("${getTimestamp()} Broker connection successful.")
    }

    public void createIntegrationServer(String integrationServer) {

        Date startTime = new Date()
 
        try {

            JSONObject integrationServerPayload = new JSONObject()
            integrationServerPayload.put('name', integrationServer)

            HttpResponse response = restHelper.doPostRequest(ACEConstants.GET_SERVERS, integrationServerPayload.toString())

            if (!response) {
                println ("[Error] Could not get integration servers - ${response}")
                throw new Exception()
            }
            if (!response.getStatusLine().getStatusCode().equals(HttpStatus.SC_ACCEPTED)) {
                println ("[Error] Bad response code of ${response.getStatusLine().getStatusCode()} - ${response}.")
                println ('Response:\n' + response.entity?.content?.getText("UTF-8"))
                throw new Exception()
            }

            if (response.getStatusLine().getStatusCode().equals(HttpStatus.SC_CONFLICT)) {
                println ("[Error] Bad response code of ${response.getStatusLine().getStatusCode()} - ${response}.")
                println ('Response:\n' + response.entity?.content?.getText("UTF-8"))
                println ('Error creating Integration Server: server name in use')
                throw new Exception()
            }


        }catch (Exception ex) {
            ex.printStackTrace()
            throw ex
        }

        System.out.println("${getTimestamp()} Integration Server ${integrationServer} created.")


    }

    public void startIntegrationServer(String integrationServer) {
    
		Date startTime = new Date()
		 
		try {

			HttpResponse response = restHelper.doPostRequest(ACEConstants.GET_SERVERS + "/" + integrationServer + ACEConstants.START)
		
			if (!response) {
				println ("[Error] Could not start integration server - ${response}")
				throw new Exception()
			}
			if (!response.getStatusLine().getStatusCode().equals(HttpStatus.SC_ACCEPTED)) {
				println ("[Error] Bad response code of ${response.getStatusLine().getStatusCode()} - ${response}.")
				println ('Response:\n' + response.entity?.content?.getText("UTF-8"))
				throw new Exception()
			}
		
		}catch (Exception ex) {
			ex.printStackTrace()
			throw ex
		}
		
		System.out.println("${getTimestamp()} Integration Server ${integrationServer} started.")
		
		
	}

    public void stopIntegrationServer(String integrationServer) {
		
		Date startTime = new Date()
		 
		try {
			
			restHelper.doPostRequestWithNoResponse(ACEConstants.GET_SERVERS + "/" + integrationServer + ACEConstants.STOP)
		
		}catch (Exception ex) {
			ex.printStackTrace()
			throw ex
		}
		
		System.out.println("${getTimestamp()} Integration Server ${integrationServer} stopped.")	
		
	}

     public void deleteIntegrationServer(String integrationServer) {
	        Date startTime = new Date()
 
                try {
    
			HttpResponse response = restHelper.doDeleteRequest(ACEConstants.GET_SERVERS + "/" + integrationServer)
		
			if (!response) {
				println ("[Error] Could not delete integration server - ${response}")
				throw new Exception()
			}
			if (!response.getStatusLine().getStatusCode().equals(HttpStatus.SC_OK)) {
				println ("[Error] Bad response code of ${response.getStatusLine().getStatusCode()} - ${response}.")
				println ('Response:\n' + response.entity?.content?.getText("UTF-8"))
				println ('Error deleting Integration Server')
				throw new Exception()
			}
			
	   }catch (Exception ex) {
			ex.printStackTrace()
			throw ex
	   }
		
			System.out.println("${getTimestamp()} Integration Server ${integrationServer} deleted.")
	}
		
    public void cleanUp() {
        //TODO
        
    }

    public void deployBarFile(String integrationServer, String barfilePath) {

        Date startTime = new Date()

        try {
            File barFile = new File(barfilePath)
            HttpResponse response = restHelper.doPostRequest(ACEConstants.getServerActionPathByNameOrId(integrationServer, ACEConstants.DEPLOY), barFile)

            
            if (!response) {
                println ("[Error] Could not deploy integrations on servers - ${response}")
                throw new Exception()
            }
            
            if (!response.getStatusLine().getStatusCode().equals(HttpStatus.SC_OK)) {
                println ("[Error] Bad response code of ${response.getStatusLine().getStatusCode()} - ${response}.")
                println ('Response:\n' + response.entity?.content?.getText("UTF-8"))
                throw new Exception()
            }


        }catch (Exception ex) {
            ex.printStackTrace()
            throw ex
        }

        System.out.println("${getTimestamp()} Bar file  ${barfilePath} deployed successfully.")

    }
    
    
    public static String getTimestamp() {
        SimpleDateFormat dateFormat = new SimpleDateFormat("[MM/dd/yyyy HH:mm:ss]")

        return dateFormat.format(new Date())
    }

    /**
     * Encode HTML form parameters.
     * @param path
     * @return The encoded parameter.
     * @throws UnsupportedEncodingException
     */
    private String encodePath(String path) throws UnsupportedEncodingException {
        return URLEncoder.encode(path, "UTF-8");
    }


    public boolean doesIntegrationServerExist(String integrationServer) {
        
        try {
            HttpResponse response = restHelper.doGetRequest(ACEConstants.getServerPathByNameOrId(integrationServer.trim()))

            Map<String, String> jsonSlurper = restHelper.parseResponse(response)
            

            if (!response) {
                println ("[Error] Could not find integration servers - ${response}")
                throw new Exception()
            }
            
            if (response.getStatusLine().getStatusCode().equals(HttpStatus.SC_OK)) {
                return true

            }
            
            if (response.getStatusLine().getStatusCode().equals(HttpStatus.SC_NOT_FOUND)) {
                return false
     
            }
            
            println ("[Error] Bad response code of ${response.getStatusLine().getStatusCode()} - ${response}.")
            println ('Response:\n' + response.entity?.content?.getText("UTF-8"))
            throw new Exception()


        }catch (Exception ex) {
            ex.printStackTrace()
            throw ex
        }
        
    }
    
}
