package kcg.faics.sec;

import java.util.Collection;
import java.util.HashMap;

import javax.annotation.Resource;

import kcg.faics.member.service.MemberService;
import kcg.faics.member.vo.MemberVO;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.authentication.encoding.PasswordEncoder;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;

/** 
 * AuthenticationProvider.java
 * @author 임새미 
 * @since 2016. 10. 6.
 *
 *  	 수정일                     수정자                                       수정내용
 *  -------------	--------	---------------------------
 *  2016. 10. 6. 	    임새미				       최초생성
 * 
 */
public class AuthenticationProvider extends DaoAuthenticationProvider {
	
	/**
	 * 사용자 서비스.
	 */
	@Resource(name = "memberService")
	private MemberService memberSerivce;
	
    /**
     * 비밀번호 인코더 객체.
     */
    @Autowired
    private PasswordEncoder passwordEncoder;
	
	@Override
	public Authentication authenticate(final Authentication authentication) throws AuthenticationException {
		
		String username = authentication.getName();
		String password = (String) authentication.getCredentials();
		
		FaicsUserDetails user = null;
		Collection<? extends GrantedAuthority> authorities = null;
		Authentication auth = null;
		
		try {
			user = (FaicsUserDetails) retrieveUser(username, (UsernamePasswordAuthenticationToken) authentication);
			String hashedPassword = passwordEncoder.encodePassword(password, null);
			if (user.getChkcnt() >= 5) {
				throw new BadCredentialsException("5회 이상 로그인에 실패하였습니다. 관리자에게 문의하세요.");
			} else if (!hashedPassword.equalsIgnoreCase(user.getPassword())) {
				MemberVO memberVO = new MemberVO();
				memberVO.setUserid(user.getUsername());
				memberVO.setUsertype(user.getUserType());
				HashMap<String, Object> map = memberSerivce.failLogin(memberVO);
 				throw new BadCredentialsException(
 						String.format("비밀번호가 일치하지 않습니다. 로그인 실패횟수는 %s회 입니다. 5회 이상이면 로그인에 제한이 생깁니다.", user.getChkcnt() + 1)
 				);
			} 
			
			authorities = user.getAuthorities();
			auth = new UsernamePasswordAuthenticationToken(user, password, authorities);
		} catch (UsernameNotFoundException e) {
			logger.info(e.toString());
			throw new UsernameNotFoundException(e.getMessage());
		} catch (BadCredentialsException e) {
			logger.info(e.toString());
			throw new BadCredentialsException(e.getMessage());
		} catch (Exception e) {
			logger.info(e.toString());
			throw new RuntimeException(e.getMessage());
		}
		
		return auth;
	}
}
