package org.devocative.demeter.web.http;

import org.devocative.adroit.ConfigUtil;
import org.devocative.demeter.DemeterConfigKey;
import org.devocative.demeter.DemeterException;
import org.devocative.demeter.core.ModuleLoader;
import org.devocative.demeter.iservice.ISecurityService;
import org.devocative.demeter.vo.UserVO;
import org.devocative.wickomp.http.filter.WAuthMethod;
import org.devocative.wickomp.http.filter.WBaseHttpAuthFilter;
import org.devocative.wickomp.http.filter.WHttpAuthBean;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import java.util.UUID;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

public class DemeterHttpAuthFilter extends WBaseHttpAuthFilter {
	private static final Logger logger = LoggerFactory.getLogger(DemeterHttpAuthFilter.class);

	private String nonce;
	private ScheduledExecutorService nonceRefreshExecutor;
	private ISecurityService securityService;

	@Override
	protected String calculateNonceForDigest(WHttpAuthBean authBean) {
		return nonce;
	}

	@Override
	protected String getRealm(WHttpAuthBean authBean) {
		return ConfigUtil.getString(DemeterConfigKey.SecurityRealm);
	}

	@Override
	protected String generateUserHashForDigest(WHttpAuthBean authBean) {
		return securityService.getUserDigest(authBean.getUsername());
	}

	@Override
	protected boolean authenticateByPasswordForBasic(String username, String password) {
		try {
			securityService.authenticate(username, password);
			return true;
		} catch (DemeterException e) {
			return false;
		}
	}

	@Override
	public void init(FilterConfig filterConfig) throws ServletException {
		String httpMode = ConfigUtil.getString(DemeterConfigKey.HttpAuthenticationMode);
		if ("digest".equals(httpMode)) {
			setDesiredAuthMethod(WAuthMethod.DIGEST);
		}

		if (getDesiredAuthMethod() == WAuthMethod.DIGEST) {
			nonce = UUID.randomUUID().toString();

			nonceRefreshExecutor = Executors.newScheduledThreadPool(1);

			nonceRefreshExecutor.scheduleAtFixedRate(new Runnable() {

				public void run() {
					nonce = UUID.randomUUID().toString();
				}
			}, 1, 1, TimeUnit.MINUTES);
		}

		securityService = ModuleLoader.getApplicationContext().getBean(ISecurityService.class);

		setProcessAuth(ConfigUtil.getBoolean(DemeterConfigKey.EnabledSecurity));

		logger.info("DemeterHttpAuthFilter Inited: DoAuth =[{}] Method=[{}]",
			ConfigUtil.getBoolean(DemeterConfigKey.EnabledSecurity), getDesiredAuthMethod());
	}

	@Override
	protected void onBeforeChainAuthenticated(WHttpAuthBean authBean) {
		// TODO
		securityService.authenticate(new UserVO().setUsername(authBean.getUsername()));
	}

	@Override
	public void destroy() {
		nonceRefreshExecutor.shutdown();
	}
}

@@ -312,17 +312,29 @@
 ter.
-vo.UserVO
+iservice.IUserService
 ;%0Aim
@@ -1072,16 +1072,51 @@
 Service;
+%0A%09private IUserService userService;
 %0A%0A%09@Over
@@ -2390,16 +2390,98 @@
 .class);
+%0A%09%09userService = ModuleLoader.getApplicationContext().getBean(IUserService.class);
 %0A%0A%09%09setP
@@ -2795,18 +2795,8 @@
 ) %7B%0A
-%09%09// TODO%0A
 %09%09se
@@ -2826,24 +2826,28 @@
 ate(
-new UserVO().set
+userService.loadVOBy
 User

load & set the logged-in user as curreny usrt