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

import org.apache.commons.lang3.StringUtils;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.InternalAuthenticationServiceException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;

import com.ym.mec.auth.config.constant.SecurityConstants;
import com.ym.mec.auth.config.token.PhoneAuthenticationToken;
import com.ym.mec.common.validcode.SmsCodeService;

public class PhoneAuthenticationProvider extends AbstractAuthenticationProvider {

	private UserDetailsService userDetailsService;

	private SmsCodeService smsCodeService;
	@Override
	protected void additionalAuthenticationChecks(UserDetails userDetails, Authentication authentication) throws AuthenticationException {
		if (authentication.getCredentials() == null) {
			throw new BadCredentialsException(this.messages.getMessage("PhoneAuthenticationProvider.badCredentials", "Bad credentials"));
		} else {
			String smsCode = authentication.getCredentials().toString();

			String phone = authentication.getPrincipal().toString();

			// 验证码验证
			smsCodeService.verifyValidCode(StringUtils.substringAfter(phone, SecurityConstants.PHONE_PRINCIPAL_PREFIX), smsCode);
		}
	}

	@Override
	protected UserDetails retrieveUser(String phone, Authentication authentication) throws AuthenticationException {
		UserDetails loadedUser;
		try {
			loadedUser = userDetailsService.loadUserByUsername(phone);
		} catch (UsernameNotFoundException e) {
			throw e;
		} catch (Exception e) {
			throw new InternalAuthenticationServiceException(e.getMessage(), e);
		}

		if (loadedUser == null) {
			throw new InternalAuthenticationServiceException("账户不存在");
		} else {
			return loadedUser;
		}
	}

	@Override
	protected Authentication createSuccessAuthentication(Object principal, Authentication authentication, UserDetails user) {
		PhoneAuthenticationToken result = new PhoneAuthenticationToken(principal, authentication.getCredentials(), user.getAuthorities());
		result.setDetails(authentication.getDetails());
		return result;
	}

	@Override
	public boolean supports(Class<?> aClass) {
		return PhoneAuthenticationToken.class.isAssignableFrom(aClass);
	}

	public void setUserDetailsService(UserDetailsService userDetailsService) {
		this.userDetailsService = userDetailsService;
	}

	public void setSmsCodeService(SmsCodeService smsCodeService) {
		this.smsCodeService = smsCodeService;
	}

}
