package com.ym.mec.auth.core.filter;

import java.io.IOException;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.springframework.security.authentication.AbstractAuthenticationToken;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.authentication.LockedException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;

import com.ym.mec.auth.api.dto.SysUserInfo;
import com.ym.mec.auth.api.enums.SysUserType;
import com.ym.mec.auth.config.constant.SecurityConstants;
import com.ym.mec.auth.config.token.PhoneAuthenticationToken;
import com.ym.mec.auth.service.SysUserService;

public class PhoneLoginAuthenticationFilter extends AbstractAuthenticationProcessingFilter {

	private static final String SPRING_SECURITY_RESTFUL_PHONE_KEY = "phone";
	private static final String SPRING_SECURITY_RESTFUL_VERIFY_CODE_KEY = "smsCode";
	private static final String clientIdParameter = "clientId";

	private static final String SPRING_SECURITY_RESTFUL_LOGIN_URL = "/smsLogin";
	private boolean postOnly = true;
	
	private SysUserService sysUserService;

	public PhoneLoginAuthenticationFilter() {
		super(new AntPathRequestMatcher(SPRING_SECURITY_RESTFUL_LOGIN_URL, "POST"));
	}

	@Override
	public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
		if (postOnly && !request.getMethod().equals("POST")) {
			throw new AuthenticationServiceException("Authentication method not supported: " + request.getMethod());
		}

		AbstractAuthenticationToken authRequest;
		String principal;
		String credentials;

		// 手机验证码登陆
		principal = obtainParameter(request, SPRING_SECURITY_RESTFUL_PHONE_KEY);
		credentials = obtainParameter(request, SPRING_SECURITY_RESTFUL_VERIFY_CODE_KEY);

		SysUserInfo userInfo = sysUserService.queryUserInfoByPhone(principal);

		String clientId = request.getParameter(clientIdParameter);

		if (userInfo == null) {
			throw new UsernameNotFoundException("用户名或密码错误");
		}
	
		if (userInfo.getSysUser().getUserType() != SysUserType.SYSTEM && !StringUtils.equalsIgnoreCase(clientId, userInfo.getSysUser().getUserType().getCode())) {
			throw new LockedException("登录失败");
		}

		principal = principal.trim();
		authRequest = new PhoneAuthenticationToken(SecurityConstants.PHONE_PRINCIPAL_PREFIX + principal, credentials);

		// Allow subclasses to set the "details" property
		setDetails(request, authRequest);
		return this.getAuthenticationManager().authenticate(authRequest);
	}

	@Override
	protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authResult)
			throws IOException, ServletException {
		super.successfulAuthentication(request, response, chain, authResult);
		//chain.doFilter(request, response);
	}

	private void setDetails(HttpServletRequest request, AbstractAuthenticationToken authRequest) {
		authRequest.setDetails(authenticationDetailsSource.buildDetails(request));
	}

	private String obtainParameter(HttpServletRequest request, String parameter) {
		String result = request.getParameter(parameter);
		return result == null ? "" : result;
	}

	public void setSysUserService(SysUserService sysUserService) {
		this.sysUserService = sysUserService;
	}

}
