package com.manageengine.ts;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.Properties;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLSession;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.apache.commons.codec.binary.Base64;
import com.manageengine.ts.TicketingSystemInterface;

//Zendesk Implementation
public class ZendeskImpl implements TicketingSystemInterface
{
	//Error Message to be reflected in Audit
	String errorMsg = null;
	public String getErrorMsg(){
		return errorMsg;
	}
	
	//Needed Comments to PMP. It will reflected in Audit too
	Properties requestProperties = null;
	public Properties getRequestProperties(){
		return requestProperties;
	}

	//No need to implement this method for 'Others' implementation
	//Output will get used for showing the 'Test Configuration Setup' output & also in 'Fetch Custom Fields'
	public JSONObject helpdeskCheck(String tsType, String tsUrl, String authToken, String ticketId, String operation) throws Exception
	{
		System.out.println("Ticketing system name : " + tsType);
		System.out.println("Ticketing system Web URL : " + tsUrl);
		System.out.println("AuthToken : " + authToken);
		System.out.println("Ticket ID : " + ticketId);
		System.out.println("Operation : " + operation);
		return null;
	}
	
	public boolean checkViewHelpDeskRequest(String ticketId, Properties pmpColumns, Properties credentialDetails, JSONObject criteriaDetails) throws Exception{
		
		System.out.println("Ticket ID : " + ticketId); //Ticket ID given from the user end
		System.out.println("PMP Columns : " + pmpColumns); //Details of the user account for which password related operations covered through ticketing system
		System.out.println("Credential Details : " + credentialDetails); //contains the Authtoken and ticketing system url. It will be empty in case of others implementation
		System.out.println("Criteria Details : " + criteriaDetails); //contains the criteria which is configured in 'Advanced Configuration' popup. It will be empty in case of others implementation
		
		// Creating & install all-trusting host name verifier
		HostnameVerifier allHostsValid = new HostnameVerifier() {
			public boolean verify(String hostname, SSLSession session) {
				return true;
			}
		};
		HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid);

		//Constructing Authstring from Zendesk login credentials
	    String username = "username@example.com"; //Zendesk username
	    String password = "zendeskpassword"; //Zendesk password
        Base64 encoder = new Base64();
        byte[] encodedPassword = (username + ":" + password).getBytes();
        byte[] encodedString = encoder.encodeBase64(encodedPassword);
        String authStr = new String(encodedString);

        //Establish a connection to ticketing system
        String sUrl = "https://<zendesk-instance>.zendesk.com/api/v2/tickets/"; //REST API call Zendesk
	    sUrl = sUrl + ticketId +".json"; //Adding the Ticket ID
		URL url = new URL(sUrl); 
		HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();           
		connection.setRequestProperty("Authorization","Basic "+authStr); //Setting Authstring in the header
		
		//Reading output from ticketing side
		BufferedReader reader = null; 
		if (connection.getResponseCode() >= 400) {
			reader = new BufferedReader(new InputStreamReader(connection.getErrorStream())); //Getting the Error stream in case of error
		} else {
			reader = new BufferedReader(new InputStreamReader(connection.getInputStream())); //Getting the output stream 
		}

		//Parsing the output from the ticketing side
		JSONParser jp = new JSONParser();
		JSONObject jObj = (JSONObject)jp.parse(reader);
		System.out.println(jObj.toString()); //Output string from ticketing system
		
		return validateTicket(jObj,pmpColumns,criteriaDetails); //Returning the output
	}
	
	private boolean validateTicket(JSONObject jObj,Properties pmpColumns, JSONObject criteriaDetails) throws Exception {
		boolean result = false;
		requestProperties = new Properties();
		
		if(jObj.containsKey("ticket")) { //Validating the given ticket ID is valid
			JSONObject ticket = (JSONObject)jObj.get("ticket");
			String status = (String)ticket.get("status");
			String subject = (String)ticket.get("subject");
			String assetName = (String)pmpColumns.get("Resource Name");//PMP Asset Name for which password related operation done
			boolean statusCheck = "open".equalsIgnoreCase(status); //Checking whether the status of the ticket is in open state
			boolean descriptionCheck = subject.toLowerCase().contains(assetName.toLowerCase()); //Checking the description of the ticket contains the resource name of user account
			if(statusCheck || descriptionCheck) { 
				result = true;
			}
			requestProperties.put("Ticket subject : ", subject);
			requestProperties.put("Ticket status : ", status);
			System.out.println("Status : "+status);
		} 
		else if(jObj.containsKey("error")) { //Checking any error message is returned
			Object errorObj = jObj.get("error");
			if(errorObj instanceof JSONObject) {
				JSONObject errorMsgObject = (JSONObject) errorObj;
				String title = (String) errorMsgObject.get("title"); 
				String message = (String) errorMsgObject.get("message");
				errorMsg = title; //Error message for Audit
				requestProperties.put("Message : ", message); //Comments on the error occured
			} else {
				errorMsg = jObj.get("error").toString(); //Error message for Audit
			}
		}
		return result;
	}
		
}