package com.avaya.mgmt.smgr.webservice.client;

import java.net.URI;
import java.util.GregorianCalendar;
import java.util.Properties;

import javax.ws.rs.core.UriBuilder;

import com.avaya.mgmt.smgr.webservice.client.ds.WebServiceClientConfig;
import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.WebResource;
import com.sun.jersey.api.client.config.ClientConfig;
import com.sun.jersey.api.client.config.DefaultClientConfig;
import com.sun.jersey.api.client.filter.HTTPBasicAuthFilter;
import com.sun.jersey.api.representation.Form;

/**
 *
 * @author
 *
 */
public class WebServiceClient
{

	private ClientConfig config;

	private Client client;

	private WebServiceClientConfig upmClientConfig;

	private static WebServiceClient webServiceClient;

	/**
	 *
	 * @param upmClientConfig
	 */
	private WebServiceClient(final WebServiceClientConfig upmClientConfig)
	{
		Properties properties = System.getProperties();
		System.out.println("upmClientConfig.getTruststoreFileLocation() " + upmClientConfig.getTruststoreFileLocation() ) ;
		properties.put("javax.net.ssl.trustStore",
				upmClientConfig.getTruststoreFileLocation());
		System.out.println("upmClientConfig.getTruststorePassword() " + upmClientConfig.getTruststorePassword() ) ;
		properties.put("javax.net.ssl.trustStorePassword",
				upmClientConfig.getTruststorePassword());
		this.upmClientConfig = upmClientConfig;
		config = new DefaultClientConfig();
		client = Client.create(config);
		client.addFilter(new HTTPBasicAuthFilter(upmClientConfig.getUserName(),
				upmClientConfig.getPassword()));
	}

	/**
	 *
	 * @param upmClientConfig
	 * @return
	 */
	public static WebServiceClient getInstance(
			final WebServiceClientConfig upmClientConfig)
	{
		if (null == webServiceClient)
		{
			webServiceClient = new WebServiceClient(upmClientConfig);
		}
		return webServiceClient;
	}

	/**
	 *
	 * @return
	 */
	protected WebResource getWebResource()
	{
		return client.resource(getBaseURI());
	}

	/**
	 *
	 * @return
	 */
	protected WebResource getSelfProvisionWebResource(String operationType)
	{
		return client.resource(getSelfProvisionBaseURI(operationType));
	}

	/**
	 *
	 * @param entityType
	 * @param entityXmlData
	 * @return
	 */
	public final String postUser(final String entityType,
			final String entityXmlData)
	{
		final Form form = new Form();
		form.add("entityType", entityType);
		form.add("entityXMLData", entityXmlData);
		System.out.println(GregorianCalendar.getInstance().getTime() + "...Sent...");
		System.out.println("POSTUSER " +  getWebResource());
		System.out.println("form " +  form);

		return getWebResource().post(String.class, form);
	}

	/**
	 *
	 * @param entityType
	 * @param entityXmlData
	 * @param updateType
	 * @return
	 */
	public final String putUser(final String entityType,
			final String entityXmlData, final String updateType)
	{
		final Form form = new Form();
		form.add("entityType", entityType);
		form.add("entityXMLData", entityXmlData);
		form.add("updateMode", updateType);
		System.out.println("PUTUSER " +  getWebResource());
		return getWebResource().put(String.class, form);
	}

	/**
	 *
	 * @param entityType
	 * @param searchCriteria
	 * @return
	 */
	public final String lookup(final String entityType,
			final String searchCriteria)
	{
		Properties properties = System.getProperties();
		System.out.println("LOOKUP " + getWebResource().queryParam("entityType", entityType)
				.queryParam("searchCriteria", searchCriteria));
				
		System.out.println("javax.net.ssl.trustStore " + properties.get("javax.net.ssl.trustStore"));
		System.out.println("javax.net.ssl.trustStorePassword " + properties.get("javax.net.ssl.trustStorePassword"));		
		return getWebResource().queryParam("entityType", entityType)
				.queryParam("searchCriteria", searchCriteria).get(String.class);
	}

	/**
	 *
	 * @param entityType
	 * @param uniqueKey
	 * @return
	 */
	public final String find(final String entityType, final String uniqueKey)
	{
		System.out.println("FIND " +  getWebResource().path(entityType).path(uniqueKey));
		return getWebResource().path(entityType).path(uniqueKey)
				.get(String.class);
	}

