package eu.dnetlib.enabling.aas.wrappers;

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

import java.io.IOException;
import java.io.StringReader;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Properties;

import org.exolab.castor.mapping.Mapping;
import org.exolab.castor.mapping.MappingException;
import org.exolab.castor.util.LocalConfiguration;
import org.exolab.castor.xml.MarshalException;
import org.exolab.castor.xml.Marshaller;
import org.exolab.castor.xml.Unmarshaller;
import org.exolab.castor.xml.ValidationException;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import eu.dnetlib.enabling.aas.ctx.SecurityContext;
import eu.dnetlib.enabling.aas.secprof.SecurityProfile;
import eu.dnetlib.enabling.aas.wrappers.SecurityContextWrapper;
import eu.dnetlib.enabling.aas.wrappers.SecurityPolicyWrapper;
import eu.dnetlib.enabling.aas.wrappers.SecurityProfileWrapper;


public class WrappersTest {

	List<String> bindings;
	Mapping mapping = new Mapping();
	private Unmarshaller unmarshaller;
	
	@Before
	public void setUp() throws Exception {
		bindings = prepareBindings();
		if (bindings.size()>0) {
        	for (Iterator<String> iter = bindings.iterator(); iter.hasNext();) {
        		String currentBinding = null;
        		try {
					currentBinding = (String) iter.next();
					mapping.loadMapping(currentBinding);
				} catch (IOException e) {
					e.printStackTrace();
				} catch (MappingException e) {
					e.printStackTrace();
				}
			}
		}
//		setting up java5 castor properties:
		Properties props = LocalConfiguration.getInstance().getProperties();
		props.setProperty("org.exolab.castor.parser", "com.sun.org.apache.xerces.internal.parsers.SAXParser");
		props.setProperty("org.exolab.castor.xml.serializer.factory", "org.exolab.castor.xml.XercesJDK5XMLSerializerFactory");
	}

	List<String> prepareBindings() {
		List<String> result = new ArrayList<String>();
		result.add("file:web/WEB-INF/bindings/core-binding.xml");
		result.add("file:web/WEB-INF/bindings/secProf-binding.xml");
		result.add("file:web/WEB-INF/bindings/secCtx-binding.xml");
		result.add("file:web/WEB-INF/bindings/commonWrapper-binding.xml");
		result.add("file:web/WEB-INF/bindings/secObjWrapper-binding.xml");				
		result.add("file:web/WEB-INF/bindings/secCtxWrapper-binding.xml");
		result.add("file:web/WEB-INF/bindings/secProfWrapper-binding.xml");
		result.add("file:web/WEB-INF/bindings/secPolicyWrapper-binding.xml");
		return result;
	}
	
	@After
	public void tearDown() throws Exception {
	}

	@Test
	public void testService() {
		assertNotNull(bindings);
	}
	
