package com.its.vms.webapp.config;

import com.its.vms.webapp.security.SessionListener;
import com.its.vms.webapp.service.UserService;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.session.SessionRegistry;
import org.springframework.security.core.session.SessionRegistryImpl;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;

import javax.servlet.http.HttpSessionListener;

@EnableWebSecurity
@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    private final UserService userService;

    public WebSecurityConfig(UserService userService) {
        this.userService = userService;
    }

    @Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring().antMatchers("/favicon.ico");
        web.ignoring().antMatchers("/css/**", "/js/**", "/img/**", "/lib/**");

        web.ignoring().antMatchers(HttpMethod.GET, "/api/**");  // GET Method 는 모두 통과
        web.ignoring().antMatchers(HttpMethod.POST, "/api/**");  // GET Method 는 모두 통과
        web.ignoring().antMatchers(HttpMethod.PUT, "/api/**");  // GET Method 는 모두 통과
        web.ignoring().antMatchers(HttpMethod.DELETE, "/api/**");  // GET Method 는 모두 통과
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {

        http
                .httpBasic().disable()
                .cors().configurationSource(corsConfigurationSource())
                .and()
                .csrf().disable()
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and()
                .authorizeRequests()
                // SWAGGER 권한 설정
                .antMatchers("/swagger-ui.html", "/swagger/**", "/swagger-resources/**", "/webjars/**", "/v2/api-docs").permitAll()
                // 웹소켓 권한 설정하지
                .antMatchers("/ws/**").permitAll()
                .antMatchers("/api/**").permitAll()
                .anyRequest().permitAll()
        ;
    }

    // CORS 허용 적용
    @Bean
    public CorsConfigurationSource corsConfigurationSource() {
        CorsConfiguration corsConfig = new CorsConfiguration();

        corsConfig.setAllowCredentials(true);       // cross origin 으로부터 인증을 위한 쿠키 정보를 받을지 여부
        corsConfig.addAllowedOriginPattern("*");    // addAllowedOrigin("*") 대신 사용, 허용할 origin 정보, Arrays.asList("http://localhost:8080")
        corsConfig.addAllowedHeader("*");
        corsConfig.addAllowedMethod("*");           // 허용할 http methods. Arrays.asList("GET", "POST")

        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", corsConfig);

        return source;
    }

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

    @Bean
    public HttpSessionListener httpSessionListener() {
        return new SessionListener();
    }

}

