package com.its.web.security;

import com.its.web.service.admin.LoginService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.core.session.SessionRegistry;
import org.springframework.security.core.session.SessionRegistryImpl;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;

@Slf4j
@Configuration
@EnableWebSecurity
@RequiredArgsConstructor
public class WebSecurityConfig {

    private final LoginService loginService;
    private final WebLoginSuccessHandler webLoginSuccessHandler;
    private final WebLoginFailureHandler webLoginFailureHandler;

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http.csrf().disable();
        http.authorizeRequests()
                .antMatchers("/swagger-ui.html", "/swagger/**", "/swagger-resources/**", "/webjars/**", "/v2/api-docs").permitAll()
                .antMatchers("/", "/trafficMap/**", "/api/**", "/notice/**", "/center/**", "/statistics/**").permitAll()
                .antMatchers("/images/**", "/css/**", "/js/**", "/font/**").permitAll()
                .antMatchers("/phits").hasIpAddress("127.0.0.1")
                .anyRequest().authenticated();
        http.formLogin()
                .loginPage("/phits")
                .loginProcessingUrl("/phits/login")
                .failureUrl("/")
                .successHandler(this.webLoginSuccessHandler)
                .failureHandler(this.webLoginFailureHandler);
        return http.build();
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new WebPasswordEncoder();
    }

    @Bean
    public SessionRegistry sessionRegistry() {
        return new SessionRegistryImpl();
    }

    public DaoAuthenticationProvider daoAuthenticationProvider() {
        DaoAuthenticationProvider authenticationProvider = new DaoAuthenticationProvider();
        authenticationProvider.setUserDetailsService(this.loginService);
        authenticationProvider.setPasswordEncoder(passwordEncoder());
        // loadUserByUsername 의 UsernameNotFoundException 이 BadCredentialsException 로 발생함.
        // Exception 을 catch 하기 위해서는 아래를 false 로 설정하면 됨.
        authenticationProvider.setHideUserNotFoundExceptions(true);
        return authenticationProvider;
    }
}