	@Test
	public void testSecurityContextWrapper() {
		
		SecurityContext secCtx = new SecurityContext();
		secCtx.setCreationTime(System.currentTimeMillis());
		SecurityContextWrapper secCtxWrapper = new SecurityContextWrapper(secCtx);
		
		StringWriter strWriter = new StringWriter();
		try {
			Marshaller marshaller = new Marshaller(strWriter);
			marshaller.setMapping(mapping);
			marshaller.marshal(secCtxWrapper);
		} catch (MappingException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (MarshalException e) {
			e.printStackTrace();
		} catch (ValidationException e) {
			e.printStackTrace();
		}
		String resourceProfile = strWriter.toString();
		assertNotNull(resourceProfile);
		System.out.println(resourceProfile);
		try {
            unmarshaller = new Unmarshaller(SecurityContextWrapper.class);
            unmarshaller.setIgnoreExtraElements(true);
			unmarshaller.setMapping(mapping);
			SecurityContextWrapper retrievedSecCtxWrapper = (SecurityContextWrapper)unmarshaller.unmarshal(new StringReader(resourceProfile));
			assertNotNull(retrievedSecCtxWrapper);
			assertTrue(retrievedSecCtxWrapper.getHeader().getResourceKind().equals(secCtxWrapper.getHeader().getResourceKind()));
			assertTrue(retrievedSecCtxWrapper.getHeader().getResourceType().equals(secCtxWrapper.getHeader().getResourceType()));
			assertTrue(retrievedSecCtxWrapper.getSecCtx().getCreationTime()==secCtxWrapper.getSecCtx().getCreationTime());

		} catch (MappingException e) {
			e.printStackTrace();
		} catch (MarshalException e) {
			e.printStackTrace();
		} catch (ValidationException e) {
			e.printStackTrace();
		}
	}
	
	@Test
	public void testSecurityProfileWrapper() {
		
		SecurityProfile secProf = new SecurityProfile();
		secProf.setResourceId("dummyResource");
		secProf.setSecProfId("112233");
		SecurityProfileWrapper secProfWrapper = new SecurityProfileWrapper(secProf);
		
		StringWriter strWriter = new StringWriter();
		try {
			Marshaller marshaller = new Marshaller(strWriter);
			marshaller.setMapping(mapping);
			marshaller.marshal(secProfWrapper);
		} catch (MappingException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (MarshalException e) {
			e.printStackTrace();
		} catch (ValidationException e) {
			e.printStackTrace();
		}
		String resourceProfile = strWriter.toString();
		assertNotNull(resourceProfile);
		System.out.println(resourceProfile);
		try {
            unmarshaller = new Unmarshaller(SecurityProfileWrapper.class);
            unmarshaller.setIgnoreExtraElements(true);
			unmarshaller.setMapping(mapping);
			SecurityProfileWrapper retrievedSecProfWrapper = (SecurityProfileWrapper)unmarshaller.unmarshal(new StringReader(resourceProfile));
			assertNotNull(retrievedSecProfWrapper);
			assertTrue(retrievedSecProfWrapper.getHeader().getResourceKind().equals(secProfWrapper.getHeader().getResourceKind()));
			assertTrue(retrievedSecProfWrapper.getHeader().getResourceType().equals(secProfWrapper.getHeader().getResourceType()));
			assertTrue(retrievedSecProfWrapper.getSecProf().getSecProfId().equals(secProfWrapper.getSecProf().getSecProfId()));
			assertTrue(retrievedSecProfWrapper.getSecProf().getResourceId().equals(secProfWrapper.getSecProf().getResourceId()));
		} catch (MappingException e) {
			e.printStackTrace();
		} catch (MarshalException e) {
			e.printStackTrace();
		} catch (ValidationException e) {
			e.printStackTrace();
		}
	}
	
	@Test
	public void testSecurityPolicyWrapper() {
		
		String secPolicy = "<PolicySet " +
				"PolicySetId=\"AuthenticationPolicySet\" " +
				"PolicyCombiningAlgId=\"urn:oasis:names:tc:xacml:1.0:policy-combining-algorithm:deny-overrides\">" +
				"</PolicySet>";
		SecurityPolicyWrapper secPolicyWrapper = new SecurityPolicyWrapper(secPolicy);
		
		StringWriter strWriter = new StringWriter();
		try {
			Marshaller marshaller = new Marshaller(strWriter);
			marshaller.setMapping(mapping);
			marshaller.marshal(secPolicyWrapper);
		} catch (MappingException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (MarshalException e) {
			e.printStackTrace();
		} catch (ValidationException e) {
			e.printStackTrace();
		}
		String resourceProfile = strWriter.toString();
		assertNotNull(resourceProfile);
		System.out.println(resourceProfile);
		try {
            unmarshaller = new Unmarshaller(SecurityPolicyWrapper.class);
            unmarshaller.setIgnoreExtraElements(true);
			unmarshaller.setMapping(mapping);
			SecurityPolicyWrapper retrievedSecPolicyWrapper = (SecurityPolicyWrapper)unmarshaller.unmarshal(new StringReader(resourceProfile));
			assertNotNull(retrievedSecPolicyWrapper);
			assertTrue(retrievedSecPolicyWrapper.getHeader().getResourceKind().equals(secPolicyWrapper.getHeader().getResourceKind()));
			assertTrue(retrievedSecPolicyWrapper.getHeader().getResourceType().equals(secPolicyWrapper.getHeader().getResourceType()));
			assertTrue(retrievedSecPolicyWrapper.getSecPolicy().equals(secPolicyWrapper.getSecPolicy()));

		} catch (MappingException e) {
			e.printStackTrace();
		} catch (MarshalException e) {
			e.printStackTrace();
		} catch (ValidationException e) {
			e.printStackTrace();
		}
	}
}
