package com.agilex.vamf.missionhealth.clientapi;

import com.agilex.vamf.missionhealth.testutility.IntegrationTestConfiguration;
import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.filter.ClientFilter;
import com.sun.jersey.api.client.filter.HTTPBasicAuthFilter;
import com.sun.jersey.api.client.filter.HTTPDigestAuthFilter;

public class JerseyFactory {
	private static final String DIGEST_AUTHENTICATION = "digest";
	private static final String BASIC_AUTHENTICATION = "basic";
	private static final String OAUTH_AUTHENTICATION = "oauth";
	private static final org.apache.commons.logging.Log logger = org.apache.commons.logging.LogFactory.getLog(JerseyFactory.class);

	public static com.sun.jersey.api.client.Client createJerseyClient(AuthenticationInfo authenticationInfo) {
		Client jerseyclient = new com.sun.jersey.api.client.Client();
		logger.debug("creating jersey client");

		if (authenticationInfo != null) {
			ClientFilter authFilter = null;
			String username = authenticationInfo.getUsername();
			String password = authenticationInfo.getPassword();
			String facilityName = authenticationInfo.getFacilityName();
			String facilityCode = authenticationInfo.getFacilityCode();

			if (authenticationInfo.getAuthtype().toLowerCase().contentEquals(BASIC_AUTHENTICATION)) {
				logger.debug(String.format("creating basic auth filter [%s][%s]", username, password));
				authFilter = new HTTPBasicAuthFilter(username, password);
			} else if (authenticationInfo.getAuthtype().toLowerCase().contentEquals(DIGEST_AUTHENTICATION)) {
				logger.debug(String.format("creating digest auth filter [%s][%s]", username, password));
				authFilter = new HTTPDigestAuthFilter(username, password);
			} else if (authenticationInfo.getAuthtype().toLowerCase().contentEquals(OAUTH_AUTHENTICATION)) {
				logger.debug(String.format("creating digest auth filter [%s][%s]", username, password));
				String accessToken = retrieveOauthToken(username, password, facilityName, facilityCode);
				authFilter = new HTTPOAuthFilter(accessToken);
			}

			if (authFilter == null)
				throw new RuntimeException("Invalid authentication type " + authenticationInfo.getAuthtype());

			jerseyclient.addFilter(authFilter);
		}
		return jerseyclient;
	}

	private static String retrieveOauthToken(String username, String password, String facilityName, String facilityCode) {
		AuthenticationInfo authenticationInfo = constructAuthInfo(username, password, facilityName, facilityCode);
		OauthClient oauthClient = new OauthClient();
		String accessToken;
		try {
			accessToken = oauthClient.authenticate(authenticationInfo, null);
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
		return accessToken;
	}

	private static AuthenticationInfo constructAuthInfo(String username, String password, String facilityName, String facilityCode) {
		AuthenticationInfo authInfo = new AuthenticationInfo();
		authInfo.setUsername(username);
		authInfo.setPassword(password);
		authInfo.setFacilityName(facilityName);
		authInfo.setFacilityCode(facilityCode);
		authInfo.setClientId("intTest");
		authInfo.setClientSecret("pass");
		authInfo.setExpectAuthenticationRequired(true);
		authInfo.setAuthorizeUrl(IntegrationTestConfiguration.getMHPAuthorizeURI());
		authInfo.setTokenUrl(IntegrationTestConfiguration.getMHPTokenURI());
		return authInfo;
	}

}
