package com.bb.config;

import java.util.ArrayList;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.stereotype.Component;

import com.bb.model.OTPInfo;
import com.bb.model.Site;
import com.bb.service.SiteService;
import com.bb.util.TOTPTokenGenerator;

import lombok.extern.slf4j.Slf4j;

@Slf4j
@Component("guestProvider")
public class GuestProvider implements AuthenticationProvider {
	
	@Autowired
	SiteService siteService;
	
	@Override
	public Authentication authenticate(Authentication authentication) throws AuthenticationException {
		String verificationCode = ((CustomWebAuthenticationDetails) authentication.getDetails()).getVerificationCode();
		
		final String LOG_PREFIX = "#-GuestProvider:::";
		log.info(LOG_PREFIX+ "Authentication::"+authentication.toString());
		log.info(LOG_PREFIX+ "verificationCode::"+verificationCode);
		
		Site guest = siteService.getGuestLogin();
		OTPInfo otpInfo = siteService.getOtpInfo(guest.getSiteIdx());
		
		if(otpInfo.getSecretKey() == null || otpInfo.getSecretKey().equals("")) {
			// Create New OTP
	        otpInfo = TOTPTokenGenerator.getGoogleAuthQRUrl(otpInfo);
	        
			log.info(LOG_PREFIX+ "makeOtp:: secret : " + otpInfo.getSecretKey());
	        log.info(LOG_PREFIX+ "makeOtp::account : " + otpInfo.getAccount());
	        log.info(LOG_PREFIX+ "makeOtp:: issuer : " + otpInfo.getIssuer());
	        log.info(LOG_PREFIX+ "makeOtp::    URL : " + otpInfo.getUrl());
	        
	        int result = siteService.registSuperOtp(otpInfo);
	        log.info(LOG_PREFIX+ "makeOtp:: result : " + result);
		} else {
			log.info(LOG_PREFIX+ "OTP Info : " + otpInfo);
			String secret = otpInfo.getSecretKey();
			
			if(verificationCode == null || verificationCode.equals("")) {
				log.error(LOG_PREFIX+ "OTP 번호를 입력하세요.");
				return null;
			}
			
			boolean chkOtp = TOTPTokenGenerator.otpVerify(secret, Integer.parseInt(verificationCode));
			if(!chkOtp) {
				log.error(LOG_PREFIX+ "OTP 번호가 일치하지 않습니다.");
				return null;
			}
		}
		
		if(guest == null) {
			return null;
		} else {
			List<GrantedAuthority> roles = new ArrayList<GrantedAuthority>();			
			roles.add(new SimpleGrantedAuthority("GUEST"));	
		
			UsernamePasswordAuthenticationToken result = new UsernamePasswordAuthenticationToken("oms", "ehfrhfo22#", roles);	
			result.setDetails(guest);
				
			return result;
		}
	}

	@Override
	public boolean supports(Class<?> authentication) {
		// TODO Auto-generated method stub
		return authentication.equals(UsernamePasswordAuthenticationToken.class);
	}

}
