package eu.dnetlib.enabling.aas.secprof;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.springframework.context.ApplicationContext;

import eu.dnetlib.enabling.aas.rmi.TypedString;
import eu.dnetlib.enabling.aas.secprof.ProfileIdentifierLocation;
import eu.dnetlib.enabling.aas.secprof.ProfilesRetrieverProxy;
import eu.dnetlib.enabling.aas.secprof.SecurityProfile;
import eu.dnetlib.enabling.aas.utils.ResourcesGenerator;
import eu.dnetlib.enabling.aas.utils.SpringUtils;
import eu.dnetlib.enabling.is.registry.rmi.ISRegistryService;

/**
 * Test class for ProfilesRetrieverProxy.
 * @author mhorst
 *
 */
public class ProfilesRetrieverProxyTest {

	protected ApplicationContext context;
	protected ProfilesRetrieverProxy profilesRetrieverProxy = null;
	protected ISRegistryService registryService = null;
	
	void initContext() {
		context = SpringUtils.getSpringContext(SpringUtils.DEFAULT_INTEGRATION_RESOURCE);
	}
	
	@Before
	public void setUp() throws Exception {
		initContext();
		profilesRetrieverProxy = (ProfilesRetrieverProxy) context.getBean("ProfilesRetrieverProxy");
		registryService = (ISRegistryService) context.getBean("registryService");
	}

	@After
	public void tearDown() throws Exception {
	}

	@Test
	public void testFindSecurityProfile() throws Exception {
//		works with mocks only, IS needs to have DriverTestDSResourceType registered
		String resourceId = null;
		String secProfId = null;
		try {
			String testUserProfile = ResourcesGenerator.generateTestProfile("someuser@gmail.com");
			resourceId = registryService.registerProfile(testUserProfile);
			assertNotNull(resourceId);
			String securityProfile = ResourcesGenerator.generateSecProf(resourceId,null);
			secProfId = registryService.registerProfile(securityProfile);
			assertNotNull(secProfId);
			TypedString principal = new TypedString("someuser@gmail.com","login");
			ProfileIdentifierLocation loc = new ProfileIdentifierLocation();
			loc.setProfileKind(ResourcesGenerator.RESOURCE_KIND_DRIVER_TEST);
			loc.setProfileType(ResourcesGenerator.RESOURCE_TYPE_DRIVER_TEST);
			loc.setPath("RESOURCE_PROFILE/BODY/CONFIGURATION/resourceId");
			SecurityProfile secProf = profilesRetrieverProxy.findSecurityProfile(principal, loc);
			assertNotNull(secProf);
			assertEquals(resourceId, secProf.getResourceId());
			Object storedInCache = profilesRetrieverProxy.getFromPrincipalToResourceIdMap(principal);
			assertNotNull(storedInCache);
			assertTrue(storedInCache instanceof String);
			assertEquals(resourceId, storedInCache);
			Object removedFormCache = profilesRetrieverProxy.removeCachedPrincipal(resourceId);
			assertNotNull(removedFormCache);
			assertTrue(removedFormCache instanceof TypedString);
			assertEquals(principal, removedFormCache);
			assertNull(profilesRetrieverProxy.getFromPrincipalToResourceIdMap(principal));

		} finally {
			if (resourceId!=null)
				registryService.deleteProfile(resourceId);
			if (secProfId!=null)
				registryService.deleteProfile(secProfId);
		}
	}

	@Test
	public void testFindSecurityProfileWithDirectAccess() throws Exception {
		String secProfId = null;
		try {
			String resourceId = "directResourceId";
			String securityProfile = ResourcesGenerator.generateSecProf(resourceId, null);
			secProfId = registryService.registerProfile(securityProfile);
			assertNotNull(secProfId);
			TypedString principal = new TypedString(resourceId,"login");
			ProfileIdentifierLocation loc = null;
			SecurityProfile secProf = profilesRetrieverProxy.findSecurityProfile(principal, loc);
			assertNotNull(secProf);
			assertEquals(resourceId, secProf.getResourceId());
			assertNull(profilesRetrieverProxy.getFromPrincipalToResourceIdMap(principal));
		} finally {
			if (secProfId!=null)
				registryService.deleteProfile(secProfId);
		}
	}
	
	@Test
	public void testRemoveCachedPrincipal() {
		assertNull(profilesRetrieverProxy.removeCachedPrincipal(null));
		String resourceId = "someResourceId";
		TypedString principal = new TypedString("someText","someType");
		profilesRetrieverProxy.putInPrincipalToResourceIdMap(principal, resourceId);
		assertEquals(principal, profilesRetrieverProxy.removeCachedPrincipal(resourceId));
		assertNull(profilesRetrieverProxy.removeCachedPrincipal(resourceId));
	}

}
