package com.agilex.vamf.missionhealth.uri;

import java.net.URI;
import java.net.URISyntaxException;

import javax.annotation.Resource;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.UriBuilder;

import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;

import com.agilex.healthcare.utility.ModeHelper;
import com.agilex.healthcare.utility.NullChecker;
import com.agilex.vamf.missionhealth.domain.ResourceDirectory;
import com.agilex.vamf.missionhealth.domain.atom.AtomLink;
import com.agilex.vamf.utils.AtomUtility;
import com.agilex.vamf.utils.PropertyHelper;
import com.sun.syndication.feed.synd.SyndFeed;

@Service
@Scope(value=ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class ResourceDirectoryBuilder {

	private static final String MHP_AUTHORIZE_URL = "oauth.authorize_url";
	private static final String MHP_TOKEN_URL = "oauth.token_url";
	private static final String OAUTH_SSOE_LOGOUT_URL = "oauth.ssoe_logout_url";
	private static final String OAUTH_LOGIN_URL = "oauthlogin";
	
	private static final org.apache.commons.logging.Log LOGGER = org.apache.commons.logging.LogFactory.getLog(ResourceDirectoryBuilder.class);
	
	@Resource
	private PropertyHelper propertyHelper;
	
	public ResourceDirectoryBuilder() {
	}

	public ResourceDirectory getResourceDirectory(URI systemBaseUri, URI resourceDirectoryUri, URI mhpBaseUri, String assigningAuthority, String patientId) {

		ResourceDirectory directory = new ResourceDirectory();
		AtomLink link;
		
		String mhpContext = propertyHelper.getProperty("mhp.context");

		link = new AtomLink();
		link.setHref(resourceDirectoryUri);
		link.setTitle("resource-directory");
		directory.getLink().setSelfLink(link);
		
		link = new AtomLink();
		link.setHref(systemBaseUri);
		link.setType(MediaType.APPLICATION_ATOM_XML);
		link.setTitle(LinkTitles.SystemRoot);
		directory.getLink().add(link);
		
		link = new AtomLink();
		link.setHref(UriBuilder.fromUri(convertBaseURItoMhpURI(systemBaseUri, mhpContext)).path("user-session").build());
		link.setType(MediaType.APPLICATION_XML);
		link.setTitle(LinkTitles.UserSession);
		directory.getLink().add(link);
		
		link = new AtomLink();
		link.setHref(UriBuilder.fromUri(convertBaseURItoMhpURI(systemBaseUri, mhpContext)).path("public").path("user-session").build());
		link.setType(MediaType.APPLICATION_XML);
		link.setTitle(LinkTitles.PublicUserSession);
		directory.getLink().add(link);
		
		link = new AtomLink();
		link.setHref(UriBuilder.fromUri(systemBaseUri).path("mhpuser").build());
		link.setType(MediaType.APPLICATION_JSON);
		link.setTitle("mhpuser");
		directory.getLink().add(link);

		link = new AtomLink();
		boolean useDefault = true;
		String mhpAuthorizeUrl = propertyHelper.getProperty(MHP_AUTHORIZE_URL);
		try {
			if (NullChecker.isNotNullish(mhpAuthorizeUrl)) {
				URI mhpAuthorizeUri = new URI(mhpAuthorizeUrl);
				link.setHref(mhpAuthorizeUri);
				useDefault = false;
			}
		} catch (URISyntaxException e) {
			LOGGER.error("Mhp authorize URL is invalid", e);
		}
		if (useDefault) {
			link.setHref(UriBuilder.fromUri(stripRestFromBaseURI(systemBaseUri)).path("oauth").path("authorize").build());
		}
		link.setTitle(LinkTitles.OAuthAuthorize);
		link.setType(MediaType.TEXT_HTML);
		directory.getLink().add(link);
		
		link = new AtomLink();
		link.setHref(UriBuilder.fromUri(stripRestFromBaseURI(convertBaseURItoMhpURI(systemBaseUri, mhpContext))).path(OAUTH_LOGIN_URL).build());
		link.setType(MediaType.APPLICATION_JSON);
		link.setTitle("login");
		directory.getLink().add(link);
		
		addUserLoginCredentialsLink(systemBaseUri, directory);
		addUserLogoutLink(systemBaseUri, directory);
		addTokenLink(systemBaseUri, directory);

		if (assigningAuthority != null && patientId != null) {
			link = new AtomLink();
			link.setHref(UriBuilder.fromUri(systemBaseUri).path("patient").path(assigningAuthority).path(patientId).path("mission-health").build());
			link.setTitle("resource-directory");
			directory.getLink().setSelfLink(link);
			
			link = new AtomLink();
			link.setHref(UriBuilder.fromUri(systemBaseUri).path("patient").path(assigningAuthority).path(patientId).path("mission-health").path("mission-health-profile").build());
			link.setTitle("mission-health-profile");
			link.setType(MediaType.APPLICATION_XML);
			directory.getLink().add(link);

			link = new AtomLink();
			link.setHref(UriBuilder.fromUri(systemBaseUri).path("patient").path(assigningAuthority).path(patientId).path("mission-health").path("mission-health-detail").build());
			link.setTitle("mission-health-detail");
			link.setType(MediaType.APPLICATION_XML);
			directory.getLink().add(link);
			
			link = new AtomLink();
			link.setHref(UriBuilder.fromUri(systemBaseUri).path("patient").path(assigningAuthority).path(patientId).path("mission-health").path("smartinfo-points").build());
			link.setTitle("smartinfo-points");
			link.setType(MediaType.APPLICATION_XML);
			directory.getLink().add(link);
			
			link = new AtomLink();
			link.setHref(UriBuilder.fromUri(systemBaseUri).path("patient").path(assigningAuthority).path(patientId).path("mission-health").path("emailfacebook-points").build());
			link.setTitle("emailfacebook-points");
			link.setType(MediaType.APPLICATION_XML);
			directory.getLink().add(link);
			
			link = new AtomLink();
			link.setHref(UriBuilder.fromUri(systemBaseUri).path("patient").path(assigningAuthority).path(patientId).path("mission-health").path("mission-readiness-report").build());
			link.setTitle("mission-readiness-report");
			link.setType(MediaType.APPLICATION_XML);
			directory.getLink().add(link);

            link = new AtomLink();
            link.setHref(UriBuilder.fromUri(systemBaseUri).path("patient").path(assigningAuthority).path(patientId).path("mission-health").path("mission").build());
            link.setTitle("mission");
            link.setType(MediaType.APPLICATION_XML);
            directory.getLink().add(link);
            
            link = new AtomLink();
            link.setHref(UriBuilder.fromUri(systemBaseUri).path("patient").path(assigningAuthority).path(patientId).path("mission-health").path("promoted").build());
            link.setTitle("promoted");
            link.setType(MediaType.APPLICATION_XML);
            directory.getLink().add(link);
            
            link = new AtomLink();
            link.setHref(UriBuilder.fromUri(systemBaseUri).path("patient").path(assigningAuthority).path(patientId).path("mission-health").path("lost-troops").build());
            link.setTitle("lost-troops");
            link.setType(MediaType.APPLICATION_XML);
            directory.getLink().add(link);

            link = new AtomLink();
            link.setHref(UriBuilder.fromUri(systemBaseUri).path("patient").path(assigningAuthority).path(patientId).path("mission-health").path("standings").build());
            link.setTitle("standings");
            link.setType(MediaType.APPLICATION_XML);
            directory.getLink().add(link);
            
            link = new AtomLink();
            link.setHref(UriBuilder.fromUri(systemBaseUri).path("patient").path(assigningAuthority).path(patientId).path("mission-health").path("annual-rollup").build());
            link.setTitle("annual-rollup");
            link.setType(MediaType.APPLICATION_XML);
            directory.getLink().add(link);
		}
		
		return directory;
	}

	private void addTokenLink(URI systemBaseUri, ResourceDirectory directory) {
		AtomLink link = new AtomLink();
		link.setTitle("token");
		link.setHref(UriBuilder.fromUri(stripWebContextFromBaseURI(systemBaseUri)).path("AuthorizationServices/rest/token").build());
	
		directory.getLink().add(link);
	}
	
    private void addUserLoginCredentialsLink(URI systemBaseUri, ResourceDirectory directory) {
		AtomLink link;
		link = new AtomLink();
		
		if(ModeHelper.isProviderMode()){
			link.setHref(UriBuilder.fromUri(stripWebContextFromBaseURI(systemBaseUri)).path("AuthorizationServices/provider/security_check").build());
		}else{
			link.setHref(UriBuilder.fromUri(stripWebContextFromBaseURI(systemBaseUri)).path("ssoeproxy/j_spring_security_check").build());
		}

		link.setTitle("login-credentials");
		link.setType(MediaType.TEXT_HTML);
		directory.getLink().add(link);
	}

	private void addUserLogoutLink(URI systemBaseUri, ResourceDirectory directory) {
		AtomLink link = new AtomLink();
		link.setTitle("logout");
		link.setType(MediaType.TEXT_HTML);

		if(ModeHelper.isProviderMode()){
			link.setHref(UriBuilder.fromUri(stripWebContextFromBaseURI(systemBaseUri)).path("AuthorizationServices/logout").build());
		}else{
			String ssoeLogoutUrl = propertyHelper.getProperty(OAUTH_SSOE_LOGOUT_URL);
			if (NullChecker.isNotNullish(ssoeLogoutUrl)) {
				link.setHref(UriBuilder.fromUri(ssoeLogoutUrl).build());
			}else{
				link.setHref(UriBuilder.fromUri(stripWebContextFromBaseURI(systemBaseUri)).path("ssoeproxy/logout").build());
			}
		}
	
		directory.getLink().add(link);
	}
    
	public SyndFeed getResourceDirectoryAsAtomFeed(URI systemBaseUri, URI resourceDirectoryUri) {
        URI mhpUri = UriBuilder.fromUri(propertyHelper.getProperty("mhp.baseUri")).build();
		ResourceDirectory resourceDirectory = getResourceDirectory(systemBaseUri, resourceDirectoryUri, mhpUri, null, null);
		SyndFeed feed = AtomUtility.createAtomFeed(resourceDirectory.getLink(), resourceDirectoryUri, "mhp-resources");
		return feed;
	}

	private static URI stripRestFromBaseURI(URI baseURI) {

		String stringURI = baseURI.toString();
		stringURI = stringURI.replaceAll("/rest", "");

		URI uri = URI.create(stringURI);

		return uri;
	}
	
	private static URI stripWebContextFromBaseURI(URI baseURI) {

		String stringURI = baseURI.toString();
		stringURI = stringURI.replaceAll("/MissionHealthServiceWeb/rest", "");

		URI uri = URI.create(stringURI);

		return uri;
	}
	private static URI convertBaseURItoMhpURI(URI baseURI, String mhpUriString) {

		String stringURI = baseURI.toString();
		stringURI = stringURI.replaceAll("/MissionHealthServiceWeb/rest", mhpUriString);

		URI uri = URI.create(stringURI);

		return uri;
	}
	
}