/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.ocelotds.security;

import org.ocelotds.security.containers.ContainerSecurityServices;
import java.util.regex.Pattern;
import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.context.Initialized;
import javax.enterprise.event.Observes;
import javax.enterprise.inject.Any;
import javax.enterprise.inject.Instance;
import javax.inject.Inject;
import javax.inject.Singleton;
import javax.servlet.ServletContext;
import org.ocelotds.Constants;
import org.ocelotds.annotations.ContainerQualifier;
import org.ocelotds.annotations.OcelotLogger;
import org.slf4j.Logger;

/**
 *
 * @author hhfrancois
 */
@Singleton
public class SecurityServices {

	@Any
	@Inject
	private Instance<ContainerSecurityServices> instances;

	@Inject
	@ContainerQualifier(Constants.Container.UNKNOWN)
	private ContainerSecurityServices unknown;

	@Inject
	@OcelotLogger
	private Logger logger;

	private ContainerSecurityServices current = null;

	/**
	 * Define the current provider for the current container
	 *
	 * @param sc
	 */
	public void setServerInfo(@Observes @Initialized(ApplicationScoped.class) ServletContext sc) {
		String serverInfo = sc.getServerInfo();
		for (ContainerSecurityServices instance : instances) {
			ContainerQualifier annotation = instance.getClass().getAnnotation(ContainerQualifier.class);
			String name = annotation.value();
			logger.debug("Container vendor {} candidate", name);
			Pattern p = Pattern.compile(".*" + name + ".*", Pattern.CASE_INSENSITIVE);
			if (p.matcher(serverInfo).matches()) {
				logger.info("Container vendor {}", name);
				current = instance;
				break;
			}
		}
		if (null == current) {
			current = unknown;
			logger.info("No ContainerSubjectServices implementation found in classpath for server '{}'. Implement it or contact ocelot team leader for implements it.", serverInfo);
		}
	}

	/**
	 * get current ContainerSecurityServices using the container implementation
	 *
	 * @return
	 */
	ContainerSecurityServices getContainerSubjectServices() {
		return current;
	}

	/**
	 * get current Subject using the container implementation
	 *
	 * @return
	 */
	public SecurityContext getSecurityContext() {
		ContainerSecurityServices c = getContainerSubjectServices();
		try {
			if (c != null) {
				return c.getSecurityContext();
			}
		} catch (Exception ex) {
		}
		return null;
	}

	/**
	 * set current Subject using the container implementation
	 *
	 * @param securityContext
	 */
	public void setSecurityContext(SecurityContext securityContext) {
		ContainerSecurityServices c = getContainerSubjectServices();
		try {
			if (c != null) {
				c.setSecurityContext(securityContext);
			}
		} catch (Exception ex) {
			ex.printStackTrace();
		}
	}
}

@@ -600,94 +600,30 @@
 vax.
-inject.Singleton;%0D%0Aimport javax.servlet.ServletContext;%0D%0Aimport org.ocelotds.Constants
+servlet.ServletContext
 ;%0D%0Ai
@@ -791,17 +791,25 @@
 /%0D%0A@
-Singleton
+ApplicationScoped
 %0D%0Apu
@@ -917,96 +917,51 @@
 ces;
-%0D%0A%0D%0A%09@Inject%0D%0A%09@ContainerQualifier(Constants.Container.UNKNOWN)%0D%0A%09private Contain
+ // contains at least the UnkownServ
 erSecu
-r
+t
 ityS
@@ -967,25 +967,16 @@
 Services
- unknown;
 %0D%0A%0D%0A%09@In
@@ -1309,16 +1309,42 @@
 nfo();%0D%0A
+%09%09boolean found = false;%0D%0A
 %09%09for (C
@@ -1490,16 +1490,47 @@
 lass);%0D%0A
+%09%09%09if (annotation != null) %7B%0D%0A%09
 %09%09%09Strin
@@ -1559,16 +1559,17 @@
 lue();%0D%0A
+%09
 %09%09%09logge
@@ -1617,16 +1617,17 @@
 name);%0D%0A
+%09
 %09%09%09Patte
@@ -1696,24 +1696,25 @@
 ITIVE);%0D%0A%09%09%09
+%09
 if (p.matche
@@ -1741,24 +1741,25 @@
 s()) %7B%0D%0A%09%09%09%09
+%09
 logger.info(
@@ -1759,16 +1759,19 @@
 r.info(%22
+%7B%7D 
 Containe
@@ -1775,29 +1775,84 @@
 iner
- vendor %7B%7D%22, name
+SubjectServices implementation found in classpath.%22, annotation.value()
 );%0D%0A
+%09
 %09%09%09%09
@@ -1872,16 +1872,37 @@
 tance;%0D%0A
+%09%09%09%09%09found = true;%0D%0A%09
 %09%09%09%09brea
@@ -1912,42 +1912,26 @@
 %0A%09%09%09
+%09
 %7D%0D%0A%09%09
-%7D%0D%0A%09%09if (null == current)
+%09%7D else
  %7B%0D%0A
+%09
 %09%09%09c
@@ -1943,16 +1943,90 @@
 t = 
-unknown;
+instance; // set the default ContainerSecurityServices%0D%0A%09%09%09%7D%0D%0A%09%09%7D%0D%0A%09%09if (!found) %7B
 %0D%0A%09%09
@@ -2109,19 +2109,22 @@
 for 
+current 
 server
- '%7B%7D'
 . Im
@@ -2187,20 +2187,8 @@
 it.%22
-, serverInfo
 );%0D%0A
@@ -2188,24 +2188,26 @@
 t.%22);%0D%0A%09%09%7D%0D%0A
+%0D%0A
 %09%7D%0D%0A%0D%0A%09/**%0D%0A

improve test coverage