	/**
	 *
	 * @param entityType
	 * @param entityXmlData
	 * @return
	 */
	public final String delete(final String entityType,
			final String entityXmlData)
	{
		final Form form = new Form();
		form.add("entityType", entityType);
		form.add("entityXMLData", entityXmlData);
		form.add("operationName", "DELETE");
		System.out.println("DELETE" + getWebResource());
		return getWebResource().post(String.class, form);
	}

	public void passwordChange(final String operationType, Properties properties) {
		long l = System.currentTimeMillis();
		System.out.println("Processing "+ operationType +"  Password Change request...");
		final String result = passwordChange(properties.getProperty("operation.type"),
				properties.getProperty("handle"), properties.getProperty("oldpassword"),
				properties.getProperty("newpassword"));
		System.out
				.println("Lookup result  :   " + ((System.currentTimeMillis() - l) / 1000) + " Seconds \n\n" + result);
	}


	/**
	 *
	 * @param handle
	 * @param currentpassword
	 * @param newpassword
	 * @return
	 */
	private final String passwordChange(final String operationType, final String handle,
			final String currentPassword, final String newPassword)
	{
		System.out.println("Password Change " + operationType);
		final Form form = new Form();
		Properties properties = System.getProperties();
		System.out.println("javax.net.ssl.trustStore " + properties.get("javax.net.ssl.trustStore"));
		System.out.println("javax.net.ssl.trustStorePassword " + properties.get("javax.net.ssl.trustStorePassword"));
		System.out.println("URI " + getSelfProvisionWebResource(operationType));
		return getSelfProvisionWebResource(operationType)
				.queryParam("handle", handle)
				.queryParam("currentpassword", currentPassword)
				.queryParam("newpassword", newPassword)
				.put(String.class);
	}

	/**
	 *
	 * @param handle
	 * @return
	 */
	public final String resetPassword(String handleToResetPassword) {
		System.out.println("Reset Password for handle " + handleToResetPassword);
		System.out.println("URI " + getSelfProvisionWebResource("Reset"));
		return getSelfProvisionWebResource("Reset").queryParam("handle", handleToResetPassword)
				.get(String.class);
	}

	/**
	 *
	 * @param uuid
	 * @return
	 */
	public final String activatePassword(String uuid) {
		System.out.println("Activate Password for uuid " + uuid);
		System.out.println("URI " + getSelfProvisionWebResource("Activate"));
		return getSelfProvisionWebResource("Activate").queryParam("uuid", uuid)
				.get(String.class);
	}


	/**
	 *
	 * @return
	 */
	public final String passwordChangeManager() {
		System.out.println("Password Change Manager");
		System.out.println("URI " + getSelfProvisionWebResource("PasswordManager"));
		String jsonInput = "{ "
				+ "\"users\": [ "
					+ "{ \"handle\": \"u1@avaya.com\","
						+ "\"commprofiles\": [ "
			            		+ "{ \"profiletype\": \"SIP\", \"currentpassword\": \"welcome\", \"newpassword\": \"Admin123\" },"
			            		+ "{ \"profiletype\": \"Agent\", \"currentpassword\": \"4321\", \"newpassword\": \"5678\" }"

			            + "] "
			        + "}, "
			        + "{ \"handle\": \"u2@avaya.com\","
			        	+ "\"commprofiles\": [ "
		                	+ "{ \"profiletype\": \"H.323\", \"currentpassword\": \"5678\", \"newpassword\": \"4321\" }, "
		                	+ "{ \"profiletype\": \"Messaging\", \"currentpassword\": \"7045\", \"newpassword\": \"9420\" } "
		                + "] "
		        	+"} "
		        + "] "
			+ "}";

		return getSelfProvisionWebResource("PasswordManager").type("application/json").post(String.class, jsonInput);
	}

	/**
	 *
	 */
	public void destroy()
	{
		client.destroy();
	}

	/**
	 *
	 * @return
	 */
	private static URI getBaseURI()
	{
		return UriBuilder
				.fromUri(webServiceClient.upmClientConfig.getBaseURI()).build();
	}

	private static URI getSelfProvisionBaseURI(final String operationType)
	{
		return UriBuilder
				.fromUri(webServiceClient.upmClientConfig.getSelfprovisionBaseURL()+"/"+operationType).build();
	}
}
