using be.ehealth.technicalconnector.beid.domain;
using be.ehealth.technicalconnector.exception;
using be.ehealth.technicalconnector.service.sts.security;
using be.ehealth.technicalconnector.service.sts.security.impl;
using be.fgov.ehealth.technicalconnector.session;
using ikvm.extensions;
using org.apache.commons.lang3;
using org.w3c.dom;

/*
 * Copyright (c) eHealth
 */
namespace be.ehealth.technicalconnector.session
{
	using System;
	using NUnit.Framework;
	using be.ehealth.technicalconnector.beid;
	using be.ehealth.technicalconnector.config;
	using be.ehealth.technicalconnector.service.sts.utils;
	using be.ehealth.technicalconnector.utils;
	using be.fgov.ehealth.technicalconnector.tests.utils.net;
	using java.util;
	
	[TestFixture]
	public class SessionManagerUserIntegrationTest : AbstractServiceIntegrationTest
	{
		protected static Configuration conf;

		protected static Properties props;

		[SetUp]
		public void prepareConfig() {
			props = TestPropertiesNetLoader.getProperties("be.ehealth.technicalconnector.test.properties",".net");
			conf = ConfigFactory.getConfigValidator().getConfig();

			Set keys = props.keySet();
			Iterator it = keys.iterator();
			while (it.hasNext()) {
				object key = it.next();
				if (!key.toString().startsWith("test.")) {
					conf.setProperty(key.toString(), props.getProperty(key.toString()));
				}
			}
			
			BeIDInfo beIdInfo = BeIDFactory.getBeIDInfo("TEST",false);
			ConfigFactory.getConfigValidator().setProperty("user.inss", beIdInfo.getIdentity().getNationalNumber());
		}
		
		[Test]
		public void testCreateSessionWithoutEnc() {

			SessionManager sessionmgmgt = Session.getInstance();
			sessionmgmgt.unloadSession();
			SessionItem session = sessionmgmgt.createSession(props.getProperty("test.session.holderofkey.password"));
			String token = SAMLConverter.toXMLString(session.getSAMLToken().getAssertion());

			Assert.IsNotNull(token);
			Assert.AreEqual(true, sessionmgmgt.hasValidSession());
			Assert.IsNotNull(session.getEncryptionCredential());


		}

		[Test]
		public void testCreateSessionWithEnc() {


			SessionManager sessionmgmgt = Session.getInstance();
			sessionmgmgt.unloadSession();
			SessionItem session = sessionmgmgt.createSession(props.getProperty("test.session.holderofkey.password"), props.getProperty("test.session.encryption.password"));
			String token = SAMLConverter.toXMLString(session.getSAMLToken().getAssertion());
			
			java.util.List expectedProps = new ArrayList();
			ConfigValidator config = ConfigFactory.getConfigValidator(expectedProps);

			Assert.IsNotNull(config.getProperty("user.inss"));
			Assert.IsNotNull(token);
			Assert.AreEqual(true, sessionmgmgt.hasValidSession());
			Assert.IsNotNull(session.getEncryptionCredential());

		}

		/**
		 * Test create session. Create a session based on the eID
		 */
		[Test]
		public void testCreateSessionEidOnlyUserInssPropertyEmpty() {
			ConfigFactory.getConfigValidator().setProperty("user.inss", "");
			SessionManager sessionmgmgt = Session.getInstance();
			sessionmgmgt.unloadSession();
			SessionItem session = sessionmgmgt.createSessionEidOnly();
			String userInss = ConfigFactory.getConfigValidator().getProperty("user.inss");
			Assert.IsNotNull(userInss);
			Assert.IsTrue(userInss.length() == 11, "property userInss should be filled out with the inss from the eid : checked if was a valid inss (check : length = 11 ) inss: " + userInss);
			String token = SAMLConverter.toXMLString(session.getSAMLToken().getAssertion());

			Assert.IsNotNull(token);
			Assert.AreEqual(true, sessionmgmgt.hasValidSession());
			Assert.IsNotNull(session.getEncryptionCredential());

		}

		/**
		 * Test create session. Create a session based on the eID
		 */
		[Test]
		public void testCreateSessionEidOnly() {
			ConfigFactory.getConfigValidator().setProperty("user.inss", "");
			SessionManager sessionmgmgt = Session.getInstance();
			sessionmgmgt.unloadSession();
			SessionItem session = sessionmgmgt.createSessionEidOnly();
			String token = SAMLConverter.toXMLString(session.getSAMLToken().getAssertion());

			Assert.IsNotNull(token);
			Assert.AreEqual(true, sessionmgmgt.hasValidSession());
			Assert.IsNotNull(session.getEncryptionCredential());

		}

		[Test]
		public void testRenewToken() {
		    Assert.Throws<TechnicalConnectorException>(() =>
            {
                ConfigFactory.getConfigValidator().setProperty("sessionmanager.activate.autorenew", "true");
                SessionManager sessionmgmgt = Session.getInstance();
                String sas = ConnectorIOUtils.convertStreamToString(ConnectorIOUtils.getResourceAsStream("/examples/sas/renew.eid.sas"));
                sas = StringUtils.replace(sas, "${user.inss}", ConfigFactory.getConfigValidator().getProperty("user.inss"));
                Element tokenEl = SAMLConverter.toElement(sas);

                Credential authCredential = BeIDCredential.getInstance("session", BeIDCredential.EID_AUTH_ALIAS);
                sessionmgmgt.getSession().setHeaderCredential(authCredential);
                SAMLToken token = new SAML11HolderOfKeyToken(tokenEl, authCredential);
                sessionmgmgt.loadSession(token, props.getProperty("test.session.holderofkey.password"), props.getProperty("test.session.encryption.password"));
                Assert.AreEqual(true, sessionmgmgt.hasValidSession());
                Assert.IsNotNull(sessionmgmgt.getSession().getEncryptionCredential());

                ConfigFactory.getConfigValidator().setProperty("sessionmanager.activate.autorenew", "false");
            });
		}
	}
}